commit
470ccf8c9a
@ -10,4 +10,4 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
|||||||
- [Introduction to Minimax Algorithm](https://www.baeldung.com/java-minimax-algorithm)
|
- [Introduction to Minimax Algorithm](https://www.baeldung.com/java-minimax-algorithm)
|
||||||
- [How to Calculate Levenshtein Distance in Java?](https://www.baeldung.com/java-levenshtein-distance)
|
- [How to Calculate Levenshtein Distance in Java?](https://www.baeldung.com/java-levenshtein-distance)
|
||||||
- [How to Find the Kth Largest Element in Java](https://www.baeldung.com/java-kth-largest-element)
|
- [How to Find the Kth Largest Element in Java](https://www.baeldung.com/java-kth-largest-element)
|
||||||
- More articles: [[next -->]](/../algorithms-miscellaneous-2)
|
- More articles: [[next -->]](/algorithms-miscellaneous-2)
|
||||||
|
@ -14,4 +14,4 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
|||||||
- [Displaying Money Amounts in Words](https://www.baeldung.com/java-money-into-words)
|
- [Displaying Money Amounts in Words](https://www.baeldung.com/java-money-into-words)
|
||||||
- [A Collaborative Filtering Recommendation System in Java](https://www.baeldung.com/java-collaborative-filtering-recommendations)
|
- [A Collaborative Filtering Recommendation System in Java](https://www.baeldung.com/java-collaborative-filtering-recommendations)
|
||||||
- [Implementing A* Pathfinding in Java](https://www.baeldung.com/java-a-star-pathfinding)
|
- [Implementing A* Pathfinding in Java](https://www.baeldung.com/java-a-star-pathfinding)
|
||||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-1) [[next -->]](/../algorithms-miscellaneous-3)
|
- More articles: [[<-- prev]](/algorithms-miscellaneous-1) [[next -->]](/algorithms-miscellaneous-3)
|
||||||
|
@ -15,5 +15,5 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
|||||||
- [Maximum Subarray Problem](https://www.baeldung.com/java-maximum-subarray)
|
- [Maximum Subarray Problem](https://www.baeldung.com/java-maximum-subarray)
|
||||||
- [How to Merge Two Sorted Arrays](https://www.baeldung.com/java-merge-sorted-arrays)
|
- [How to Merge Two Sorted Arrays](https://www.baeldung.com/java-merge-sorted-arrays)
|
||||||
- [Median of Stream of Integers using Heap](https://www.baeldung.com/java-stream-integers-median-using-heap)
|
- [Median of Stream of Integers using Heap](https://www.baeldung.com/java-stream-integers-median-using-heap)
|
||||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-4) [[next -->]](/../algorithms-miscellaneous-6)
|
- More articles: [[<-- prev]](/algorithms-miscellaneous-4) [[next -->]](/algorithms-miscellaneous-6)
|
||||||
|
|
||||||
|
@ -10,4 +10,4 @@
|
|||||||
- [Implementing a 2048 Solver in Java](https://www.baeldung.com/2048-java-solver)
|
- [Implementing a 2048 Solver in Java](https://www.baeldung.com/2048-java-solver)
|
||||||
- [Finding Top K Elements in an Array](https://www.baeldung.com/java-array-top-elements)
|
- [Finding Top K Elements in an Array](https://www.baeldung.com/java-array-top-elements)
|
||||||
- [Reversing a Linked List in Java](https://www.baeldung.com/java-reverse-linked-list)
|
- [Reversing a Linked List in Java](https://www.baeldung.com/java-reverse-linked-list)
|
||||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-5)
|
- More articles: [[<-- prev]](/algorithms-miscellaneous-5)
|
||||||
|
@ -8,3 +8,4 @@ This module contains articles about Apache Spark
|
|||||||
- [Building a Data Pipeline with Kafka, Spark Streaming and Cassandra](https://www.baeldung.com/kafka-spark-data-pipeline)
|
- [Building a Data Pipeline with Kafka, Spark Streaming and Cassandra](https://www.baeldung.com/kafka-spark-data-pipeline)
|
||||||
- [Machine Learning with Spark MLlib](https://www.baeldung.com/spark-mlib-machine-learning)
|
- [Machine Learning with Spark MLlib](https://www.baeldung.com/spark-mlib-machine-learning)
|
||||||
- [Introduction to Spark Graph Processing with GraphFrames](https://www.baeldung.com/spark-graph-graphframes)
|
- [Introduction to Spark Graph Processing with GraphFrames](https://www.baeldung.com/spark-graph-graphframes)
|
||||||
|
- [Apache Spark: Differences between Dataframes, Datasets and RDDs](https://www.baeldung.com/java-spark-dataframe-dataset-rdd)
|
||||||
|
@ -19,12 +19,12 @@ public class StudentDbService implements StudentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Student update(Student student) {
|
public Student update(Student student) {
|
||||||
logger.log(Level.INFO, "Updating sutdent in DB...");
|
logger.log(Level.INFO, "Updating student in DB...");
|
||||||
return student;
|
return student;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String delete(String registrationId) {
|
public String delete(String registrationId) {
|
||||||
logger.log(Level.INFO, "Deleteing sutdent in DB...");
|
logger.log(Level.INFO, "Deleting student in DB...");
|
||||||
return registrationId;
|
return registrationId;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -33,11 +33,15 @@ public class HashSetBenchmark {
|
|||||||
private List<Employee> employeeList1 = new ArrayList<>();
|
private List<Employee> employeeList1 = new ArrayList<>();
|
||||||
private Set<Employee> employeeSet2 = new HashSet<>();
|
private Set<Employee> employeeSet2 = new HashSet<>();
|
||||||
private List<Employee> employeeList2 = new ArrayList<>();
|
private List<Employee> employeeList2 = new ArrayList<>();
|
||||||
|
private Set<Employee> employeeSet3 = new HashSet<>();
|
||||||
|
private Set<Employee> employeeSet4 = new HashSet<>();
|
||||||
|
|
||||||
private long set1Size = 60000;
|
private long set1Size = 60000;
|
||||||
private long list1Size = 50000;
|
private long list1Size = 50000;
|
||||||
private long set2Size = 50000;
|
private long set2Size = 50000;
|
||||||
private long list2Size = 60000;
|
private long list2Size = 60000;
|
||||||
|
private long set3Size = 50000;
|
||||||
|
private long set4Size = 60000;
|
||||||
|
|
||||||
@Setup(Level.Trial)
|
@Setup(Level.Trial)
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@ -58,6 +62,14 @@ public class HashSetBenchmark {
|
|||||||
employeeList2.add(new Employee(i, RandomStringUtils.random(7, true, false)));
|
employeeList2.add(new Employee(i, RandomStringUtils.random(7, true, false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (long i = 0; i < set3Size; i++) {
|
||||||
|
employeeSet3.add(new Employee(i, RandomStringUtils.random(7, true, false)));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (long i = 0; i < set4Size; i++) {
|
||||||
|
employeeSet4.add(new Employee(i, RandomStringUtils.random(7, true, false)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -72,6 +84,11 @@ public class HashSetBenchmark {
|
|||||||
return state.employeeSet2.removeAll(state.employeeList2);
|
return state.employeeSet2.removeAll(state.employeeList2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public boolean given_SizeOfHashsetSmallerThanSizeOfAnotherHashSet_When_RemoveAllFromHashSet_Then_GoodPerformance(MyState state) {
|
||||||
|
return state.employeeSet3.removeAll(state.employeeSet4);
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
Options options = new OptionsBuilder().include(HashSetBenchmark.class.getSimpleName())
|
Options options = new OptionsBuilder().include(HashSetBenchmark.class.getSimpleName())
|
||||||
.threads(1)
|
.threads(1)
|
||||||
|
@ -73,7 +73,7 @@ public class LivelockExample {
|
|||||||
|
|
||||||
public void tryLock(Lock lock, long millis) {
|
public void tryLock(Lock lock, long millis) {
|
||||||
try {
|
try {
|
||||||
lock.tryLock(10, TimeUnit.MILLISECONDS);
|
lock.tryLock(millis, TimeUnit.MILLISECONDS);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.baeldung.exceptions.classcastexception;
|
||||||
|
|
||||||
|
public interface Animal {
|
||||||
|
|
||||||
|
String getName();
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.baeldung.exceptions.classcastexception;
|
||||||
|
|
||||||
|
public class Box<T> {
|
||||||
|
|
||||||
|
private T content;
|
||||||
|
|
||||||
|
public T getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(T content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.exceptions.classcastexception;
|
||||||
|
|
||||||
|
public class Frog extends Reptile {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return super.getName() + ": Frog";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.exceptions.classcastexception;
|
||||||
|
|
||||||
|
public class Mammal implements Animal {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Mammal";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.exceptions.classcastexception;
|
||||||
|
|
||||||
|
public class Reptile implements Animal {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Reptile";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.baeldung.exceptions.classcastexception;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class CheckedCastsUnitTest {
|
||||||
|
|
||||||
|
@Test(expected = ClassCastException.class)
|
||||||
|
public void givenBaseTypeVariableReferencingChildInstance_whenCastToIncompatibleSubtype_thenClassCastException() {
|
||||||
|
Animal animal = new Frog();
|
||||||
|
|
||||||
|
//A checked downcast to Mammal is incompatible from Frog because Frog is not a subtype of Mammal.
|
||||||
|
Mammal mammal = (Mammal) animal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ClassCastException.class)
|
||||||
|
public void givenBaseTypeVariableReferencingChildInstance_whenCastToIncompatibleInterface_thenClassCastException() {
|
||||||
|
Animal animal = new Frog();
|
||||||
|
|
||||||
|
//A checked cast to Serializable is incompatible from Frog because Frog is not a subtype of Serializable.
|
||||||
|
Serializable serial = (Serializable) animal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ClassCastException.class)
|
||||||
|
public void givenObjectVariableReferencingPrimitiveArray_whenCastToBoxedTypeArray_thenClassCastException() {
|
||||||
|
Object primitives = new int[1];
|
||||||
|
|
||||||
|
//A checked cast to Integer[] is incompatible from primitive arrays. Auto-boxing does not work for arrays.
|
||||||
|
Integer[] integers = (Integer[]) primitives;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ClassCastException.class)
|
||||||
|
public void givenObjectVariableReferencingPrimitiveArray_whenCastToPromotedTypeArray_thenClassCastException() {
|
||||||
|
Object primitives = new int[1];
|
||||||
|
|
||||||
|
//A checked cast to long[] is incompatible from int[]. Type promotion does not work for arrays.
|
||||||
|
long[] longs = (long[]) primitives;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.baeldung.exceptions.classcastexception;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class GenericConversionUnitTest {
|
||||||
|
|
||||||
|
@Test(expected = ClassCastException.class)
|
||||||
|
public void givenIncompatibleType_whenConvertInstanceOfObject_thenClassCastException() {
|
||||||
|
// Should have been null, but due to type erasure, inside convertInstanceOfObject,
|
||||||
|
// it will attempt to cast to Object instead of String, so it casts to Object, which is always possible.
|
||||||
|
String shouldBeNull = convertInstanceOfObject(123);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T convertInstanceOfObject(Object o) {
|
||||||
|
try {
|
||||||
|
return (T) o; // Casts to Object due to type erasure
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
return null; // Will never reach this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.baeldung.exceptions.classcastexception;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class UncheckedConversionUnitTest {
|
||||||
|
|
||||||
|
@Test(expected = ClassCastException.class)
|
||||||
|
public void givenPollutedGenericType_whenGetProperty_thenClassCastException() {
|
||||||
|
Box<Long> originalBox = new Box<>();
|
||||||
|
Box raw = originalBox;
|
||||||
|
raw.setContent(2.5);
|
||||||
|
Box<Long> bound = (Box<Long>) raw;
|
||||||
|
|
||||||
|
//An incompatible element was found in the raw box.
|
||||||
|
Long content = bound.getContent();
|
||||||
|
}
|
||||||
|
}
|
@ -7,4 +7,5 @@ This module contains articles about core features in the Java language
|
|||||||
- [When are Static Variables Initialized in Java?](https://www.baeldung.com/java-static-variables-initialization)
|
- [When are Static Variables Initialized in Java?](https://www.baeldung.com/java-static-variables-initialization)
|
||||||
- [Checking if a Class Exists in Java](https://www.baeldung.com/java-check-class-exists)
|
- [Checking if a Class Exists in Java](https://www.baeldung.com/java-check-class-exists)
|
||||||
- [The Difference Between a.getClass() and A.class in Java](https://www.baeldung.com/java-getclass-vs-class)
|
- [The Difference Between a.getClass() and A.class in Java](https://www.baeldung.com/java-getclass-vs-class)
|
||||||
|
- [Constants in Java: Patterns and Anti-Patterns](https://www.baeldung.com/java-constants-good-practices)
|
||||||
- [[<-- Prev]](/core-java-modules/core-java-lang-2)
|
- [[<-- Prev]](/core-java-modules/core-java-lang-2)
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.baeldung.constantspatterns;
|
||||||
|
|
||||||
|
public class Calculator {
|
||||||
|
public static final double PI = 3.14159265359;
|
||||||
|
private static final double UPPER_LIMIT = 0x1.fffffffffffffP+1023;
|
||||||
|
|
||||||
|
public enum Operation {
|
||||||
|
ADD, SUBTRACT, DIVIDE, MULTIPLY
|
||||||
|
}
|
||||||
|
|
||||||
|
public double operateOnTwoNumbers(double numberOne, double numberTwo, Operation operation) {
|
||||||
|
if (numberOne > UPPER_LIMIT) {
|
||||||
|
throw new IllegalArgumentException("'numberOne' is too large");
|
||||||
|
}
|
||||||
|
if (numberTwo > UPPER_LIMIT) {
|
||||||
|
throw new IllegalArgumentException("'numberTwo' is too large");
|
||||||
|
}
|
||||||
|
double answer = 0;
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case ADD:
|
||||||
|
answer = numberOne + numberTwo;
|
||||||
|
break;
|
||||||
|
case SUBTRACT:
|
||||||
|
answer = numberOne - numberTwo;
|
||||||
|
break;
|
||||||
|
case DIVIDE:
|
||||||
|
answer = numberOne / numberTwo;
|
||||||
|
break;
|
||||||
|
case MULTIPLY:
|
||||||
|
answer = numberOne * numberTwo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.baeldung.constantspatterns;
|
||||||
|
|
||||||
|
public interface CalculatorConstants {
|
||||||
|
double PI = 3.14159265359;
|
||||||
|
double UPPER_LIMIT = 0x1.fffffffffffffP+1023;
|
||||||
|
|
||||||
|
enum Operation {
|
||||||
|
ADD, SUBTRACT, MULTIPLY, DIVIDE
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.baeldung.constantspatterns;
|
||||||
|
|
||||||
|
public class GeometryCalculator implements CalculatorConstants {
|
||||||
|
public static final double UPPER_LIMIT = 100000000000000000000.0;
|
||||||
|
|
||||||
|
public double operateOnTwoNumbers(double numberOne, double numberTwo, Operation operation) {
|
||||||
|
if (numberOne > UPPER_LIMIT) {
|
||||||
|
throw new IllegalArgumentException("'numberOne' is too large");
|
||||||
|
}
|
||||||
|
if (numberTwo > UPPER_LIMIT) {
|
||||||
|
throw new IllegalArgumentException("'numberTwo' is too large");
|
||||||
|
}
|
||||||
|
double answer = 0;
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case ADD:
|
||||||
|
answer = numberOne + numberTwo;
|
||||||
|
break;
|
||||||
|
case SUBTRACT:
|
||||||
|
answer = numberOne - numberTwo;
|
||||||
|
break;
|
||||||
|
case DIVIDE:
|
||||||
|
answer = numberOne / numberTwo;
|
||||||
|
break;
|
||||||
|
case MULTIPLY:
|
||||||
|
answer = numberOne * numberTwo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.baeldung.constantspatterns.calculations;
|
||||||
|
|
||||||
|
public final class MathConstants {
|
||||||
|
public static final double PI = 3.14159265359;
|
||||||
|
static final double GOLDEN_RATIO = 1.6180;
|
||||||
|
static final double GRAVITATIONAL_ACCELERATION = 9.8;
|
||||||
|
static final double EULERS_NUMBER = 2.7182818284590452353602874713527;
|
||||||
|
|
||||||
|
public enum Operation {
|
||||||
|
ADD, SUBTRACT, DIVIDE, MULTIPLY
|
||||||
|
}
|
||||||
|
|
||||||
|
private MathConstants() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.baeldung.constantspatterns;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ConstantPatternUnitTest {
|
||||||
|
@Test
|
||||||
|
public void givenTwoNumbersAndAdd_whenCallingCalculatorOperatOneTwoNumbers_thenCorrectAnswerReturned() {
|
||||||
|
Calculator calculator = new Calculator();
|
||||||
|
double expected = 4;
|
||||||
|
double answer = calculator.operateOnTwoNumbers(2, 2, Calculator.Operation.ADD);
|
||||||
|
assertEquals(expected, answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTwoNumbersAndAdd_whenCallingGeometryCalculatorOperatOneTwoNumbers_thenCorrectAnswerReturned() {
|
||||||
|
GeometryCalculator calculator = new GeometryCalculator();
|
||||||
|
double expected = 4;
|
||||||
|
double answer = calculator.operateOnTwoNumbers(2, 2, GeometryCalculator.Operation.ADD);
|
||||||
|
assertEquals(expected, answer);
|
||||||
|
}
|
||||||
|
}
|
@ -14,4 +14,5 @@ This module contains articles about networking in Java
|
|||||||
- [Handling java.net.ConnectException](https://www.baeldung.com/java-net-connectexception)
|
- [Handling java.net.ConnectException](https://www.baeldung.com/java-net-connectexception)
|
||||||
- [Getting MAC addresses in Java](https://www.baeldung.com/java-mac-address)
|
- [Getting MAC addresses in Java](https://www.baeldung.com/java-mac-address)
|
||||||
- [Sending Emails with Attachments in Java](https://www.baeldung.com/java-send-emails-attachments)
|
- [Sending Emails with Attachments in Java](https://www.baeldung.com/java-send-emails-attachments)
|
||||||
|
- [Finding a Free Port in Java](https://www.baeldung.com/java-free-port)
|
||||||
- [[<-- Prev]](/core-java-modules/core-java-networking)
|
- [[<-- Prev]](/core-java-modules/core-java-networking)
|
||||||
|
@ -3,7 +3,7 @@ package com.baeldung.hashing;
|
|||||||
class SHACommonUtils {
|
class SHACommonUtils {
|
||||||
|
|
||||||
public static String bytesToHex(byte[] hash) {
|
public static String bytesToHex(byte[] hash) {
|
||||||
StringBuffer hexString = new StringBuffer();
|
StringBuilder hexString = new StringBuilder(2 * hash.length);
|
||||||
for (byte h : hash) {
|
for (byte h : hash) {
|
||||||
String hex = Integer.toHexString(0xff & h);
|
String hex = Integer.toHexString(0xff & h);
|
||||||
if (hex.length() == 1)
|
if (hex.length() == 1)
|
||||||
|
@ -104,16 +104,12 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>${maven-surefire-plugin.version}</version>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
|
|
||||||
<joda-money.version>1.0.1</joda-money.version>
|
<joda-money.version>1.0.1</joda-money.version>
|
||||||
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
||||||
|
78
netflix-modules/mantis/pom.xml
Normal file
78
netflix-modules/mantis/pom.xml
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<?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>mantis</artifactId>
|
||||||
|
<name>Mantis</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<description>Sample project for Netflix Mantis</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-boot-2</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../parent-boot-2</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
<version>2.1.3.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.mantisrx</groupId>
|
||||||
|
<artifactId>mantis-runtime</artifactId>
|
||||||
|
<version>1.2.63</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.10.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.andreinc.mockneat</groupId>
|
||||||
|
<artifactId>mockneat</artifactId>
|
||||||
|
<version>0.3.8</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.12</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-webflux</artifactId>
|
||||||
|
<version>5.0.9.RELEASE</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.projectreactor.netty</groupId>
|
||||||
|
<artifactId>reactor-netty</artifactId>
|
||||||
|
<version>0.9.12.RELEASE</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>SpringLibReleaseRepo</id>
|
||||||
|
<url>https://repo.spring.io/libs-release/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.baeldung.netflix.mantis;
|
||||||
|
|
||||||
|
import com.baeldung.netflix.mantis.job.LogAggregationJob;
|
||||||
|
import io.mantisrx.runtime.executor.LocalJobExecutorNetworked;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.CommandLineRunner;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@SpringBootApplication
|
||||||
|
public class MantisApplication implements CommandLineRunner {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(MantisApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(String... args) {
|
||||||
|
LocalJobExecutorNetworked.execute(new LogAggregationJob().getJobInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.baeldung.netflix.mantis.job;
|
||||||
|
|
||||||
|
import com.baeldung.netflix.mantis.model.LogAggregate;
|
||||||
|
import com.baeldung.netflix.mantis.source.RandomLogSource;
|
||||||
|
import com.baeldung.netflix.mantis.stage.CountLogStage;
|
||||||
|
import com.baeldung.netflix.mantis.stage.GroupLogStage;
|
||||||
|
import com.baeldung.netflix.mantis.stage.TransformLogStage;
|
||||||
|
import io.mantisrx.runtime.Job;
|
||||||
|
import io.mantisrx.runtime.MantisJob;
|
||||||
|
import io.mantisrx.runtime.MantisJobProvider;
|
||||||
|
import io.mantisrx.runtime.Metadata;
|
||||||
|
import io.mantisrx.runtime.sink.Sink;
|
||||||
|
import io.mantisrx.runtime.sink.Sinks;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class LogAggregationJob extends MantisJobProvider<LogAggregate> {
|
||||||
|
|
||||||
|
private Sink<LogAggregate> sink = Sinks.eagerSubscribe(Sinks.sse(LogAggregate::toJsonString));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Job<LogAggregate> getJobInstance() {
|
||||||
|
|
||||||
|
return MantisJob
|
||||||
|
.source(new RandomLogSource())
|
||||||
|
.stage(new TransformLogStage(), TransformLogStage.stageConfig())
|
||||||
|
.stage(new GroupLogStage(), GroupLogStage.config())
|
||||||
|
.stage(new CountLogStage(), CountLogStage.config())
|
||||||
|
.sink(sink)
|
||||||
|
.metadata(new Metadata.Builder().build())
|
||||||
|
.create();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.baeldung.netflix.mantis.job;
|
||||||
|
|
||||||
|
import com.baeldung.netflix.mantis.model.LogEvent;
|
||||||
|
import com.baeldung.netflix.mantis.sink.LogSink;
|
||||||
|
import com.baeldung.netflix.mantis.source.RandomLogSource;
|
||||||
|
import com.baeldung.netflix.mantis.stage.TransformLogStage;
|
||||||
|
import io.mantisrx.runtime.Job;
|
||||||
|
import io.mantisrx.runtime.MantisJob;
|
||||||
|
import io.mantisrx.runtime.MantisJobProvider;
|
||||||
|
import io.mantisrx.runtime.Metadata;
|
||||||
|
import io.mantisrx.runtime.ScalarToScalar;
|
||||||
|
import io.mantisrx.runtime.sink.Sink;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class LogCollectingJob extends MantisJobProvider<LogEvent> {
|
||||||
|
|
||||||
|
private Sink<LogEvent> sink = new LogSink();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Job<LogEvent> getJobInstance() {
|
||||||
|
|
||||||
|
return MantisJob
|
||||||
|
.source(new RandomLogSource())
|
||||||
|
.stage(new TransformLogStage(), new ScalarToScalar.Config<>())
|
||||||
|
.sink(sink)
|
||||||
|
.metadata(new Metadata.Builder().build())
|
||||||
|
.create();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.baeldung.netflix.mantis.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.mantisrx.runtime.codec.JsonType;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class LogAggregate implements JsonType {
|
||||||
|
|
||||||
|
private static final ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
private Integer count;
|
||||||
|
private String level;
|
||||||
|
|
||||||
|
public String toJsonString() {
|
||||||
|
try {
|
||||||
|
return mapper.writeValueAsString(this);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.baeldung.netflix.mantis.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.mantisrx.runtime.codec.JsonType;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class LogEvent implements JsonType {
|
||||||
|
|
||||||
|
private static final ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
private Long index;
|
||||||
|
private String level;
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public LogEvent(String[] parts) {
|
||||||
|
this.index = Long.valueOf(parts[0]);
|
||||||
|
this.level = parts[1];
|
||||||
|
this.message = parts[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toJsonString() {
|
||||||
|
try {
|
||||||
|
return mapper.writeValueAsString(this);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.baeldung.netflix.mantis.sink;
|
||||||
|
|
||||||
|
import com.baeldung.netflix.mantis.model.LogEvent;
|
||||||
|
import io.mantisrx.runtime.Context;
|
||||||
|
import io.mantisrx.runtime.PortRequest;
|
||||||
|
import io.mantisrx.runtime.sink.SelfDocumentingSink;
|
||||||
|
import io.mantisrx.runtime.sink.ServerSentEventsSink;
|
||||||
|
import io.mantisrx.runtime.sink.Sink;
|
||||||
|
import io.mantisrx.runtime.sink.predicate.Predicate;
|
||||||
|
import rx.Observable;
|
||||||
|
|
||||||
|
public class LogSink implements Sink<LogEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void call(Context context, PortRequest portRequest, Observable<LogEvent> logEventObservable) {
|
||||||
|
|
||||||
|
SelfDocumentingSink<LogEvent> sink = new ServerSentEventsSink.Builder<LogEvent>()
|
||||||
|
.withEncoder(LogEvent::toJsonString)
|
||||||
|
.withPredicate(filterByLogMessage())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
logEventObservable.subscribe();
|
||||||
|
|
||||||
|
sink.call(context, portRequest, logEventObservable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Predicate<LogEvent> filterByLogMessage() {
|
||||||
|
return new Predicate<>("filter by message",
|
||||||
|
parameters -> {
|
||||||
|
if (parameters != null && parameters.containsKey("filter")) {
|
||||||
|
return logEvent -> logEvent.getMessage().contains(parameters.get("filter").get(0));
|
||||||
|
}
|
||||||
|
return logEvent -> true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.baeldung.netflix.mantis.source;
|
||||||
|
|
||||||
|
import io.mantisrx.runtime.Context;
|
||||||
|
import io.mantisrx.runtime.source.Index;
|
||||||
|
import io.mantisrx.runtime.source.Source;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.andreinc.mockneat.MockNeat;
|
||||||
|
import rx.Observable;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class RandomLogSource implements Source<String> {
|
||||||
|
|
||||||
|
private MockNeat mockDataGenerator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context, Index index) {
|
||||||
|
mockDataGenerator = MockNeat.threadLocal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Observable<Observable<String>> call(Context context, Index index) {
|
||||||
|
return Observable.just(
|
||||||
|
Observable
|
||||||
|
.interval(250, TimeUnit.MILLISECONDS)
|
||||||
|
.map(this::createRandomLogEvent));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createRandomLogEvent(Long tick) {
|
||||||
|
String level = mockDataGenerator.probabilites(String.class)
|
||||||
|
.add(0.5, "INFO")
|
||||||
|
.add(0.3, "WARN")
|
||||||
|
.add(0.2, "ERROR")
|
||||||
|
.get();
|
||||||
|
|
||||||
|
String message = mockDataGenerator.probabilites(String.class)
|
||||||
|
.add(0.5, "login attempt")
|
||||||
|
.add(0.5, "user created")
|
||||||
|
.get();
|
||||||
|
|
||||||
|
return tick + "#" + level + "#" + message;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package com.baeldung.netflix.mantis.stage;
|
||||||
|
|
||||||
|
import com.baeldung.netflix.mantis.model.LogAggregate;
|
||||||
|
import com.baeldung.netflix.mantis.model.LogEvent;
|
||||||
|
import io.mantisrx.common.MantisGroup;
|
||||||
|
import io.mantisrx.runtime.Context;
|
||||||
|
import io.mantisrx.runtime.GroupToScalar;
|
||||||
|
import io.mantisrx.runtime.codec.JacksonCodecs;
|
||||||
|
import io.mantisrx.runtime.computation.GroupToScalarComputation;
|
||||||
|
import io.mantisrx.runtime.parameter.ParameterDefinition;
|
||||||
|
import io.mantisrx.runtime.parameter.type.IntParameter;
|
||||||
|
import io.mantisrx.runtime.parameter.validator.Validators;
|
||||||
|
import rx.Observable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class CountLogStage implements GroupToScalarComputation<String, LogEvent, LogAggregate> {
|
||||||
|
|
||||||
|
private int duration;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
duration = (int)context.getParameters().get("LogAggregationDuration", 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Observable<LogAggregate> call(Context context, Observable<MantisGroup<String, LogEvent>> mantisGroup) {
|
||||||
|
return mantisGroup
|
||||||
|
.window(duration, TimeUnit.MILLISECONDS)
|
||||||
|
.flatMap(o -> o.groupBy(MantisGroup::getKeyValue)
|
||||||
|
.flatMap(group -> group.reduce(0, (count, value) -> count = count + 1)
|
||||||
|
.map((count) -> new LogAggregate(count, group.getKey()))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GroupToScalar.Config<String, LogEvent, LogAggregate> config(){
|
||||||
|
return new GroupToScalar.Config<String, LogEvent, LogAggregate>()
|
||||||
|
.description("sum events for a log level")
|
||||||
|
.codec(JacksonCodecs.pojo(LogAggregate.class))
|
||||||
|
.withParameters(getParameters());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ParameterDefinition<?>> getParameters() {
|
||||||
|
List<ParameterDefinition<?>> params = new ArrayList<>();
|
||||||
|
|
||||||
|
params.add(new IntParameter()
|
||||||
|
.name("LogAggregationDuration")
|
||||||
|
.description("window size for aggregation in milliseconds")
|
||||||
|
.validator(Validators.range(100, 10000))
|
||||||
|
.defaultValue(5000)
|
||||||
|
.build()) ;
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.netflix.mantis.stage;
|
||||||
|
|
||||||
|
import com.baeldung.netflix.mantis.model.LogEvent;
|
||||||
|
import io.mantisrx.common.MantisGroup;
|
||||||
|
import io.mantisrx.runtime.Context;
|
||||||
|
import io.mantisrx.runtime.ScalarToGroup;
|
||||||
|
import io.mantisrx.runtime.codec.JacksonCodecs;
|
||||||
|
import io.mantisrx.runtime.computation.ToGroupComputation;
|
||||||
|
import rx.Observable;
|
||||||
|
|
||||||
|
public class GroupLogStage implements ToGroupComputation<LogEvent, String, LogEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Observable<MantisGroup<String, LogEvent>> call(Context context, Observable<LogEvent> logEvent) {
|
||||||
|
return logEvent.map(log -> new MantisGroup<>(log.getLevel(), log));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ScalarToGroup.Config<LogEvent, String, LogEvent> config(){
|
||||||
|
return new ScalarToGroup.Config<LogEvent, String, LogEvent>()
|
||||||
|
.description("Group event data by level")
|
||||||
|
.codec(JacksonCodecs.pojo(LogEvent.class))
|
||||||
|
.concurrentInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.netflix.mantis.stage;
|
||||||
|
|
||||||
|
import com.baeldung.netflix.mantis.model.LogEvent;
|
||||||
|
import io.mantisrx.runtime.Context;
|
||||||
|
import io.mantisrx.runtime.ScalarToScalar;
|
||||||
|
import io.mantisrx.runtime.codec.JacksonCodecs;
|
||||||
|
import io.mantisrx.runtime.computation.ScalarComputation;
|
||||||
|
import rx.Observable;
|
||||||
|
|
||||||
|
public class TransformLogStage implements ScalarComputation<String, LogEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Observable<LogEvent> call(Context context, Observable<String> logEntry) {
|
||||||
|
return logEntry
|
||||||
|
.map(log -> log.split("#"))
|
||||||
|
.filter(parts -> parts.length == 3)
|
||||||
|
.map(LogEvent::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ScalarToScalar.Config<String, LogEvent> stageConfig() {
|
||||||
|
return new ScalarToScalar.Config<String, LogEvent>()
|
||||||
|
.codec(JacksonCodecs.pojo(LogEvent.class));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.baeldung.netflix.mantis.job;
|
||||||
|
|
||||||
|
import com.baeldung.netflix.mantis.model.LogAggregate;
|
||||||
|
import io.mantisrx.runtime.PortRequest;
|
||||||
|
import io.mantisrx.runtime.sink.Sinks;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static java.util.Optional.of;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class LogAggregationJobIntegrationTest extends MantisJobTestBase<LogAggregate> {
|
||||||
|
|
||||||
|
private final static int PORT = 7382;
|
||||||
|
private final static String SINK_URL = "http://localhost:" + PORT;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void beforeAll() {
|
||||||
|
start(new LogAggregationJob((context, portRequest, logAggregateObservable) -> {
|
||||||
|
logAggregateObservable.subscribe();
|
||||||
|
Sinks.sse(LogAggregate::toJsonString).call(context, new PortRequest(PORT), logAggregateObservable);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSinkUrl() {
|
||||||
|
return SINK_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<LogAggregate> getEventType() {
|
||||||
|
return LogAggregate.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenReadingFromSink_thenShouldRetrieveCorrectNumberOfLogAggregates() {
|
||||||
|
assertEquals(of(5L), sinkStream.take(5).count().blockOptional());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenReadingFromSink_thenShouldRetrieveLogAggregate() {
|
||||||
|
assertNotNull(sinkStream.take(1).blockFirst());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenReadingFromSink_thenShouldRetrieveValidLogAggregate() {
|
||||||
|
LogAggregate logAggregate = sinkStream.take(1).blockFirst();
|
||||||
|
|
||||||
|
assertTrue(asList("ERROR", "WARN", "INFO").contains(logAggregate.getLevel()));
|
||||||
|
assertTrue(logAggregate.getCount() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
package com.baeldung.netflix.mantis.job;
|
||||||
|
|
||||||
|
import com.baeldung.netflix.mantis.model.LogEvent;
|
||||||
|
import com.baeldung.netflix.mantis.sink.LogSink;
|
||||||
|
import io.mantisrx.runtime.Context;
|
||||||
|
import io.mantisrx.runtime.PortRequest;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import rx.Observable;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static java.util.Optional.of;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class LogCollectingJobIntegrationTest extends MantisJobTestBase<LogEvent> {
|
||||||
|
|
||||||
|
private final static int PORT = 7381;
|
||||||
|
private final static String SINK_URL = "http://localhost:" + PORT;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void beforeAll() {
|
||||||
|
|
||||||
|
start(new LogCollectingJob(new LogSink() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void call(Context context, PortRequest portRequest, Observable<LogEvent> observable) {
|
||||||
|
super.call(context, new PortRequest(PORT), observable);
|
||||||
|
}
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSinkUrl() {
|
||||||
|
return SINK_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<LogEvent> getEventType() {
|
||||||
|
return LogEvent.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenReadingFromSink_thenShouldRetrieveCorrectNumberOfLogEvents() {
|
||||||
|
assertEquals(of(5L), sinkStream.take(5).count().blockOptional());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenReadingFromSink_thenShouldRetrieveLogEvent() {
|
||||||
|
assertNotNull(sinkStream.take(1).blockFirst());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenReadingFromSink_thenShouldRetrieveValidLogEvent() {
|
||||||
|
LogEvent logEvent = sinkStream.take(1).blockFirst();
|
||||||
|
|
||||||
|
assertTrue(asList("ERROR", "WARN", "INFO").contains(logEvent.getLevel()));
|
||||||
|
assertTrue(asList("login attempt", "user created").contains(logEvent.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenReadingFromSink_thenShouldRetrieveFilteredLogEvents() {
|
||||||
|
getSinkStream(SINK_URL + "?filter=login")
|
||||||
|
.take(7)
|
||||||
|
.toStream().forEach(
|
||||||
|
logEvent -> assertEquals("login attempt", logEvent.getMessage())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.baeldung.netflix.mantis.job;
|
||||||
|
|
||||||
|
import io.mantisrx.runtime.Job;
|
||||||
|
import io.mantisrx.runtime.MantisJobProvider;
|
||||||
|
import io.mantisrx.runtime.executor.LocalJobExecutorNetworked;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
import reactor.util.retry.Retry;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
public abstract class MantisJobTestBase<T> {
|
||||||
|
|
||||||
|
private static Job jobInstance;
|
||||||
|
Flux<T> sinkStream;
|
||||||
|
|
||||||
|
public abstract String getSinkUrl();
|
||||||
|
public abstract Class<T> getEventType();
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
sinkStream = getSinkStream(getSinkUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void afterAll() {
|
||||||
|
stopJob();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Flux<T> getSinkStream(String sinkUrl) {
|
||||||
|
return WebClient.builder().build().get()
|
||||||
|
.uri(sinkUrl)
|
||||||
|
.retrieve()
|
||||||
|
.bodyToFlux(getEventType())
|
||||||
|
.retryWhen(Retry.fixedDelay(10, Duration.ofMillis(2000)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T> void start(MantisJobProvider<T> job) {
|
||||||
|
jobInstance = job.getJobInstance();
|
||||||
|
new Thread(() -> LocalJobExecutorNetworked.execute(jobInstance)).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stopJob() {
|
||||||
|
jobInstance.getLifecycle().shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>genie</module>
|
<module>genie</module>
|
||||||
|
<module>mantis</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
3
persistence-modules/core-java-persistence-2/README.md
Normal file
3
persistence-modules/core-java-persistence-2/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Getting Database URL From JDBC Connection Object](https://www.baeldung.com/jdbc-get-url-from-connection)
|
29
persistence-modules/core-java-persistence-2/pom.xml
Normal file
29
persistence-modules/core-java-persistence-2/pom.xml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?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.core-java-persistence-2</groupId>
|
||||||
|
<artifactId>core-java-persistence-2</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<name>core-java-persistence-2</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>persistence-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<version>${h2.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<h2.version>1.4.200</h2.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.getdburl;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
|
||||||
|
public class DBConfiguration {
|
||||||
|
|
||||||
|
public static Connection getConnection() throws Exception {
|
||||||
|
Class.forName("org.h2.Driver");
|
||||||
|
String url = "jdbc:h2:mem:testdb";
|
||||||
|
return DriverManager.getConnection(url, "user", "password");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.baeldung.getdburl;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class DBConfigurationUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenConnectionObject_whenExtractMetaData_thenGetDbURL() throws Exception {
|
||||||
|
Connection connection = DBConfiguration.getConnection();
|
||||||
|
String dbUrl = connection.getMetaData().getURL();
|
||||||
|
assertEquals("jdbc:h2:mem:testdb", dbUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -76,10 +76,6 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<flyway.configFiles>src/main/resources/application-${spring-boot.run.profiles}.properties</flyway.configFiles>
|
<flyway.configFiles>src/main/resources/application-${spring-boot.run.profiles}.properties</flyway.configFiles>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -66,10 +66,6 @@
|
|||||||
<flyway-core.version>5.2.3</flyway-core.version>
|
<flyway-core.version>5.2.3</flyway-core.version>
|
||||||
<flyway-maven-plugin.version>5.0.2</flyway-maven-plugin.version>
|
<flyway-maven-plugin.version>5.0.2</flyway-maven-plugin.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -8,7 +8,7 @@ public class Application {
|
|||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
EntityManager entityManager = getJpaEntityManager();
|
EntityManager entityManager = getJpaEntityManager();
|
||||||
User user = entityManager.find(User.class, 1);
|
User user = entityManager.find(User.class, 1l);
|
||||||
System.out.println(user);
|
System.out.println(user);
|
||||||
entityManager.getTransaction().begin();
|
entityManager.getTransaction().begin();
|
||||||
user.setName("John");
|
user.setName("John");
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package com.baeldung.hibernate.onetoone.sharedkeybased;
|
package com.baeldung.hibernate.onetoone.sharedkeybased;
|
||||||
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.MapsId;
|
import javax.persistence.MapsId;
|
||||||
import javax.persistence.OneToOne;
|
import javax.persistence.OneToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
@ -13,7 +13,7 @@ import javax.persistence.Table;
|
|||||||
public class Address {
|
public class Address {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@Column(name = "id")
|
@Column(name = "user_id")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Column(name = "street")
|
@Column(name = "street")
|
||||||
@ -24,6 +24,7 @@ public class Address {
|
|||||||
|
|
||||||
@OneToOne
|
@OneToOne
|
||||||
@MapsId
|
@MapsId
|
||||||
|
@JoinColumn(name = "user_id")
|
||||||
private User user;
|
private User user;
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
|
@ -8,6 +8,7 @@ import javax.persistence.GeneratedValue;
|
|||||||
import javax.persistence.GenerationType;
|
import javax.persistence.GenerationType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.OneToOne;
|
import javax.persistence.OneToOne;
|
||||||
|
import javax.persistence.PrimaryKeyJoinColumn;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@ -22,6 +23,7 @@ public class User {
|
|||||||
private String userName;
|
private String userName;
|
||||||
|
|
||||||
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
|
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
|
||||||
|
@PrimaryKeyJoinColumn
|
||||||
private Address address;
|
private Address address;
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<module>apache-bookkeeper</module><!-- BAEL-2322 -->
|
<module>apache-bookkeeper</module><!-- BAEL-2322 -->
|
||||||
<module>apache-cayenne</module>
|
<module>apache-cayenne</module>
|
||||||
<module>core-java-persistence</module>
|
<module>core-java-persistence</module>
|
||||||
|
<module>core-java-persistence-2</module>
|
||||||
<module>deltaspike</module>
|
<module>deltaspike</module>
|
||||||
<module>elasticsearch</module>
|
<module>elasticsearch</module>
|
||||||
<module>flyway</module>
|
<module>flyway</module>
|
||||||
|
@ -69,10 +69,6 @@
|
|||||||
<r2dbc-h2.version>0.8.1.RELEASE</r2dbc-h2.version>
|
<r2dbc-h2.version>0.8.1.RELEASE</r2dbc-h2.version>
|
||||||
<h2.version>1.4.200</h2.version>
|
<h2.version>1.4.200</h2.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -62,10 +62,6 @@
|
|||||||
<jedis.version>3.3.0</jedis.version>
|
<jedis.version>3.3.0</jedis.version>
|
||||||
<epoll.version>4.1.50.Final</epoll.version>
|
<epoll.version>4.1.50.Final</epoll.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -40,10 +40,6 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<mysql-connector-java.version>8.0.12</mysql-connector-java.version>
|
<mysql-connector-java.version>8.0.12</mysql-connector-java.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -5,4 +5,5 @@
|
|||||||
- [Integrating Spring Boot with HSQLDB](https://www.baeldung.com/spring-boot-hsqldb)
|
- [Integrating Spring Boot with HSQLDB](https://www.baeldung.com/spring-boot-hsqldb)
|
||||||
- [List of In-Memory Databases](https://www.baeldung.com/java-in-memory-databases)
|
- [List of In-Memory Databases](https://www.baeldung.com/java-in-memory-databases)
|
||||||
- [Oracle Connection Pooling With Spring](https://www.baeldung.com/spring-oracle-connection-pooling)
|
- [Oracle Connection Pooling With Spring](https://www.baeldung.com/spring-oracle-connection-pooling)
|
||||||
|
- [Object States in Hibernate’s Session](https://www.baeldung.com/hibernate-session-object-states)
|
||||||
- More articles: [[<-- prev]](../spring-boot-persistence)
|
- More articles: [[<-- prev]](../spring-boot-persistence)
|
||||||
|
@ -47,10 +47,6 @@
|
|||||||
<start-class>com.baeldung.h2db.demo.server.SpringBootApp</start-class>
|
<start-class>com.baeldung.h2db.demo.server.SpringBootApp</start-class>
|
||||||
<db-util.version>1.0.4</db-util.version>
|
<db-util.version>1.0.4</db-util.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -37,9 +37,5 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
@ -76,11 +76,6 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<mockito.version>2.23.0</mockito.version>
|
<mockito.version>2.23.0</mockito.version>
|
||||||
<validation-api.version>2.0.1.Final</validation-api.version>
|
<validation-api.version>2.0.1.Final</validation-api.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -54,10 +54,6 @@
|
|||||||
<spring-boot.version>2.2.6.RELEASE</spring-boot.version>
|
<spring-boot.version>2.2.6.RELEASE</spring-boot.version>
|
||||||
<cassandra-unit-spring.version>3.11.2.0</cassandra-unit-spring.version>
|
<cassandra-unit-spring.version>3.11.2.0</cassandra-unit-spring.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -105,10 +105,6 @@
|
|||||||
<cassandra-unit-shaded.version>2.1.9.2</cassandra-unit-shaded.version>
|
<cassandra-unit-shaded.version>2.1.9.2</cassandra-unit-shaded.version>
|
||||||
<hector-core.version>2.0-0</hector-core.version>
|
<hector-core.version>2.0-0</hector-core.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -17,10 +17,6 @@
|
|||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<cosmodb.version>2.3.0</cosmodb.version>
|
<cosmodb.version>2.3.0</cosmodb.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -182,11 +182,6 @@
|
|||||||
<dynamodblocal.version>1.11.86</dynamodblocal.version>
|
<dynamodblocal.version>1.11.86</dynamodblocal.version>
|
||||||
<dynamodblocal.repository.url>https://s3-us-west-2.amazonaws.com/dynamodb-local/release</dynamodblocal.repository.url>
|
<dynamodblocal.repository.url>https://s3-us-west-2.amazonaws.com/dynamodb-local/release</dynamodblocal.repository.url>
|
||||||
<maven-dependency-plugin.version>3.1.1</maven-dependency-plugin.version>
|
<maven-dependency-plugin.version>3.1.1</maven-dependency-plugin.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -69,10 +69,5 @@
|
|||||||
<fastjson.version>1.2.47</fastjson.version>
|
<fastjson.version>1.2.47</fastjson.version>
|
||||||
<spatial4j.version>0.7</spatial4j.version>
|
<spatial4j.version>0.7</spatial4j.version>
|
||||||
<jts.version>1.15.0</jts.version>
|
<jts.version>1.15.0</jts.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
@ -28,9 +28,5 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
||||||
|
@ -73,10 +73,6 @@
|
|||||||
<postgresql.version>42.2.5</postgresql.version>
|
<postgresql.version>42.2.5</postgresql.version>
|
||||||
<guava.version>21.0</guava.version>
|
<guava.version>21.0</guava.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Prod Dependencies -->
|
<!-- Prod Dependencies -->
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
@ -66,11 +62,6 @@
|
|||||||
<datasource-proxy.version>1.4.1</datasource-proxy.version>
|
<datasource-proxy.version>1.4.1</datasource-proxy.version>
|
||||||
<guava.version>21.0</guava.version>
|
<guava.version>21.0</guava.version>
|
||||||
<testcontainers.version>1.12.2</testcontainers.version>
|
<testcontainers.version>1.12.2</testcontainers.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -99,10 +99,6 @@
|
|||||||
<guava.version>21.0</guava.version>
|
<guava.version>21.0</guava.version>
|
||||||
<testcontainers.version>1.12.2</testcontainers.version>
|
<testcontainers.version>1.12.2</testcontainers.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -73,10 +73,6 @@
|
|||||||
<postgresql.version>42.2.5</postgresql.version>
|
<postgresql.version>42.2.5</postgresql.version>
|
||||||
<guava.version>21.0</guava.version>
|
<guava.version>21.0</guava.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -84,10 +84,6 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
<tomcat-dbcp.version>9.0.0.M26</tomcat-dbcp.version>
|
<tomcat-dbcp.version>9.0.0.M26</tomcat-dbcp.version>
|
||||||
<jta.version>1.1</jta.version>
|
<jta.version>1.1</jta.version>
|
||||||
<guava.version>21.0</guava.version>
|
<guava.version>21.0</guava.version>
|
||||||
|
@ -44,10 +44,6 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<datasource-proxy.version>1.4.1</datasource-proxy.version>
|
<datasource-proxy.version>1.4.1</datasource-proxy.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -44,9 +44,5 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<guava.version>29.0-jre</guava.version>
|
<guava.version>29.0-jre</guava.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
@ -50,9 +50,6 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
@ -29,9 +29,6 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
@ -108,10 +108,6 @@
|
|||||||
<projectreactor.version>3.2.0.RELEASE</projectreactor.version>
|
<projectreactor.version>3.2.0.RELEASE</projectreactor.version>
|
||||||
<mongodb-driver.version>4.0.5</mongodb-driver.version>
|
<mongodb-driver.version>4.0.5</mongodb-driver.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -98,11 +98,6 @@
|
|||||||
<cglib.version>3.2.4</cglib.version>
|
<cglib.version>3.2.4</cglib.version>
|
||||||
<nosqlunit.version>0.10.0</nosqlunit.version>
|
<nosqlunit.version>0.10.0</nosqlunit.version>
|
||||||
<embedded-redis.version>0.6</embedded-redis.version>
|
<embedded-redis.version>0.6</embedded-redis.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -5,7 +5,6 @@ import org.springframework.context.annotation.ComponentScan;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.PropertySource;
|
import org.springframework.context.annotation.PropertySource;
|
||||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.data.redis.listener.ChannelTopic;
|
import org.springframework.data.redis.listener.ChannelTopic;
|
||||||
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
||||||
|
@ -1,16 +1,32 @@
|
|||||||
package com.baeldung;
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.annotation.DirtiesContext.ClassMode;
|
||||||
|
|
||||||
import com.baeldung.spring.data.redis.config.RedisConfig;
|
import com.baeldung.spring.data.redis.SpringRedisApplication;
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
import redis.embedded.RedisServerBuilder;
|
||||||
@ContextConfiguration(classes = RedisConfig.class)
|
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringRedisApplication.class)
|
||||||
|
@DirtiesContext(classMode = ClassMode.BEFORE_CLASS)
|
||||||
public class SpringContextTest {
|
public class SpringContextTest {
|
||||||
|
|
||||||
|
private static redis.embedded.RedisServer redisServer;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void startRedisServer() {
|
||||||
|
redisServer = new RedisServerBuilder().port(6379).setting("maxmemory 256M").build();
|
||||||
|
redisServer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void stopRedisServer() {
|
||||||
|
redisServer.stop();
|
||||||
|
}
|
||||||
@Test
|
@Test
|
||||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||||
}
|
}
|
||||||
|
@ -46,10 +46,6 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<spring-data-solr.version>2.0.5.RELEASE</spring-data-solr.version>
|
<spring-data-solr.version>2.0.5.RELEASE</spring-data-solr.version>
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -18,7 +18,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-jdbc</artifactId>
|
<artifactId>spring-data-jdbc</artifactId>
|
||||||
<version>${spring-data-jdbc.version}</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@ -36,11 +35,5 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<spring-data-jdbc.version>2.0.3.RELEASE</spring-data-jdbc.version>
|
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
|
||||||
<junit-jupiter.version>5.6.2</junit-jupiter.version>
|
|
||||||
<junit.version>4.13</junit.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
@ -7,6 +7,7 @@
|
|||||||
- [Transaction Propagation and Isolation in Spring @Transactional](https://www.baeldung.com/spring-transactional-propagation-isolation)
|
- [Transaction Propagation and Isolation in Spring @Transactional](https://www.baeldung.com/spring-transactional-propagation-isolation)
|
||||||
- [JTA Transaction with Spring](https://www.baeldung.com/spring-vs-jta-transactional)
|
- [JTA Transaction with Spring](https://www.baeldung.com/spring-vs-jta-transactional)
|
||||||
- [Test a Mock JNDI Datasource with Spring](https://www.baeldung.com/spring-mock-jndi-datasource)
|
- [Test a Mock JNDI Datasource with Spring](https://www.baeldung.com/spring-mock-jndi-datasource)
|
||||||
|
- [Detecting If a Spring Transaction Is Active](https://www.baeldung.com/spring-transaction-active)
|
||||||
|
|
||||||
### 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:
|
||||||
|
@ -9,3 +9,4 @@ This module contains articles about Spring Boot annotations
|
|||||||
- [Spring Web Annotations](https://www.baeldung.com/spring-mvc-annotations)
|
- [Spring Web Annotations](https://www.baeldung.com/spring-mvc-annotations)
|
||||||
- [Spring Core Annotations](https://www.baeldung.com/spring-core-annotations)
|
- [Spring Core Annotations](https://www.baeldung.com/spring-core-annotations)
|
||||||
- [Spring Bean Annotations](https://www.baeldung.com/spring-bean-annotations)
|
- [Spring Bean Annotations](https://www.baeldung.com/spring-bean-annotations)
|
||||||
|
- [Difference Between @ComponentScan and @EnableAutoConfiguration in Spring Boot](https://www.baeldung.com/spring-componentscan-vs-enableautoconfiguration)
|
||||||
|
@ -4,11 +4,12 @@
|
|||||||
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>
|
||||||
|
|
||||||
|
<!-- this module should use the Boot parent directly to avoid inherit the logback dependency from our other parents -->
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung.spring-boot-modules</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-modules</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>2.1.1.RELEASE</version>
|
||||||
<relativePath>../</relativePath>
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>spring-boot-mvc-birt</artifactId>
|
<artifactId>spring-boot-mvc-birt</artifactId>
|
||||||
@ -19,10 +20,6 @@
|
|||||||
<description>Module For Spring Boot Integration with BIRT</description>
|
<description>Module For Spring Boot Integration with BIRT</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@ -51,17 +48,14 @@
|
|||||||
<artifactId>org.eclipse.birt.runtime_4.8.0-20180626</artifactId>
|
<artifactId>org.eclipse.birt.runtime_4.8.0-20180626</artifactId>
|
||||||
<version>${eclipse.birt.runtime.version}</version>
|
<version>${eclipse.birt.runtime.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>log4j</groupId>
|
<groupId>log4j</groupId>
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>log4j</artifactId>
|
||||||
<version>${log4j.version}</version>
|
<version>${log4j.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>${lombok.version}</version>
|
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@ -81,6 +75,7 @@
|
|||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
<eclipse.birt.runtime.version>4.8.0</eclipse.birt.runtime.version>
|
<eclipse.birt.runtime.version>4.8.0</eclipse.birt.runtime.version>
|
||||||
|
<log4j.version>1.2.17</log4j.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
# Set root logger level to DEBUG and its only appender to A1.
|
||||||
|
log4j.rootLogger=DEBUG, A1
|
||||||
|
|
||||||
|
# A1 is set to be a ConsoleAppender.
|
||||||
|
log4j.appender.A1=org.apache.log4j.ConsoleAppender
|
||||||
|
|
||||||
|
# A1 uses PatternLayout.
|
||||||
|
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.birt.engine;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
public class SpringContextTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ package com.baeldung.cloud.openfeign.config;
|
|||||||
|
|
||||||
import feign.Logger;
|
import feign.Logger;
|
||||||
import feign.RequestInterceptor;
|
import feign.RequestInterceptor;
|
||||||
|
import feign.auth.BasicAuthRequestInterceptor;
|
||||||
import feign.codec.ErrorDecoder;
|
import feign.codec.ErrorDecoder;
|
||||||
import feign.okhttp.OkHttpClient;
|
import feign.okhttp.OkHttpClient;
|
||||||
import org.apache.http.entity.ContentType;
|
import org.apache.http.entity.ContentType;
|
||||||
@ -34,4 +35,9 @@ public class ClientConfiguration {
|
|||||||
requestTemplate.header("Accept", ContentType.APPLICATION_JSON.getMimeType());
|
requestTemplate.header("Accept", ContentType.APPLICATION_JSON.getMimeType());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Bean - uncomment to use this interceptor and remove @Bean from the requestInterceptor()
|
||||||
|
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
|
||||||
|
return new BasicAuthRequestInterceptor("ajeje", "brazof");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@
|
|||||||
<httpcore.version>4.4.9</httpcore.version>
|
<httpcore.version>4.4.9</httpcore.version>
|
||||||
<httpclient.version>4.5.5</httpclient.version>
|
<httpclient.version>4.5.5</httpclient.version>
|
||||||
<javax.servlet-api.version>4.0.0</javax.servlet-api.version>
|
<javax.servlet-api.version>4.0.0</javax.servlet-api.version>
|
||||||
<wiremock.version>2.25.1</wiremock.version>
|
<wiremock.version>2.27.2</wiremock.version>
|
||||||
<assertj-core.version>3.10.0</assertj-core.version>
|
<assertj-core.version>3.10.0</assertj-core.version>
|
||||||
<spring-boot.version>1.5.10.RELEASE</spring-boot.version>
|
<spring-boot.version>1.5.10.RELEASE</spring-boot.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
@ -206,7 +206,7 @@
|
|||||||
<lifecycle-mapping.version>1.0.0</lifecycle-mapping.version>
|
<lifecycle-mapping.version>1.0.0</lifecycle-mapping.version>
|
||||||
<sql-maven-plugin.version>1.5</sql-maven-plugin.version>
|
<sql-maven-plugin.version>1.5</sql-maven-plugin.version>
|
||||||
<properties-maven-plugin.version>1.0.0</properties-maven-plugin.version>
|
<properties-maven-plugin.version>1.0.0</properties-maven-plugin.version>
|
||||||
<start-class>org.jooq.example.spring.Application</start-class>
|
<h2.version>1.4.198</h2.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -119,7 +119,7 @@ public class EmailConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
public ResourceBundleMessageSource emailMessageSource() {
|
public ResourceBundleMessageSource emailMessageSource() {
|
||||||
final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
|
final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
|
||||||
messageSource.setBasename("/mailMessages");
|
messageSource.setBasename("mailMessages");
|
||||||
return messageSource;
|
return messageSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,11 +11,7 @@ public class MaxSizeConstraintValidator implements ConstraintValidator<MaxSizeCo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid(List<Movie> values, ConstraintValidatorContext context) {
|
public boolean isValid(List<Movie> values, ConstraintValidatorContext context) {
|
||||||
boolean isValid = true;
|
return values.size() <= 4;
|
||||||
if (values.size() > 4) {
|
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
return isValid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.baeldung.resttemplate;
|
package com.baeldung.resttemplate;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
package com.baeldung.resttemplate.logging;
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
|
||||||
@EnableAutoConfiguration
|
|
||||||
public class RestTemplateConfigurationApplication {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication.run(RestTemplateConfigurationApplication.class, args);
|
|
||||||
}
|
|
||||||
}
|
|
@ -14,16 +14,18 @@ import org.springframework.http.client.ClientHttpResponse;
|
|||||||
|
|
||||||
public class LoggingInterceptor implements ClientHttpRequestInterceptor {
|
public class LoggingInterceptor implements ClientHttpRequestInterceptor {
|
||||||
|
|
||||||
final static Logger log = LoggerFactory.getLogger(LoggingInterceptor.class);
|
final static Logger LOGGER = LoggerFactory.getLogger(LoggingInterceptor.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientHttpResponse intercept(HttpRequest req, byte[] reqBody, ClientHttpRequestExecution ex) throws IOException {
|
public ClientHttpResponse intercept(HttpRequest req, byte[] reqBody, ClientHttpRequestExecution ex) throws IOException {
|
||||||
log.debug("Request body: {}", new String(reqBody, StandardCharsets.UTF_8));
|
LOGGER.debug("Request body: {}", new String(reqBody, StandardCharsets.UTF_8));
|
||||||
ClientHttpResponse response = ex.execute(req, reqBody);
|
ClientHttpResponse response = ex.execute(req, reqBody);
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
InputStreamReader isr = new InputStreamReader(response.getBody(), StandardCharsets.UTF_8);
|
InputStreamReader isr = new InputStreamReader(response.getBody(), StandardCharsets.UTF_8);
|
||||||
String body = new BufferedReader(isr).lines()
|
String body = new BufferedReader(isr).lines()
|
||||||
.collect(Collectors.joining("\n"));
|
.collect(Collectors.joining("\n"));
|
||||||
log.debug("Response body: {}", body);
|
LOGGER.debug("Response body: {}", body);
|
||||||
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
package com.baeldung.resttemplate.logging;
|
package com.baeldung.resttemplate.logging;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||||
|
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||||
|
import org.springframework.http.client.BufferingClientHttpRequestFactory;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
@ -22,6 +25,7 @@ import org.springframework.web.client.RestTemplate;
|
|||||||
public class RestTemplateLoggingLiveTest {
|
public class RestTemplateLoggingLiveTest {
|
||||||
|
|
||||||
private static final String baseUrl = "http://localhost:8080/spring-rest";
|
private static final String baseUrl = "http://localhost:8080/spring-rest";
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(RestTemplateLoggingLiveTest.class);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenHttpClientConfiguration_whenSendGetForRequestEntity_thenRequestResponseFullLog() {
|
public void givenHttpClientConfiguration_whenSendGetForRequestEntity_thenRequestResponseFullLog() {
|
||||||
@ -30,13 +34,22 @@ public class RestTemplateLoggingLiveTest {
|
|||||||
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
|
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
|
||||||
|
|
||||||
final ResponseEntity<String> response = restTemplate.postForEntity(baseUrl + "/persons", "my request body", String.class);
|
final ResponseEntity<String> response = restTemplate.postForEntity(baseUrl + "/persons", "my request body", String.class);
|
||||||
assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
|
assertEquals("[\"Lucie\",\"Jackie\",\"Danesh\",\"Tao\"]", response.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenLoggingInterceptorConfiguration_whenSendGetForRequestEntity_thenRequestResponseCustomLog() {
|
public void givenLoggingInterceptorConfiguration_whenSendGetForRequestEntity_thenRequestResponseCustomLog() {
|
||||||
|
|
||||||
RestTemplate restTemplate = new RestTemplate();
|
RestTemplate restTemplate = null;
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(
|
||||||
|
new SimpleClientHttpRequestFactory());
|
||||||
|
restTemplate = new RestTemplate(factory);
|
||||||
|
} else {
|
||||||
|
restTemplate = new RestTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
|
List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
|
||||||
if (CollectionUtils.isEmpty(interceptors)) {
|
if (CollectionUtils.isEmpty(interceptors)) {
|
||||||
interceptors = new ArrayList<>();
|
interceptors = new ArrayList<>();
|
||||||
@ -45,6 +58,7 @@ public class RestTemplateLoggingLiveTest {
|
|||||||
restTemplate.setInterceptors(interceptors);
|
restTemplate.setInterceptors(interceptors);
|
||||||
|
|
||||||
final ResponseEntity<String> response = restTemplate.postForEntity(baseUrl + "/persons", "my request body", String.class);
|
final ResponseEntity<String> response = restTemplate.postForEntity(baseUrl + "/persons", "my request body", String.class);
|
||||||
assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
|
assertEquals("[\"Lucie\",\"Jackie\",\"Danesh\",\"Tao\"]", response.getBody());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
logging.level.org.springframework.web.client.RestTemplate=DEBUG
|
logging.level.org.springframework.web.client.RestTemplate=DEBUG
|
||||||
logging.level.com.baeldung.resttemplate.logging.LoggingInterceptor=DEBUG
|
logging.level.com.baeldung.resttemplate.logging=DEBUG
|
||||||
logging.level.org.apache.http=DEBUG
|
logging.level.org.apache.http=DEBUG
|
||||||
logging.level.httpclient.wire=DEBUG
|
logging.level.httpclient.wire=DEBUG
|
||||||
logging.pattern.console=%20logger{20} - %msg%n
|
logging.pattern.console=%20logger{20} - %msg%n
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
<module>spring-security-web-login</module>
|
<module>spring-security-web-login</module>
|
||||||
<module>spring-security-web-persisted-remember-me</module>
|
<module>spring-security-web-persisted-remember-me</module>
|
||||||
<module>spring-security-web-sockets</module>
|
<module>spring-security-web-sockets</module>
|
||||||
|
<module>spring-security-legacy-oidc</module>
|
||||||
<module>spring-security-oidc</module>
|
<module>spring-security-oidc</module>
|
||||||
<module>spring-security-okta</module>
|
<module>spring-security-okta</module>
|
||||||
<module>spring-security-web-react</module>
|
<module>spring-security-web-react</module>
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
## Spring Security OpenID
|
||||||
|
|
||||||
|
This module contains articles about OpenID with Spring Security
|
||||||
|
|
||||||
|
### Relevant articles
|
||||||
|
|
||||||
|
- [Spring Security and OpenID Connect (Legacy)](https://www.baeldung.com/spring-security-openid-connect-legacy)
|
||||||
|
|
||||||
|
### OpenID Connect with Spring Security
|
||||||
|
|
||||||
|
### Run the Project
|
||||||
|
|
||||||
|
```
|
||||||
|
mvn spring-boot:run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Obtain Google App - Client ID, Secret
|
||||||
|
|
||||||
|
- We need to get client id and client secret by creating a new project at [Google Developer Console](https://console.developers.google.com/project/_/apiui/credential?pli=1)
|
||||||
|
- We can follow these instructions to register our client application on their platform
|
||||||
|
|
||||||
|
- Once we have the client id and secret, we have to make sure we add them to the application.properties file.
|
||||||
|
|
58
spring-security-modules/spring-security-legacy-oidc/pom.xml
Normal file
58
spring-security-modules/spring-security-legacy-oidc/pom.xml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?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-security-legacy-oidc</artifactId>
|
||||||
|
<name>spring-security-legacy-oidc</name>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<description>Spring OpenID Connect sample project</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-boot-2</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../parent-boot-2</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</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-tomcat</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security.oauth</groupId>
|
||||||
|
<artifactId>spring-security-oauth2</artifactId>
|
||||||
|
<version>${spring-security-oauth2.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-jwt</artifactId>
|
||||||
|
<version>${spring-security-jwt.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.auth0</groupId>
|
||||||
|
<artifactId>jwks-rsa</artifactId>
|
||||||
|
<version>${jwks-rsa.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<spring-security-oauth2.version>2.2.1.RELEASE</spring-security-oauth2.version>
|
||||||
|
<spring-security-jwt.version>1.0.9.RELEASE</spring-security-jwt.version>
|
||||||
|
<jwks-rsa.version>0.3.0</jwks-rsa.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.baeldung.openid.oidc;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2ClientContext;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
|
||||||
|
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
|
||||||
|
import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
|
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableOAuth2Client
|
||||||
|
public class GoogleOpenIdConnectConfig {
|
||||||
|
@Value("${google.clientId}")
|
||||||
|
private String clientId;
|
||||||
|
|
||||||
|
@Value("${google.clientSecret}")
|
||||||
|
private String clientSecret;
|
||||||
|
|
||||||
|
@Value("${google.accessTokenUri}")
|
||||||
|
private String accessTokenUri;
|
||||||
|
|
||||||
|
@Value("${google.userAuthorizationUri}")
|
||||||
|
private String userAuthorizationUri;
|
||||||
|
|
||||||
|
@Value("${google.redirectUri}")
|
||||||
|
private String redirectUri;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public OAuth2ProtectedResourceDetails googleOpenId() {
|
||||||
|
final AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
|
||||||
|
details.setClientId(clientId);
|
||||||
|
details.setClientSecret(clientSecret);
|
||||||
|
details.setAccessTokenUri(accessTokenUri);
|
||||||
|
details.setUserAuthorizationUri(userAuthorizationUri);
|
||||||
|
details.setScope(Arrays.asList("openid", "email"));
|
||||||
|
details.setPreEstablishedRedirectUri(redirectUri);
|
||||||
|
details.setUseCurrentUri(false);
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public OAuth2RestTemplate googleOpenIdTemplate(final OAuth2ClientContext clientContext) {
|
||||||
|
final OAuth2RestTemplate template = new OAuth2RestTemplate(googleOpenId(), clientContext);
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.baeldung.openid.oidc;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class HomeController {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
@RequestMapping("/")
|
||||||
|
@ResponseBody
|
||||||
|
public final String home() {
|
||||||
|
final String username = SecurityContextHolder.getContext().getAuthentication().getName();
|
||||||
|
logger.info(username);
|
||||||
|
return "Welcome, " + username;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
package com.baeldung.openid.oidc;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.security.interfaces.RSAPublicKey;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.jwt.Jwt;
|
||||||
|
import org.springframework.security.jwt.JwtHelper;
|
||||||
|
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2RestOperations;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
|
||||||
|
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||||
|
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||||
|
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||||
|
|
||||||
|
import com.auth0.jwk.Jwk;
|
||||||
|
import com.auth0.jwk.JwkProvider;
|
||||||
|
import com.auth0.jwk.UrlJwkProvider;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
public class OpenIdConnectFilter extends AbstractAuthenticationProcessingFilter {
|
||||||
|
@Value("${google.clientId}")
|
||||||
|
private String clientId;
|
||||||
|
|
||||||
|
@Value("${google.issuer}")
|
||||||
|
private String issuer;
|
||||||
|
|
||||||
|
@Value("${google.jwkUrl}")
|
||||||
|
private String jwkUrl;
|
||||||
|
|
||||||
|
public OAuth2RestOperations restTemplate;
|
||||||
|
|
||||||
|
public OpenIdConnectFilter(String defaultFilterProcessesUrl) {
|
||||||
|
super(defaultFilterProcessesUrl);
|
||||||
|
setAuthenticationManager(new NoopAuthenticationManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
|
||||||
|
|
||||||
|
OAuth2AccessToken accessToken;
|
||||||
|
try {
|
||||||
|
accessToken = restTemplate.getAccessToken();
|
||||||
|
} catch (final OAuth2Exception e) {
|
||||||
|
throw new BadCredentialsException("Could not obtain access token", e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final String idToken = accessToken.getAdditionalInformation().get("id_token").toString();
|
||||||
|
String kid = JwtHelper.headers(idToken)
|
||||||
|
.get("kid");
|
||||||
|
final Jwt tokenDecoded = JwtHelper.decodeAndVerify(idToken, verifier(kid));
|
||||||
|
final Map<String, String> authInfo = new ObjectMapper().readValue(tokenDecoded.getClaims(), Map.class);
|
||||||
|
verifyClaims(authInfo);
|
||||||
|
final OpenIdConnectUserDetails user = new OpenIdConnectUserDetails(authInfo, accessToken);
|
||||||
|
return new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new BadCredentialsException("Could not obtain user details from token", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void verifyClaims(Map claims) {
|
||||||
|
int exp = (int) claims.get("exp");
|
||||||
|
Date expireDate = new Date(exp * 1000L);
|
||||||
|
Date now = new Date();
|
||||||
|
if (expireDate.before(now) || !claims.get("iss").equals(issuer) || !claims.get("aud").equals(clientId)) {
|
||||||
|
throw new RuntimeException("Invalid claims");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private RsaVerifier verifier(String kid) throws Exception {
|
||||||
|
JwkProvider provider = new UrlJwkProvider(new URL(jwkUrl));
|
||||||
|
Jwk jwk = provider.get(kid);
|
||||||
|
return new RsaVerifier((RSAPublicKey) jwk.getPublicKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRestTemplate(OAuth2RestTemplate restTemplate2) {
|
||||||
|
restTemplate = restTemplate2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NoopAuthenticationManager implements AuthenticationManager {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||||
|
throw new UnsupportedOperationException("No authentication should be done with this AuthenticationManager");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
package com.baeldung.openid.oidc;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||||
|
|
||||||
|
public class OpenIdConnectUserDetails implements UserDetails {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String userId;
|
||||||
|
private String username;
|
||||||
|
private OAuth2AccessToken token;
|
||||||
|
|
||||||
|
public OpenIdConnectUserDetails(Map<String, String> userInfo, OAuth2AccessToken token) {
|
||||||
|
this.userId = userInfo.get("sub");
|
||||||
|
this.username = userInfo.get("email");
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
|
return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserId(String userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OAuth2AccessToken getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(OAuth2AccessToken token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonExpired() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonLocked() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCredentialsNonExpired() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user