Merge branch 'master' into BAEL-2088-HibernateExceptions
This commit is contained in:
commit
262d2efb7b
|
@ -14,7 +14,7 @@ Java and Spring Tutorials
|
||||||
================
|
================
|
||||||
|
|
||||||
This project is **a collection of small and focused tutorials** - each covering a single and well defined area of development in the Java ecosystem.
|
This project is **a collection of small and focused tutorials** - each covering a single and well defined area of development in the Java ecosystem.
|
||||||
A strong focus of these is, of course, the Spring Framework - Spring, Spring Boot and Spring Securiyt.
|
A strong focus of these is, of course, the Spring Framework - Spring, Spring Boot and Spring Security.
|
||||||
In additional to Spring, the following technologies are in focus: `core Java`, `Jackson`, `HttpClient`, `Guava`.
|
In additional to Spring, the following technologies are in focus: `core Java`, `Jackson`, `HttpClient`, `Guava`.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
## Relevant articles:
|
||||||
|
|
||||||
|
- [Introduction to Akka HTTP](https://www.baeldung.com/akka-http)
|
|
@ -12,4 +12,6 @@
|
||||||
- [Check If a String Contains All The Letters of The Alphabet](https://www.baeldung.com/java-string-contains-all-letters)
|
- [Check If a String Contains All The Letters of The Alphabet](https://www.baeldung.com/java-string-contains-all-letters)
|
||||||
- [Find the Middle Element of a Linked List](http://www.baeldung.com/java-linked-list-middle-element)
|
- [Find the Middle Element of a Linked List](http://www.baeldung.com/java-linked-list-middle-element)
|
||||||
- [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial)
|
- [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial)
|
||||||
- [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings)
|
- [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings)
|
||||||
|
- [Find the Longest Substring without Repeating Characters](https://www.baeldung.com/java-longest-substring-without-repeated-characters)
|
||||||
|
- [Java Two Pointer Technique](https://www.baeldung.com/java-two-pointer-technique)
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
package com.baeldung.algorithms.permutation;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
public class Permutation {
|
||||||
|
|
||||||
|
public static <T> void printAllRecursive(T[] elements, char delimiter) {
|
||||||
|
printAllRecursive(elements.length, elements, delimiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void printAllRecursive(int n, T[] elements, char delimiter) {
|
||||||
|
|
||||||
|
if(n == 1) {
|
||||||
|
printArray(elements, delimiter);
|
||||||
|
} else {
|
||||||
|
for(int i = 0; i < n-1; i++) {
|
||||||
|
printAllRecursive(n - 1, elements, delimiter);
|
||||||
|
if(n % 2 == 0) {
|
||||||
|
swap(elements, i, n-1);
|
||||||
|
} else {
|
||||||
|
swap(elements, 0, n-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printAllRecursive(n - 1, elements, delimiter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void printAllIterative(int n, T[] elements, char delimiter) {
|
||||||
|
|
||||||
|
int[] indexes = new int[n];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
indexes[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printArray(elements, delimiter);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (i < n) {
|
||||||
|
if (indexes[i] < i) {
|
||||||
|
swap(elements, i % 2 == 0 ? 0: indexes[i], i);
|
||||||
|
printArray(elements, delimiter);
|
||||||
|
indexes[i]++;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
indexes[i] = 0;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Comparable<T>> void printAllOrdered(T[] elements, char delimiter) {
|
||||||
|
|
||||||
|
Arrays.sort(elements);
|
||||||
|
boolean hasNext = true;
|
||||||
|
|
||||||
|
while(hasNext) {
|
||||||
|
printArray(elements, delimiter);
|
||||||
|
int k = 0, l = 0;
|
||||||
|
hasNext = false;
|
||||||
|
for (int i = elements.length - 1; i > 0; i--) {
|
||||||
|
if (elements[i].compareTo(elements[i - 1]) > 0) {
|
||||||
|
k = i - 1;
|
||||||
|
hasNext = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = elements.length - 1; i > k; i--) {
|
||||||
|
if (elements[i].compareTo(elements[k]) > 0) {
|
||||||
|
l = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
swap(elements, k, l);
|
||||||
|
Collections.reverse(Arrays.asList(elements).subList(k + 1, elements.length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void printRandom(T[] elements, char delimiter) {
|
||||||
|
|
||||||
|
Collections.shuffle(Arrays.asList(elements));
|
||||||
|
printArray(elements, delimiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> void swap(T[] elements, int a, int b) {
|
||||||
|
|
||||||
|
T tmp = elements[a];
|
||||||
|
elements[a] = elements[b];
|
||||||
|
elements[b] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> void printArray(T[] elements, char delimiter) {
|
||||||
|
|
||||||
|
String delimiterSpace = delimiter + " ";
|
||||||
|
for(int i = 0; i < elements.length; i++) {
|
||||||
|
System.out.print(elements[i] + delimiterSpace);
|
||||||
|
}
|
||||||
|
System.out.print('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] argv) {
|
||||||
|
|
||||||
|
Integer[] elements = {1,2,3,4};
|
||||||
|
|
||||||
|
System.out.println("Rec:");
|
||||||
|
printAllRecursive(elements, ';');
|
||||||
|
|
||||||
|
System.out.println("Iter:");
|
||||||
|
printAllIterative(elements.length, elements, ';');
|
||||||
|
|
||||||
|
System.out.println("Orderes:");
|
||||||
|
printAllOrdered(elements, ';');
|
||||||
|
|
||||||
|
System.out.println("Random:");
|
||||||
|
printRandom(elements, ';');
|
||||||
|
|
||||||
|
System.out.println("Random:");
|
||||||
|
printRandom(elements, ';');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.baeldung.algorithms.twopointertechnique;
|
||||||
|
|
||||||
|
public class LinkedListFindMiddle {
|
||||||
|
|
||||||
|
public <T> T findMiddle(MyNode<T> head) {
|
||||||
|
MyNode<T> slowPointer = head;
|
||||||
|
MyNode<T> fastPointer = head;
|
||||||
|
|
||||||
|
while (fastPointer.next != null && fastPointer.next.next != null) {
|
||||||
|
fastPointer = fastPointer.next.next;
|
||||||
|
slowPointer = slowPointer.next;
|
||||||
|
}
|
||||||
|
return slowPointer.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.baeldung.algorithms.twopointertechnique;
|
||||||
|
|
||||||
|
public class MyNode<E> {
|
||||||
|
MyNode<E> next;
|
||||||
|
E data;
|
||||||
|
|
||||||
|
public MyNode(E value) {
|
||||||
|
data = value;
|
||||||
|
next = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MyNode(E value, MyNode<E> n) {
|
||||||
|
data = value;
|
||||||
|
next = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNext(MyNode<E> n) {
|
||||||
|
next = n;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.baeldung.algorithms.twopointertechnique;
|
||||||
|
|
||||||
|
public class RotateArray {
|
||||||
|
|
||||||
|
public void rotate(int[] input, int step) {
|
||||||
|
step %= input.length;
|
||||||
|
reverse(input, 0, input.length - 1);
|
||||||
|
reverse(input, 0, step - 1);
|
||||||
|
reverse(input, step, input.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reverse(int[] input, int start, int end) {
|
||||||
|
while (start < end) {
|
||||||
|
int temp = input[start];
|
||||||
|
input[start] = input[end];
|
||||||
|
input[end] = temp;
|
||||||
|
start++;
|
||||||
|
end--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.baeldung.algorithms.twopointertechnique;
|
||||||
|
|
||||||
|
public class TwoSum {
|
||||||
|
|
||||||
|
public boolean twoSum(int[] input, int targetValue) {
|
||||||
|
|
||||||
|
int pointerOne = 0;
|
||||||
|
int pointerTwo = input.length - 1;
|
||||||
|
|
||||||
|
while (pointerOne < pointerTwo) {
|
||||||
|
int sum = input[pointerOne] + input[pointerTwo];
|
||||||
|
|
||||||
|
if (sum == targetValue) {
|
||||||
|
return true;
|
||||||
|
} else if (sum < targetValue) {
|
||||||
|
pointerOne++;
|
||||||
|
} else {
|
||||||
|
pointerTwo--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean twoSumSlow(int[] input, int targetValue) {
|
||||||
|
|
||||||
|
for (int i = 0; i < input.length; i++) {
|
||||||
|
for (int j = 1; j < input.length; j++) {
|
||||||
|
if (input[i] + input[j] == targetValue) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.algorithms.twopointertechnique;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class LinkedListFindMiddleUnitTest {
|
||||||
|
|
||||||
|
LinkedListFindMiddle linkedListFindMiddle = new LinkedListFindMiddle();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLinkedListOfMyNodes_whenLinkedListFindMiddle_thenCorrect() {
|
||||||
|
|
||||||
|
MyNode<String> head = createNodesList(8);
|
||||||
|
|
||||||
|
assertThat(linkedListFindMiddle.findMiddle(head)).isEqualTo("4");
|
||||||
|
|
||||||
|
head = createNodesList(9);
|
||||||
|
|
||||||
|
assertThat(linkedListFindMiddle.findMiddle(head)).isEqualTo("5");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MyNode<String> createNodesList(int n) {
|
||||||
|
|
||||||
|
MyNode<String> head = new MyNode<String>("1");
|
||||||
|
MyNode<String> current = head;
|
||||||
|
|
||||||
|
for (int i = 2; i <= n; i++) {
|
||||||
|
MyNode<String> newNode = new MyNode<String>(String.valueOf(i));
|
||||||
|
current.setNext(newNode);
|
||||||
|
current = newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.baeldung.algorithms.twopointertechnique;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class RotateArrayUnitTest {
|
||||||
|
|
||||||
|
private RotateArray rotateArray = new RotateArray();
|
||||||
|
|
||||||
|
private int[] inputArray;
|
||||||
|
|
||||||
|
private int step;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAnArrayOfIntegers_whenRotateKsteps_thenCorrect() {
|
||||||
|
|
||||||
|
inputArray = new int[] { 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
step = 4;
|
||||||
|
|
||||||
|
rotateArray.rotate(inputArray, step);
|
||||||
|
|
||||||
|
assertThat(inputArray).containsExactly(new int[] { 4, 5, 6, 7, 1, 2, 3 });
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.baeldung.algorithms.twopointertechnique;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class TwoSumUnitTest {
|
||||||
|
|
||||||
|
private TwoSum twoSum = new TwoSum();
|
||||||
|
|
||||||
|
private int[] sortedArray;
|
||||||
|
|
||||||
|
private int targetValue;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenASortedArrayOfIntegers_whenTwoSumSlow_thenPairExists() {
|
||||||
|
|
||||||
|
sortedArray = new int[] { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
|
||||||
|
|
||||||
|
targetValue = 12;
|
||||||
|
|
||||||
|
assertTrue(twoSum.twoSumSlow(sortedArray, targetValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenASortedArrayOfIntegers_whenTwoSumSlow_thenPairDoesNotExists() {
|
||||||
|
|
||||||
|
sortedArray = new int[] { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
|
||||||
|
|
||||||
|
targetValue = 20;
|
||||||
|
|
||||||
|
assertFalse(twoSum.twoSumSlow(sortedArray, targetValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenASortedArrayOfIntegers_whenTwoSum_thenPairExists() {
|
||||||
|
|
||||||
|
sortedArray = new int[] { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
|
||||||
|
|
||||||
|
targetValue = 12;
|
||||||
|
|
||||||
|
assertTrue(twoSum.twoSum(sortedArray, targetValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenASortedArrayOfIntegers_whenTwoSum_thenPairDoesNotExists() {
|
||||||
|
|
||||||
|
sortedArray = new int[] { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
|
||||||
|
|
||||||
|
targetValue = 20;
|
||||||
|
|
||||||
|
assertFalse(twoSum.twoSum(sortedArray, targetValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -15,16 +15,76 @@
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-core_2.10 -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.spark</groupId>
|
<groupId>org.apache.spark</groupId>
|
||||||
<artifactId>spark-core_2.10</artifactId>
|
<artifactId>spark-core_2.11</artifactId>
|
||||||
<version>${org.apache.spark.spark-core.version}</version>
|
<version>${org.apache.spark.spark-core.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.spark</groupId>
|
||||||
|
<artifactId>spark-sql_2.11</artifactId>
|
||||||
|
<version>${org.apache.spark.spark-sql.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.spark</groupId>
|
||||||
|
<artifactId>spark-streaming_2.11</artifactId>
|
||||||
|
<version>${org.apache.spark.spark-streaming.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.spark</groupId>
|
||||||
|
<artifactId>spark-streaming-kafka-0-10_2.11</artifactId>
|
||||||
|
<version>${org.apache.spark.spark-streaming-kafka.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.datastax.spark</groupId>
|
||||||
|
<artifactId>spark-cassandra-connector_2.11</artifactId>
|
||||||
|
<version>${com.datastax.spark.spark-cassandra-connector.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.datastax.spark</groupId>
|
||||||
|
<artifactId>spark-cassandra-connector-java_2.11</artifactId>
|
||||||
|
<version>${com.datastax.spark.spark-cassandra-connector-java.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.2</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
<properties>
|
<properties>
|
||||||
<org.apache.spark.spark-core.version>2.2.0</org.apache.spark.spark-core.version>
|
<org.apache.spark.spark-core.version>2.3.0</org.apache.spark.spark-core.version>
|
||||||
|
<org.apache.spark.spark-sql.version>2.3.0</org.apache.spark.spark-sql.version>
|
||||||
|
<org.apache.spark.spark-streaming.version>2.3.0</org.apache.spark.spark-streaming.version>
|
||||||
|
<org.apache.spark.spark-streaming-kafka.version>2.3.0</org.apache.spark.spark-streaming-kafka.version>
|
||||||
|
<com.datastax.spark.spark-cassandra-connector.version>2.3.0</com.datastax.spark.spark-cassandra-connector.version>
|
||||||
|
<com.datastax.spark.spark-cassandra-connector-java.version>1.5.2</com.datastax.spark.spark-cassandra-connector-java.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.data.pipeline;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class Word implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private String word;
|
||||||
|
private int count;
|
||||||
|
Word(String word, int count) {
|
||||||
|
this.word = word;
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
public String getWord() {
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
public void setWord(String word) {
|
||||||
|
this.word = word;
|
||||||
|
}
|
||||||
|
public int getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
public void setCount(int count) {
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package com.baeldung.data.pipeline;
|
||||||
|
|
||||||
|
import static com.datastax.spark.connector.japi.CassandraJavaUtil.javaFunctions;
|
||||||
|
import static com.datastax.spark.connector.japi.CassandraJavaUtil.mapToRow;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
|
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.apache.spark.SparkConf;
|
||||||
|
import org.apache.spark.api.java.JavaRDD;
|
||||||
|
import org.apache.spark.streaming.Durations;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaInputDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaPairDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaStreamingContext;
|
||||||
|
import org.apache.spark.streaming.kafka010.ConsumerStrategies;
|
||||||
|
import org.apache.spark.streaming.kafka010.KafkaUtils;
|
||||||
|
import org.apache.spark.streaming.kafka010.LocationStrategies;
|
||||||
|
|
||||||
|
import scala.Tuple2;
|
||||||
|
|
||||||
|
public class WordCountingApp {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
Logger.getLogger("org")
|
||||||
|
.setLevel(Level.OFF);
|
||||||
|
Logger.getLogger("akka")
|
||||||
|
.setLevel(Level.OFF);
|
||||||
|
|
||||||
|
Map<String, Object> kafkaParams = new HashMap<>();
|
||||||
|
kafkaParams.put("bootstrap.servers", "localhost:9092");
|
||||||
|
kafkaParams.put("key.deserializer", StringDeserializer.class);
|
||||||
|
kafkaParams.put("value.deserializer", StringDeserializer.class);
|
||||||
|
kafkaParams.put("group.id", "use_a_separate_group_id_for_each_stream");
|
||||||
|
kafkaParams.put("auto.offset.reset", "latest");
|
||||||
|
kafkaParams.put("enable.auto.commit", false);
|
||||||
|
|
||||||
|
Collection<String> topics = Arrays.asList("messages");
|
||||||
|
|
||||||
|
SparkConf sparkConf = new SparkConf();
|
||||||
|
sparkConf.setMaster("local[2]");
|
||||||
|
sparkConf.setAppName("WordCountingApp");
|
||||||
|
sparkConf.set("spark.cassandra.connection.host", "127.0.0.1");
|
||||||
|
|
||||||
|
JavaStreamingContext streamingContext = new JavaStreamingContext(sparkConf, Durations.seconds(1));
|
||||||
|
|
||||||
|
JavaInputDStream<ConsumerRecord<String, String>> messages = KafkaUtils.createDirectStream(streamingContext, LocationStrategies.PreferConsistent(), ConsumerStrategies.<String, String> Subscribe(topics, kafkaParams));
|
||||||
|
|
||||||
|
JavaPairDStream<String, String> results = messages.mapToPair(record -> new Tuple2<>(record.key(), record.value()));
|
||||||
|
|
||||||
|
JavaDStream<String> lines = results.map(tuple2 -> tuple2._2());
|
||||||
|
|
||||||
|
JavaDStream<String> words = lines.flatMap(x -> Arrays.asList(x.split("\\s+"))
|
||||||
|
.iterator());
|
||||||
|
|
||||||
|
JavaPairDStream<String, Integer> wordCounts = words.mapToPair(s -> new Tuple2<>(s, 1))
|
||||||
|
.reduceByKey((i1, i2) -> i1 + i2);
|
||||||
|
|
||||||
|
wordCounts.foreachRDD(javaRdd -> {
|
||||||
|
Map<String, Integer> wordCountMap = javaRdd.collectAsMap();
|
||||||
|
for (String key : wordCountMap.keySet()) {
|
||||||
|
List<Word> wordList = Arrays.asList(new Word(key, wordCountMap.get(key)));
|
||||||
|
JavaRDD<Word> rdd = streamingContext.sparkContext()
|
||||||
|
.parallelize(wordList);
|
||||||
|
javaFunctions(rdd).writerBuilder("vocabulary", "words", mapToRow(Word.class))
|
||||||
|
.saveToCassandra();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
streamingContext.start();
|
||||||
|
streamingContext.awaitTermination();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package com.baeldung.data.pipeline;
|
||||||
|
|
||||||
|
import static com.datastax.spark.connector.japi.CassandraJavaUtil.javaFunctions;
|
||||||
|
import static com.datastax.spark.connector.japi.CassandraJavaUtil.mapToRow;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
|
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.apache.spark.SparkConf;
|
||||||
|
import org.apache.spark.api.java.JavaRDD;
|
||||||
|
import org.apache.spark.api.java.JavaSparkContext;
|
||||||
|
import org.apache.spark.api.java.function.Function2;
|
||||||
|
import org.apache.spark.streaming.Durations;
|
||||||
|
import org.apache.spark.streaming.StateSpec;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaInputDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaMapWithStateDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaPairDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaStreamingContext;
|
||||||
|
import org.apache.spark.streaming.kafka010.ConsumerStrategies;
|
||||||
|
import org.apache.spark.streaming.kafka010.KafkaUtils;
|
||||||
|
import org.apache.spark.streaming.kafka010.LocationStrategies;
|
||||||
|
|
||||||
|
import scala.Tuple2;
|
||||||
|
|
||||||
|
public class WordCountingAppWithCheckpoint {
|
||||||
|
|
||||||
|
public static JavaSparkContext sparkContext;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
|
||||||
|
Logger.getLogger("org")
|
||||||
|
.setLevel(Level.OFF);
|
||||||
|
Logger.getLogger("akka")
|
||||||
|
.setLevel(Level.OFF);
|
||||||
|
|
||||||
|
Map<String, Object> kafkaParams = new HashMap<>();
|
||||||
|
kafkaParams.put("bootstrap.servers", "localhost:9092");
|
||||||
|
kafkaParams.put("key.deserializer", StringDeserializer.class);
|
||||||
|
kafkaParams.put("value.deserializer", StringDeserializer.class);
|
||||||
|
kafkaParams.put("group.id", "use_a_separate_group_id_for_each_stream");
|
||||||
|
kafkaParams.put("auto.offset.reset", "latest");
|
||||||
|
kafkaParams.put("enable.auto.commit", false);
|
||||||
|
|
||||||
|
Collection<String> topics = Arrays.asList("messages");
|
||||||
|
|
||||||
|
SparkConf sparkConf = new SparkConf();
|
||||||
|
sparkConf.setMaster("local[2]");
|
||||||
|
sparkConf.setAppName("WordCountingAppWithCheckpoint");
|
||||||
|
sparkConf.set("spark.cassandra.connection.host", "127.0.0.1");
|
||||||
|
|
||||||
|
JavaStreamingContext streamingContext = new JavaStreamingContext(sparkConf, Durations.seconds(1));
|
||||||
|
|
||||||
|
sparkContext = streamingContext.sparkContext();
|
||||||
|
|
||||||
|
streamingContext.checkpoint("./.checkpoint");
|
||||||
|
|
||||||
|
JavaInputDStream<ConsumerRecord<String, String>> messages = KafkaUtils.createDirectStream(streamingContext, LocationStrategies.PreferConsistent(), ConsumerStrategies.<String, String> Subscribe(topics, kafkaParams));
|
||||||
|
|
||||||
|
JavaPairDStream<String, String> results = messages.mapToPair(record -> new Tuple2<>(record.key(), record.value()));
|
||||||
|
|
||||||
|
JavaDStream<String> lines = results.map(tuple2 -> tuple2._2());
|
||||||
|
|
||||||
|
JavaDStream<String> words = lines.flatMap(x -> Arrays.asList(x.split("\\s+"))
|
||||||
|
.iterator());
|
||||||
|
|
||||||
|
JavaPairDStream<String, Integer> wordCounts = words.mapToPair(s -> new Tuple2<>(s, 1))
|
||||||
|
.reduceByKey((Function2<Integer, Integer, Integer>) (i1, i2) -> i1 + i2);
|
||||||
|
|
||||||
|
JavaMapWithStateDStream<String, Integer, Integer, Tuple2<String, Integer>> cumulativeWordCounts = wordCounts.mapWithState(StateSpec.function((word, one, state) -> {
|
||||||
|
int sum = one.orElse(0) + (state.exists() ? state.get() : 0);
|
||||||
|
Tuple2<String, Integer> output = new Tuple2<>(word, sum);
|
||||||
|
state.update(sum);
|
||||||
|
return output;
|
||||||
|
}));
|
||||||
|
|
||||||
|
cumulativeWordCounts.foreachRDD(javaRdd -> {
|
||||||
|
List<Tuple2<String, Integer>> wordCountList = javaRdd.collect();
|
||||||
|
for (Tuple2<String, Integer> tuple : wordCountList) {
|
||||||
|
List<Word> wordList = Arrays.asList(new Word(tuple._1, tuple._2));
|
||||||
|
JavaRDD<Word> rdd = sparkContext.parallelize(wordList);
|
||||||
|
javaFunctions(rdd).writerBuilder("vocabulary", "words", mapToRow(Word.class))
|
||||||
|
.saveToCassandra();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
streamingContext.start();
|
||||||
|
streamingContext.awaitTermination();
|
||||||
|
}
|
||||||
|
}
|
46
axon/pom.xml
46
axon/pom.xml
|
@ -4,29 +4,61 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>axon</artifactId>
|
<artifactId>axon</artifactId>
|
||||||
<name>axon</name>
|
<name>axon</name>
|
||||||
|
<description>Basic Axon Framework with Spring Boot configuration tutorial</description>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent-modules</artifactId>
|
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<artifactId>parent-boot-2</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-boot-2</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.axonframework</groupId>
|
||||||
|
<artifactId>axon-spring-boot-starter</artifactId>
|
||||||
|
<version>${axon.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.axonframework</groupId>
|
||||||
|
<artifactId>axon-server-connector</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.axonframework</groupId>
|
<groupId>org.axonframework</groupId>
|
||||||
<artifactId>axon-test</artifactId>
|
<artifactId>axon-test</artifactId>
|
||||||
<version>${axon.version}</version>
|
<version>${axon.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.axonframework</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>axon-core</artifactId>
|
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||||
<version>${axon.version}</version>
|
<version>2.1.1.RELEASE</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<axon.version>3.0.2</axon.version>
|
<axon.version>4.0.3</axon.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -1,54 +0,0 @@
|
||||||
package com.baeldung.axon;
|
|
||||||
|
|
||||||
import com.baeldung.axon.aggregates.MessagesAggregate;
|
|
||||||
import com.baeldung.axon.commands.CreateMessageCommand;
|
|
||||||
import com.baeldung.axon.commands.MarkReadMessageCommand;
|
|
||||||
import com.baeldung.axon.eventhandlers.MessagesEventHandler;
|
|
||||||
import org.axonframework.commandhandling.AggregateAnnotationCommandHandler;
|
|
||||||
import org.axonframework.commandhandling.CommandBus;
|
|
||||||
import org.axonframework.commandhandling.SimpleCommandBus;
|
|
||||||
import org.axonframework.commandhandling.gateway.CommandGateway;
|
|
||||||
import org.axonframework.commandhandling.gateway.DefaultCommandGateway;
|
|
||||||
import org.axonframework.eventhandling.AnnotationEventListenerAdapter;
|
|
||||||
import org.axonframework.eventsourcing.EventSourcingRepository;
|
|
||||||
import org.axonframework.eventsourcing.eventstore.EmbeddedEventStore;
|
|
||||||
import org.axonframework.eventsourcing.eventstore.EventStore;
|
|
||||||
import org.axonframework.eventsourcing.eventstore.inmemory.InMemoryEventStorageEngine;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class MessagesRunner {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
CommandBus commandBus = new SimpleCommandBus();
|
|
||||||
|
|
||||||
CommandGateway commandGateway = new DefaultCommandGateway(commandBus);
|
|
||||||
|
|
||||||
EventStore eventStore = new EmbeddedEventStore(new InMemoryEventStorageEngine());
|
|
||||||
|
|
||||||
EventSourcingRepository<MessagesAggregate> repository =
|
|
||||||
new EventSourcingRepository<>(MessagesAggregate.class, eventStore);
|
|
||||||
|
|
||||||
|
|
||||||
AggregateAnnotationCommandHandler<MessagesAggregate> messagesAggregateAggregateAnnotationCommandHandler =
|
|
||||||
new AggregateAnnotationCommandHandler<MessagesAggregate>(MessagesAggregate.class, repository);
|
|
||||||
messagesAggregateAggregateAnnotationCommandHandler.subscribe(commandBus);
|
|
||||||
|
|
||||||
final AnnotationEventListenerAdapter annotationEventListenerAdapter =
|
|
||||||
new AnnotationEventListenerAdapter(new MessagesEventHandler());
|
|
||||||
eventStore.subscribe(eventMessages -> eventMessages.forEach(e -> {
|
|
||||||
try {
|
|
||||||
annotationEventListenerAdapter.handle(e);
|
|
||||||
} catch (Exception e1) {
|
|
||||||
throw new RuntimeException(e1);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
));
|
|
||||||
|
|
||||||
final String itemId = UUID.randomUUID().toString();
|
|
||||||
commandGateway.send(new CreateMessageCommand(itemId, "Hello, how is your day? :-)"));
|
|
||||||
commandGateway.send(new MarkReadMessageCommand(itemId));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.axon;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class OrderApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(OrderApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,36 +0,0 @@
|
||||||
package com.baeldung.axon.aggregates;
|
|
||||||
|
|
||||||
import com.baeldung.axon.commands.CreateMessageCommand;
|
|
||||||
import com.baeldung.axon.commands.MarkReadMessageCommand;
|
|
||||||
import com.baeldung.axon.events.MessageCreatedEvent;
|
|
||||||
import com.baeldung.axon.events.MessageReadEvent;
|
|
||||||
import org.axonframework.commandhandling.CommandHandler;
|
|
||||||
import org.axonframework.commandhandling.model.AggregateIdentifier;
|
|
||||||
import org.axonframework.eventhandling.EventHandler;
|
|
||||||
|
|
||||||
import static org.axonframework.commandhandling.model.AggregateLifecycle.apply;
|
|
||||||
|
|
||||||
|
|
||||||
public class MessagesAggregate {
|
|
||||||
|
|
||||||
@AggregateIdentifier
|
|
||||||
private String id;
|
|
||||||
|
|
||||||
public MessagesAggregate() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@CommandHandler
|
|
||||||
public MessagesAggregate(CreateMessageCommand command) {
|
|
||||||
apply(new MessageCreatedEvent(command.getId(), command.getText()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void on(MessageCreatedEvent event) {
|
|
||||||
this.id = event.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@CommandHandler
|
|
||||||
public void markRead(MarkReadMessageCommand command) {
|
|
||||||
apply(new MessageReadEvent(id));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.baeldung.axon.commandmodel;
|
||||||
|
|
||||||
|
import static org.axonframework.modelling.command.AggregateLifecycle.apply;
|
||||||
|
|
||||||
|
import org.axonframework.commandhandling.CommandHandler;
|
||||||
|
import org.axonframework.eventsourcing.EventSourcingHandler;
|
||||||
|
import org.axonframework.modelling.command.AggregateIdentifier;
|
||||||
|
import org.axonframework.spring.stereotype.Aggregate;
|
||||||
|
|
||||||
|
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.commands.PlaceOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderPlacedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
|
||||||
|
|
||||||
|
@Aggregate
|
||||||
|
public class OrderAggregate {
|
||||||
|
|
||||||
|
@AggregateIdentifier
|
||||||
|
private String orderId;
|
||||||
|
private boolean orderConfirmed;
|
||||||
|
|
||||||
|
@CommandHandler
|
||||||
|
public OrderAggregate(PlaceOrderCommand command) {
|
||||||
|
apply(new OrderPlacedEvent(command.getOrderId(), command.getProduct()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@CommandHandler
|
||||||
|
public void handle(ConfirmOrderCommand command) {
|
||||||
|
apply(new OrderConfirmedEvent(orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@CommandHandler
|
||||||
|
public void handle(ShipOrderCommand command) {
|
||||||
|
if (!orderConfirmed) {
|
||||||
|
throw new IllegalStateException("Cannot ship an order which has not been confirmed yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(new OrderShippedEvent(orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventSourcingHandler
|
||||||
|
public void on(OrderPlacedEvent event) {
|
||||||
|
this.orderId = event.getOrderId();
|
||||||
|
orderConfirmed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventSourcingHandler
|
||||||
|
public void on(OrderConfirmedEvent event) {
|
||||||
|
orderConfirmed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected OrderAggregate() {
|
||||||
|
// Required by Axon to build a default Aggregate prior to Event Sourcing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,24 +0,0 @@
|
||||||
package com.baeldung.axon.commands;
|
|
||||||
|
|
||||||
|
|
||||||
import org.axonframework.commandhandling.TargetAggregateIdentifier;
|
|
||||||
|
|
||||||
public class CreateMessageCommand {
|
|
||||||
|
|
||||||
@TargetAggregateIdentifier
|
|
||||||
private final String id;
|
|
||||||
private final String text;
|
|
||||||
|
|
||||||
public CreateMessageCommand(String id, String text) {
|
|
||||||
this.id = id;
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package com.baeldung.axon.commands;
|
|
||||||
|
|
||||||
|
|
||||||
import org.axonframework.commandhandling.TargetAggregateIdentifier;
|
|
||||||
|
|
||||||
public class MarkReadMessageCommand {
|
|
||||||
|
|
||||||
@TargetAggregateIdentifier
|
|
||||||
private final String id;
|
|
||||||
|
|
||||||
public MarkReadMessageCommand(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.baeldung.axon.coreapi.commands;
|
||||||
|
|
||||||
|
import org.axonframework.modelling.command.TargetAggregateIdentifier;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class ConfirmOrderCommand {
|
||||||
|
|
||||||
|
@TargetAggregateIdentifier
|
||||||
|
private final String orderId;
|
||||||
|
|
||||||
|
public ConfirmOrderCommand(String orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final ConfirmOrderCommand other = (ConfirmOrderCommand) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ConfirmOrderCommand{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.baeldung.axon.coreapi.commands;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.axonframework.modelling.command.TargetAggregateIdentifier;
|
||||||
|
|
||||||
|
public class PlaceOrderCommand {
|
||||||
|
|
||||||
|
@TargetAggregateIdentifier
|
||||||
|
private final String orderId;
|
||||||
|
private final String product;
|
||||||
|
|
||||||
|
public PlaceOrderCommand(String orderId, String product) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
this.product = product;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProduct() {
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId, product);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final PlaceOrderCommand other = (PlaceOrderCommand) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId)
|
||||||
|
&& Objects.equals(this.product, other.product);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PlaceOrderCommand{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
", product='" + product + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.baeldung.axon.coreapi.commands;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.axonframework.modelling.command.TargetAggregateIdentifier;
|
||||||
|
|
||||||
|
public class ShipOrderCommand {
|
||||||
|
|
||||||
|
@TargetAggregateIdentifier
|
||||||
|
private final String orderId;
|
||||||
|
|
||||||
|
public ShipOrderCommand(String orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final ShipOrderCommand other = (ShipOrderCommand) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ShipOrderCommand{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.axon.coreapi.events;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class OrderConfirmedEvent {
|
||||||
|
|
||||||
|
private final String orderId;
|
||||||
|
|
||||||
|
public OrderConfirmedEvent(String orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final OrderConfirmedEvent other = (OrderConfirmedEvent) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OrderConfirmedEvent{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.baeldung.axon.coreapi.events;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class OrderPlacedEvent {
|
||||||
|
|
||||||
|
private final String orderId;
|
||||||
|
private final String product;
|
||||||
|
|
||||||
|
public OrderPlacedEvent(String orderId, String product) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
this.product = product;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProduct() {
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId, product);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final OrderPlacedEvent other = (OrderPlacedEvent) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId)
|
||||||
|
&& Objects.equals(this.product, other.product);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OrderPlacedEvent{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
", product='" + product + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.axon.coreapi.events;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class OrderShippedEvent {
|
||||||
|
|
||||||
|
private final String orderId;
|
||||||
|
|
||||||
|
public OrderShippedEvent(String orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final OrderShippedEvent other = (OrderShippedEvent) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OrderShippedEvent{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.axon.coreapi.queries;
|
||||||
|
|
||||||
|
public class FindAllOrderedProductsQuery {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.baeldung.axon.coreapi.queries;
|
||||||
|
|
||||||
|
public enum OrderStatus {
|
||||||
|
|
||||||
|
PLACED, CONFIRMED, SHIPPED
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.baeldung.axon.coreapi.queries;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class OrderedProduct {
|
||||||
|
|
||||||
|
private final String orderId;
|
||||||
|
private final String product;
|
||||||
|
private OrderStatus orderStatus;
|
||||||
|
|
||||||
|
public OrderedProduct(String orderId, String product) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
this.product = product;
|
||||||
|
orderStatus = OrderStatus.PLACED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProduct() {
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrderStatus getOrderStatus() {
|
||||||
|
return orderStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderConfirmed() {
|
||||||
|
this.orderStatus = OrderStatus.CONFIRMED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderShipped() {
|
||||||
|
this.orderStatus = OrderStatus.SHIPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId, product, orderStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final OrderedProduct other = (OrderedProduct) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId)
|
||||||
|
&& Objects.equals(this.product, other.product)
|
||||||
|
&& Objects.equals(this.orderStatus, other.orderStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OrderedProduct{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
", product='" + product + '\'' +
|
||||||
|
", orderStatus=" + orderStatus +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +0,0 @@
|
||||||
package com.baeldung.axon.eventhandlers;
|
|
||||||
|
|
||||||
import com.baeldung.axon.events.MessageReadEvent;
|
|
||||||
import com.baeldung.axon.events.MessageCreatedEvent;
|
|
||||||
import org.axonframework.eventhandling.EventHandler;
|
|
||||||
|
|
||||||
|
|
||||||
public class MessagesEventHandler {
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void handle(MessageCreatedEvent event) {
|
|
||||||
System.out.println("Message received: " + event.getText() + " (" + event.getId() + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void handle(MessageReadEvent event) {
|
|
||||||
System.out.println("Message read: " + event.getId());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package com.baeldung.axon.events;
|
|
||||||
|
|
||||||
public class MessageCreatedEvent {
|
|
||||||
|
|
||||||
private final String id;
|
|
||||||
private final String text;
|
|
||||||
|
|
||||||
public MessageCreatedEvent(String id, String text) {
|
|
||||||
this.id = id;
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package com.baeldung.axon.events;
|
|
||||||
|
|
||||||
public class MessageReadEvent {
|
|
||||||
|
|
||||||
private final String id;
|
|
||||||
|
|
||||||
public MessageReadEvent(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.axon.gui;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.axonframework.commandhandling.gateway.CommandGateway;
|
||||||
|
import org.axonframework.messaging.responsetypes.ResponseTypes;
|
||||||
|
import org.axonframework.queryhandling.QueryGateway;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.commands.PlaceOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery;
|
||||||
|
import com.baeldung.axon.coreapi.queries.OrderedProduct;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class OrderRestEndpoint {
|
||||||
|
|
||||||
|
private final CommandGateway commandGateway;
|
||||||
|
private final QueryGateway queryGateway;
|
||||||
|
|
||||||
|
public OrderRestEndpoint(CommandGateway commandGateway, QueryGateway queryGateway) {
|
||||||
|
this.commandGateway = commandGateway;
|
||||||
|
this.queryGateway = queryGateway;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/ship-order")
|
||||||
|
public void shipOrder() {
|
||||||
|
String orderId = UUID.randomUUID().toString();
|
||||||
|
commandGateway.send(new PlaceOrderCommand(orderId, "Deluxe Chair"));
|
||||||
|
commandGateway.send(new ConfirmOrderCommand(orderId));
|
||||||
|
commandGateway.send(new ShipOrderCommand(orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/ship-unconfirmed-order")
|
||||||
|
public void shipUnconfirmedOrder() {
|
||||||
|
String orderId = UUID.randomUUID().toString();
|
||||||
|
commandGateway.send(new PlaceOrderCommand(orderId, "Deluxe Chair"));
|
||||||
|
// This throws an exception, as an Order cannot be shipped if it has not been confirmed yet.
|
||||||
|
commandGateway.send(new ShipOrderCommand(orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/all-orders")
|
||||||
|
public List<OrderedProduct> findAllOrderedProducts() {
|
||||||
|
return queryGateway.query(new FindAllOrderedProductsQuery(), ResponseTypes.multipleInstancesOf(OrderedProduct.class))
|
||||||
|
.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.baeldung.axon.querymodel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.axonframework.eventhandling.EventHandler;
|
||||||
|
import org.axonframework.queryhandling.QueryHandler;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderPlacedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery;
|
||||||
|
import com.baeldung.axon.coreapi.queries.OrderedProduct;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class OrderedProductsEventHandler {
|
||||||
|
|
||||||
|
private final Map<String, OrderedProduct> orderedProducts = new HashMap<>();
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void on(OrderPlacedEvent event) {
|
||||||
|
String orderId = event.getOrderId();
|
||||||
|
orderedProducts.put(orderId, new OrderedProduct(orderId, event.getProduct()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void on(OrderConfirmedEvent event) {
|
||||||
|
orderedProducts.computeIfPresent(event.getOrderId(), (orderId, orderedProduct) -> {
|
||||||
|
orderedProduct.setOrderConfirmed();
|
||||||
|
return orderedProduct;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void on(OrderShippedEvent event) {
|
||||||
|
orderedProducts.computeIfPresent(event.getOrderId(), (orderId, orderedProduct) -> {
|
||||||
|
orderedProduct.setOrderShipped();
|
||||||
|
return orderedProduct;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@QueryHandler
|
||||||
|
public List<OrderedProduct> handle(FindAllOrderedProductsQuery query) {
|
||||||
|
return new ArrayList<>(orderedProducts.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
POST http://localhost:8080/ship-order
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
POST http://localhost:8080/ship-unconfirmed-order
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
GET http://localhost:8080/all-orders
|
||||||
|
|
||||||
|
###
|
|
@ -1,42 +0,0 @@
|
||||||
package com.baeldung.axon;
|
|
||||||
|
|
||||||
import com.baeldung.axon.aggregates.MessagesAggregate;
|
|
||||||
import com.baeldung.axon.commands.CreateMessageCommand;
|
|
||||||
import com.baeldung.axon.commands.MarkReadMessageCommand;
|
|
||||||
import com.baeldung.axon.events.MessageCreatedEvent;
|
|
||||||
import com.baeldung.axon.events.MessageReadEvent;
|
|
||||||
import org.axonframework.test.aggregate.AggregateTestFixture;
|
|
||||||
import org.axonframework.test.aggregate.FixtureConfiguration;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class MessagesAggregateIntegrationTest {
|
|
||||||
|
|
||||||
private FixtureConfiguration<MessagesAggregate> fixture;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
fixture = new AggregateTestFixture<MessagesAggregate>(MessagesAggregate.class);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void giveAggregateRoot_whenCreateMessageCommand_thenShouldProduceMessageCreatedEvent() throws Exception {
|
|
||||||
String eventText = "Hello, how is your day?";
|
|
||||||
String id = UUID.randomUUID().toString();
|
|
||||||
fixture.given()
|
|
||||||
.when(new CreateMessageCommand(id, eventText))
|
|
||||||
.expectEvents(new MessageCreatedEvent(id, eventText));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenMessageCreatedEvent_whenReadMessageCommand_thenShouldProduceMessageReadEvent() throws Exception {
|
|
||||||
String id = UUID.randomUUID().toString();
|
|
||||||
|
|
||||||
fixture.given(new MessageCreatedEvent(id, "Hello :-)"))
|
|
||||||
.when(new MarkReadMessageCommand(id))
|
|
||||||
.expectEvents(new MessageReadEvent(id));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.baeldung.axon.commandmodel;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.axonframework.test.aggregate.AggregateTestFixture;
|
||||||
|
import org.axonframework.test.aggregate.FixtureConfiguration;
|
||||||
|
import org.junit.*;
|
||||||
|
|
||||||
|
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.commands.PlaceOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderPlacedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
|
||||||
|
|
||||||
|
public class OrderAggregateUnitTest {
|
||||||
|
|
||||||
|
private FixtureConfiguration<OrderAggregate> fixture;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
fixture = new AggregateTestFixture<>(OrderAggregate.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void giveNoPriorActivity_whenPlaceOrderCommand_thenShouldPublishOrderPlacedEvent() {
|
||||||
|
String orderId = UUID.randomUUID().toString();
|
||||||
|
String product = "Deluxe Chair";
|
||||||
|
fixture.givenNoPriorActivity()
|
||||||
|
.when(new PlaceOrderCommand(orderId, product))
|
||||||
|
.expectEvents(new OrderPlacedEvent(orderId, product));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOrderPlacedEvent_whenConfirmOrderCommand_thenShouldPublishOrderConfirmedEvent() {
|
||||||
|
String orderId = UUID.randomUUID().toString();
|
||||||
|
String product = "Deluxe Chair";
|
||||||
|
fixture.given(new OrderPlacedEvent(orderId, product))
|
||||||
|
.when(new ConfirmOrderCommand(orderId))
|
||||||
|
.expectEvents(new OrderConfirmedEvent(orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOrderPlacedEvent_whenShipOrderCommand_thenShouldThrowIllegalStateException() {
|
||||||
|
String orderId = UUID.randomUUID().toString();
|
||||||
|
String product = "Deluxe Chair";
|
||||||
|
fixture.given(new OrderPlacedEvent(orderId, product))
|
||||||
|
.when(new ShipOrderCommand(orderId))
|
||||||
|
.expectException(IllegalStateException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOrderPlacedEventAndOrderConfirmedEvent_whenShipOrderCommand_thenShouldPublishOrderShippedEvent() {
|
||||||
|
String orderId = UUID.randomUUID().toString();
|
||||||
|
String product = "Deluxe Chair";
|
||||||
|
fixture.given(new OrderPlacedEvent(orderId, product), new OrderConfirmedEvent(orderId))
|
||||||
|
.when(new ShipOrderCommand(orderId))
|
||||||
|
.expectEvents(new OrderShippedEvent(orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
- [Java 11 Single File Source Code](https://www.baeldung.com/java-single-file-source-code)
|
- [Java 11 Single File Source Code](https://www.baeldung.com/java-single-file-source-code)
|
||||||
- [Java 11 Local Variable Syntax for Lambda Parameters](https://www.baeldung.com/java-var-lambda-params)
|
- [Java 11 Local Variable Syntax for Lambda Parameters](https://www.baeldung.com/java-var-lambda-params)
|
||||||
|
- [Java 11 String API Additions](https://www.baeldung.com/java-11-string-api)
|
||||||
|
|
|
@ -33,3 +33,8 @@
|
||||||
- [Java Primitives versus Objects](https://www.baeldung.com/java-primitives-vs-objects)
|
- [Java Primitives versus Objects](https://www.baeldung.com/java-primitives-vs-objects)
|
||||||
- [How to Use if/else Logic in Java 8 Streams](https://www.baeldung.com/java-8-streams-if-else-logic)
|
- [How to Use if/else Logic in Java 8 Streams](https://www.baeldung.com/java-8-streams-if-else-logic)
|
||||||
- [How to Replace Many if Statements in Java](https://www.baeldung.com/java-replace-if-statements)
|
- [How to Replace Many if Statements in Java](https://www.baeldung.com/java-replace-if-statements)
|
||||||
|
- [Java @Override Annotation](https://www.baeldung.com/java-override)
|
||||||
|
- [Java @SuppressWarnings Annotation](https://www.baeldung.com/java-suppresswarnings)
|
||||||
|
- [Java @SafeVarargs Annotation](https://www.baeldung.com/java-safevarargs)
|
||||||
|
- [Java @Deprecated Annotation](https://www.baeldung.com/java-deprecated)
|
||||||
|
- [Java 8 Predicate Chain](https://www.baeldung.com/java-predicate-chain)
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
package com.baeldung.interfaces;
|
|
||||||
|
|
||||||
public interface Electronic {
|
|
||||||
//Constant variable
|
|
||||||
public static final String LED = "LED";
|
|
||||||
|
|
||||||
//Abstract method
|
|
||||||
public int getElectricityUse();
|
|
||||||
|
|
||||||
// Static method
|
|
||||||
public static boolean isEnergyEfficient(String electtronicType) {
|
|
||||||
if (electtronicType.equals(LED)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Default method
|
|
||||||
public default void printDescription() {
|
|
||||||
System.out.println("Electronic Description");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
package com.baeldung.interfaces;
|
|
||||||
|
|
||||||
import com.baeldung.interfaces.multiinheritance.Transform;
|
|
||||||
|
|
||||||
public class Motorcycle implements Transform {
|
|
||||||
@Override
|
|
||||||
public void transform() {
|
|
||||||
// Implementation
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package com.baeldung.interfaces;
|
|
||||||
|
|
||||||
public class Truck extends Vehicle {
|
|
||||||
@Override
|
|
||||||
public void transform() {
|
|
||||||
// implementation
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
package com.baeldung.interfaces;
|
|
||||||
|
|
||||||
import com.baeldung.interfaces.multiinheritance.Transform;
|
|
||||||
|
|
||||||
public abstract class Vehicle implements Transform {
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
package com.baeldung.interfaces.multiinheritance;
|
|
||||||
|
|
||||||
public class Vehicle implements Fly, Transform {
|
|
||||||
@Override
|
|
||||||
public void fly() {
|
|
||||||
System.out.println("I can Fly!!");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void transform() {
|
|
||||||
System.out.println("I can Transform!!");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package com.baeldung.interfaces.polymorphysim;
|
|
||||||
|
|
||||||
public class Circle implements Shape {
|
|
||||||
|
|
||||||
private double radius;
|
|
||||||
|
|
||||||
public Circle(double radius){
|
|
||||||
this.radius = radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String name() {
|
|
||||||
return "Circle";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double area() {
|
|
||||||
return Math.PI * (radius * radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getColor() {
|
|
||||||
return "green";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package com.baeldung.interfaces.polymorphysim;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class DisplayShape {
|
|
||||||
|
|
||||||
private ArrayList<Shape> shapes;
|
|
||||||
|
|
||||||
public ArrayList<Shape> getShapes() {
|
|
||||||
return shapes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DisplayShape() {
|
|
||||||
shapes = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(Shape shape) {
|
|
||||||
shapes.add(shape);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void display() {
|
|
||||||
for (Shape shape : shapes) {
|
|
||||||
System.out.println(shape.name() + " area: " + shape.area());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package com.baeldung.interfaces.polymorphysim;
|
|
||||||
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
public class FunctionalMain {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
Shape circleShape = new Circle(2);
|
|
||||||
Shape squareShape = new Square(2);
|
|
||||||
|
|
||||||
DisplayShape DisplayShape = new DisplayShape();
|
|
||||||
DisplayShape.add(circleShape);
|
|
||||||
DisplayShape.add(squareShape);
|
|
||||||
|
|
||||||
Predicate<Shape> checkArea = (shape) -> shape.area() < 5;
|
|
||||||
|
|
||||||
for (Shape shape : DisplayShape.getShapes()) {
|
|
||||||
if (checkArea.test(shape)) {
|
|
||||||
System.out.println(shape.name() + " " + shape.area());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package com.baeldung.interfaces.polymorphysim;
|
|
||||||
|
|
||||||
public class MainPolymorphic {
|
|
||||||
public static void main(String[] args){
|
|
||||||
|
|
||||||
Shape circleShape = new Circle(2);
|
|
||||||
Shape squareShape = new Square(2);
|
|
||||||
|
|
||||||
DisplayShape displayShape = new DisplayShape();
|
|
||||||
displayShape.add(circleShape);
|
|
||||||
displayShape.add(squareShape);
|
|
||||||
|
|
||||||
displayShape.display();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package com.baeldung.interfaces.polymorphysim;
|
|
||||||
|
|
||||||
import com.baeldung.interfaces.HasColor;
|
|
||||||
|
|
||||||
public interface Shape extends HasColor {
|
|
||||||
|
|
||||||
public abstract String name();
|
|
||||||
public abstract double area();
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package com.baeldung.interfaces.polymorphysim;
|
|
||||||
|
|
||||||
public class Square implements Shape {
|
|
||||||
|
|
||||||
private double width;
|
|
||||||
|
|
||||||
public Square(double width) {
|
|
||||||
this.width = width;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String name() {
|
|
||||||
return "Square";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double area() {
|
|
||||||
return width * width;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getColor() {
|
|
||||||
return "red";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package com.baeldung.interfaces;
|
|
||||||
|
|
||||||
import com.baeldung.interfaces.polymorphysim.Circle;
|
|
||||||
import com.baeldung.interfaces.polymorphysim.Shape;
|
|
||||||
import com.baeldung.interfaces.polymorphysim.Square;
|
|
||||||
import org.assertj.core.api.Assertions;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class PolymorphysimUnitTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenInterfacePointsToCircle_CircleAreaMethodisBeingCalled(){
|
|
||||||
double expectedArea = 12.566370614359172;
|
|
||||||
Shape circle = new Circle(2);
|
|
||||||
double actualArea = circle.area();
|
|
||||||
Assertions.assertThat(actualArea).isEqualTo(expectedArea);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenInterfacePointsToSquare_SquareAreaMethodisBeingCalled(){
|
|
||||||
double expectedArea = 4;
|
|
||||||
Shape square = new Square(2);
|
|
||||||
double actualArea = square.area();
|
|
||||||
Assertions.assertThat(actualArea).isEqualTo(expectedArea);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.baeldung.java9.set;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class UnmodifiableSet {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
Set<String> set = new HashSet<>();
|
||||||
|
set.add("Canada");
|
||||||
|
set.add("USA");
|
||||||
|
|
||||||
|
coreJDK(set);
|
||||||
|
guavaOf();
|
||||||
|
copyOf(set);
|
||||||
|
java9Of();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void java9Of() {
|
||||||
|
Set<String> immutable = Set.of("Canada", "USA");
|
||||||
|
System.out.println(immutable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void guavaOf() {
|
||||||
|
Set<String> immutable = ImmutableSet.of("Canada", "USA");
|
||||||
|
System.out.println(immutable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void copyOf(Set<String> set) {
|
||||||
|
Set<String> immutable = ImmutableSet.copyOf(set);
|
||||||
|
set.add("Costa Rica");
|
||||||
|
System.out.println(immutable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void coreJDK(Set<String> set) {
|
||||||
|
Set<String> unmodifiableSet = Collections.unmodifiableSet(set);
|
||||||
|
set.add("Costa Rica");
|
||||||
|
System.out.println(unmodifiableSet);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package com.baeldung.java9;
|
package com.baeldung.java9;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -23,4 +25,14 @@ public class SetExamplesUnitTest {
|
||||||
Set<Integer> intSet = Set.of(intArray);
|
Set<Integer> intSet = Set.of(intArray);
|
||||||
assertEquals(intSet.size(), intArray.length);
|
assertEquals(intSet.size(), intArray.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
|
public void testUnmodifiableSet() {
|
||||||
|
Set<String> set = new HashSet<>();
|
||||||
|
set.add("Canada");
|
||||||
|
set.add("USA");
|
||||||
|
|
||||||
|
Set<String> unmodifiableSet = Collections.unmodifiableSet(set);
|
||||||
|
unmodifiableSet.add("Costa Rica");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,3 +13,4 @@
|
||||||
- [How to Invert an Array in Java](http://www.baeldung.com/java-invert-array)
|
- [How to Invert an Array in Java](http://www.baeldung.com/java-invert-array)
|
||||||
- [Array Operations in Java](http://www.baeldung.com/java-common-array-operations)
|
- [Array Operations in Java](http://www.baeldung.com/java-common-array-operations)
|
||||||
- [Intersection Between two Integer Arrays](https://www.baeldung.com/java-array-intersection)
|
- [Intersection Between two Integer Arrays](https://www.baeldung.com/java-array-intersection)
|
||||||
|
- [Sorting Arrays in Java](https://www.baeldung.com/java-sorting-arrays)
|
||||||
|
|
|
@ -24,4 +24,5 @@
|
||||||
- [Java List Initialization in One Line](https://www.baeldung.com/java-init-list-one-line)
|
- [Java List Initialization in One Line](https://www.baeldung.com/java-init-list-one-line)
|
||||||
- [Ways to Iterate Over a List in Java](https://www.baeldung.com/java-iterate-list)
|
- [Ways to Iterate Over a List in Java](https://www.baeldung.com/java-iterate-list)
|
||||||
- [ClassCastException: Arrays$ArrayList cannot be cast to ArrayList](https://www.baeldung.com/java-classcastexception-arrays-arraylist)
|
- [ClassCastException: Arrays$ArrayList cannot be cast to ArrayList](https://www.baeldung.com/java-classcastexception-arrays-arraylist)
|
||||||
- [Flattening Nested Collections in Java](http://www.baeldung.com/java-flatten-nested-collections)
|
- [Flattening Nested Collections in Java](http://www.baeldung.com/java-flatten-nested-collections)
|
||||||
|
- [Intersection of Two Lists in Java](https://www.baeldung.com/java-lists-intersection)
|
||||||
|
|
|
@ -6,11 +6,11 @@ public class ArrayListOfArrayList {
|
||||||
|
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
|
|
||||||
int numVertices = 3;
|
int vertexCount = 3;
|
||||||
ArrayList<ArrayList<Integer>> graph = new ArrayList<>(numVertices);
|
ArrayList<ArrayList<Integer>> graph = new ArrayList<>(vertexCount);
|
||||||
|
|
||||||
//Initializing each element of ArrayList with ArrayList
|
//Initializing each element of ArrayList with ArrayList
|
||||||
for(int i=0; i< numVertices; i++) {
|
for(int i = 0; i< vertexCount; i++) {
|
||||||
graph.add(new ArrayList<Integer>());
|
graph.add(new ArrayList<Integer>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,13 +21,14 @@ public class ArrayListOfArrayList {
|
||||||
graph.get(1).add(0);
|
graph.get(1).add(0);
|
||||||
graph.get(2).add(1);
|
graph.get(2).add(1);
|
||||||
graph.get(0).add(2);
|
graph.get(0).add(2);
|
||||||
|
|
||||||
//Printing all the edges
|
vertexCount = graph.size();
|
||||||
for(int vertexNo=0; vertexNo<numVertices; vertexNo++) {
|
for(int i = 0; i < vertexCount; i++) {
|
||||||
int edgeCount = graph.get(vertexNo).size();
|
int edgeCount = graph.get(i).size();
|
||||||
ArrayList<Integer> listOfVertices = graph.get(vertexNo);
|
for(int j = 0; j < edgeCount; j++) {
|
||||||
for(int i=0; i<edgeCount; i++) {
|
Integer startVertex = i;
|
||||||
System.out.println("Vertex "+vertexNo+" is connected to vetex "+listOfVertices.get(i));
|
Integer endVertex = graph.get(i).get(j);
|
||||||
|
System.out.printf("Vertex %d is connected to vertex %d%n", startVertex, endVertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,9 @@ public class ThreeDimensionalArrayList {
|
||||||
ArrayList< ArrayList< ArrayList<String> > > space = new ArrayList<>(x_axis_length);
|
ArrayList< ArrayList< ArrayList<String> > > space = new ArrayList<>(x_axis_length);
|
||||||
|
|
||||||
//Initializing each element of ArrayList with ArrayList< ArrayList<String> >
|
//Initializing each element of ArrayList with ArrayList< ArrayList<String> >
|
||||||
for(int i=0; i< x_axis_length; i++) {
|
for(int i = 0; i < x_axis_length; i++) {
|
||||||
space.add(new ArrayList< ArrayList<String> >(y_axis_length));
|
space.add(new ArrayList< ArrayList<String> >(y_axis_length));
|
||||||
for(int j =0; j< y_axis_length; j++) {
|
for(int j = 0; j < y_axis_length; j++) {
|
||||||
space.get(i).add(new ArrayList<String>(z_axis_length));
|
space.get(i).add(new ArrayList<String>(z_axis_length));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,9 +33,9 @@ public class ThreeDimensionalArrayList {
|
||||||
space.get(1).get(1).add(1,"Yellow");
|
space.get(1).get(1).add(1,"Yellow");
|
||||||
|
|
||||||
//Printing colors for all the points
|
//Printing colors for all the points
|
||||||
for(int i=0; i<x_axis_length; i++) {
|
for(int i = 0; i < x_axis_length; i++) {
|
||||||
for(int j=0; j<y_axis_length; j++) {
|
for(int j = 0; j < y_axis_length; j++) {
|
||||||
for(int k=0; k<z_axis_length; k++) {
|
for(int k = 0; k < z_axis_length; k++) {
|
||||||
System.out.println("Color of point ("+i+","+j+","+k+") is :"+space.get(i).get(j).get(k));
|
System.out.println("Color of point ("+i+","+j+","+k+") is :"+space.get(i).get(j).get(k));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,4 +28,6 @@
|
||||||
- [Combining Different Types of Collections in Java](https://www.baeldung.com/java-combine-collections)
|
- [Combining Different Types of Collections in Java](https://www.baeldung.com/java-combine-collections)
|
||||||
- [Sorting in Java](http://www.baeldung.com/java-sorting)
|
- [Sorting in Java](http://www.baeldung.com/java-sorting)
|
||||||
- [Join and Split Arrays and Collections in Java](http://www.baeldung.com/java-join-and-split)
|
- [Join and Split Arrays and Collections in Java](http://www.baeldung.com/java-join-and-split)
|
||||||
- [A Guide to EnumMap](https://www.baeldung.com/java-enum-map)
|
- [A Guide to EnumMap](https://www.baeldung.com/java-enum-map)
|
||||||
|
- [A Guide to Iterator in Java](http://www.baeldung.com/java-iterator)
|
||||||
|
- [Differences Between HashMap and Hashtable](https://www.baeldung.com/hashmap-hashtable-differences)
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.baeldung.java.list;
|
||||||
|
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
public class VectorExample {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
Vector<String> vector = new Vector<>();
|
||||||
|
vector.add("baeldung");
|
||||||
|
vector.add("Vector");
|
||||||
|
vector.add("example");
|
||||||
|
|
||||||
|
Enumeration e = vector.elements();
|
||||||
|
while(e.hasMoreElements()){
|
||||||
|
System.out.println(e.nextElement());
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<String> iterator = vector.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
System.out.println(iterator.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@BenchmarkMode(Mode.AverageTime)
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
@Warmup(iterations = 10)
|
@Warmup(iterations = 10)
|
||||||
public class ArrayListBenchmark {
|
public class ArrayListBenchmark {
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ public class ArrayListBenchmark {
|
||||||
public static class MyState {
|
public static class MyState {
|
||||||
|
|
||||||
List<Employee> employeeList = new ArrayList<>();
|
List<Employee> employeeList = new ArrayList<>();
|
||||||
|
Vector<Employee> employeeVector = new Vector<>();
|
||||||
//LinkedList<Employee> employeeList = new LinkedList<>();
|
//LinkedList<Employee> employeeList = new LinkedList<>();
|
||||||
|
|
||||||
long iterations = 100000;
|
long iterations = 100000;
|
||||||
|
@ -29,9 +30,11 @@ public class ArrayListBenchmark {
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
for (long i = 0; i < iterations; i++) {
|
for (long i = 0; i < iterations; i++) {
|
||||||
employeeList.add(new Employee(i, "John"));
|
employeeList.add(new Employee(i, "John"));
|
||||||
|
employeeVector.add(new Employee(i, "John"));
|
||||||
}
|
}
|
||||||
|
|
||||||
employeeList.add(employee);
|
employeeList.add(employee);
|
||||||
|
employeeVector.add(employee);
|
||||||
employeeIndex = employeeList.indexOf(employee);
|
employeeIndex = employeeList.indexOf(employee);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +49,11 @@ public class ArrayListBenchmark {
|
||||||
return state.employeeList.contains(state.employee);
|
return state.employeeList.contains(state.employee);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public boolean testContainsVector(ArrayListBenchmark.MyState state) {
|
||||||
|
return state.employeeVector.contains(state.employee);
|
||||||
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
public int testIndexOf(ArrayListBenchmark.MyState state) {
|
public int testIndexOf(ArrayListBenchmark.MyState state) {
|
||||||
return state.employeeList.indexOf(state.employee);
|
return state.employeeList.indexOf(state.employee);
|
||||||
|
@ -56,19 +64,24 @@ public class ArrayListBenchmark {
|
||||||
return state.employeeList.get(state.employeeIndex);
|
return state.employeeList.get(state.employeeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Employee testVectorGet(ArrayListBenchmark.MyState state) {
|
||||||
|
return state.employeeVector.get(state.employeeIndex);
|
||||||
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
public boolean testRemove(ArrayListBenchmark.MyState state) {
|
public boolean testRemove(ArrayListBenchmark.MyState state) {
|
||||||
return state.employeeList.remove(state.employee);
|
return state.employeeList.remove(state.employee);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Benchmark
|
@Benchmark
|
||||||
// public void testAdd(ArrayListBenchmark.MyState state) {
|
public void testAdd(ArrayListBenchmark.MyState state) {
|
||||||
// state.employeeList.add(new Employee(state.iterations + 1, "John"));
|
state.employeeList.add(new Employee(state.iterations + 1, "John"));
|
||||||
// }
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
Options options = new OptionsBuilder()
|
Options options = new OptionsBuilder()
|
||||||
.include(ArrayListBenchmark.class.getSimpleName()).threads(1)
|
.include(ArrayListBenchmark.class.getSimpleName()).threads(3)
|
||||||
.forks(1).shouldFailOnError(true)
|
.forks(1).shouldFailOnError(true)
|
||||||
.shouldDoGC(true)
|
.shouldDoGC(true)
|
||||||
.jvmArgs("-server").build();
|
.jvmArgs("-server").build();
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.baeldung.queueinterface;
|
||||||
|
|
||||||
|
import java.util.AbstractQueue;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
public class CustomBaeldungQueue<T> extends AbstractQueue<T> {
|
||||||
|
|
||||||
|
private LinkedList<T> elements;
|
||||||
|
|
||||||
|
public CustomBaeldungQueue() {
|
||||||
|
this.elements = new LinkedList<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<T> iterator() {
|
||||||
|
return elements.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return elements.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean offer(T t) {
|
||||||
|
if(t == null) return false;
|
||||||
|
elements.add(t);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T poll() {
|
||||||
|
|
||||||
|
Iterator<T> iter = elements.iterator();
|
||||||
|
T t = iter.next();
|
||||||
|
if(t != null){
|
||||||
|
iter.remove();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T peek() {
|
||||||
|
return elements.getFirst();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.baeldung.queueinterface;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class PriorityQueueUnitTest {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenIntegerQueue_whenIntegersOutOfOrder_checkRetrievalOrderIsNatural() {
|
||||||
|
|
||||||
|
PriorityQueue<Integer> integerQueue = new PriorityQueue<>();
|
||||||
|
|
||||||
|
integerQueue.add(9);
|
||||||
|
integerQueue.add(2);
|
||||||
|
integerQueue.add(4);
|
||||||
|
|
||||||
|
int first = integerQueue.poll();
|
||||||
|
int second = integerQueue.poll();
|
||||||
|
int third = integerQueue.poll();
|
||||||
|
|
||||||
|
assertEquals(2, first);
|
||||||
|
assertEquals(4, second);
|
||||||
|
assertEquals(9, third);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenStringQueue_whenStringsAddedOutOfNaturalOrder_checkRetrievalOrderNatural() {
|
||||||
|
|
||||||
|
PriorityQueue<String> stringQueue = new PriorityQueue<>();
|
||||||
|
|
||||||
|
stringQueue.add("banana");
|
||||||
|
stringQueue.add("apple");
|
||||||
|
stringQueue.add("cherry");
|
||||||
|
|
||||||
|
String first = stringQueue.poll();
|
||||||
|
String second = stringQueue.poll();
|
||||||
|
String third = stringQueue.poll();
|
||||||
|
|
||||||
|
assertEquals("apple", first);
|
||||||
|
assertEquals("banana", second);
|
||||||
|
assertEquals("cherry", third);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.queueinterface;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class CustomBaeldungQueueUnitTest {
|
||||||
|
|
||||||
|
private CustomBaeldungQueue<Integer> customQueue;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
customQueue = new CustomBaeldungQueue<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenQueueWithTwoElements_whenElementsRetrieved_checkRetrievalCorrect() {
|
||||||
|
|
||||||
|
customQueue.add(7);
|
||||||
|
customQueue.add(5);
|
||||||
|
|
||||||
|
int first = customQueue.poll();
|
||||||
|
int second = customQueue.poll();
|
||||||
|
|
||||||
|
assertEquals(7, first);
|
||||||
|
assertEquals(5, second);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.application;
|
||||||
|
|
||||||
|
import com.baeldung.concurrent.threadsafety.callables.AtomicCounterCallable;
|
||||||
|
import com.baeldung.concurrent.threadsafety.mathutils.MathUtils;
|
||||||
|
import com.baeldung.concurrent.threadsafety.callables.CounterCallable;
|
||||||
|
import com.baeldung.concurrent.threadsafety.callables.ExtrinsicLockCounterCallable;
|
||||||
|
import com.baeldung.concurrent.threadsafety.callables.MessageServiceCallable;
|
||||||
|
import com.baeldung.concurrent.threadsafety.callables.ReentranReadWriteLockCounterCallable;
|
||||||
|
import com.baeldung.concurrent.threadsafety.callables.ReentrantLockCounterCallable;
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.AtomicCounter;
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.Counter;
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.ExtrinsicLockCounter;
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.MessageService;
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.ReentrantLockCounter;
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.ReentrantReadWriteLockCounter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException, ExecutionException {
|
||||||
|
|
||||||
|
new Thread(() -> {
|
||||||
|
System.out.println(MathUtils.factorial(10));
|
||||||
|
}).start();
|
||||||
|
new Thread(() -> {
|
||||||
|
System.out.println(MathUtils.factorial(5));
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(10);
|
||||||
|
MessageService messageService = new MessageService("Welcome to Baeldung!");
|
||||||
|
Future<String> future1 = (Future<String>) executorService.submit(new MessageServiceCallable(messageService));
|
||||||
|
Future<String> future2 = (Future<String>) executorService.submit(new MessageServiceCallable(messageService));
|
||||||
|
System.out.println(future1.get());
|
||||||
|
System.out.println(future2.get());
|
||||||
|
|
||||||
|
Counter counter = new Counter();
|
||||||
|
Future<Integer> future3 = (Future<Integer>) executorService.submit(new CounterCallable(counter));
|
||||||
|
Future<Integer> future4 = (Future<Integer>) executorService.submit(new CounterCallable(counter));
|
||||||
|
System.out.println(future3.get());
|
||||||
|
System.out.println(future4.get());
|
||||||
|
|
||||||
|
ExtrinsicLockCounter extrinsicLockCounter = new ExtrinsicLockCounter();
|
||||||
|
Future<Integer> future5 = (Future<Integer>) executorService.submit(new ExtrinsicLockCounterCallable(extrinsicLockCounter));
|
||||||
|
Future<Integer> future6 = (Future<Integer>) executorService.submit(new ExtrinsicLockCounterCallable(extrinsicLockCounter));
|
||||||
|
System.out.println(future5.get());
|
||||||
|
System.out.println(future6.get());
|
||||||
|
|
||||||
|
ReentrantLockCounter reentrantLockCounter = new ReentrantLockCounter();
|
||||||
|
Future<Integer> future7 = (Future<Integer>) executorService.submit(new ReentrantLockCounterCallable(reentrantLockCounter));
|
||||||
|
Future<Integer> future8 = (Future<Integer>) executorService.submit(new ReentrantLockCounterCallable(reentrantLockCounter));
|
||||||
|
System.out.println(future7.get());
|
||||||
|
System.out.println(future8.get());
|
||||||
|
|
||||||
|
ReentrantReadWriteLockCounter reentrantReadWriteLockCounter = new ReentrantReadWriteLockCounter();
|
||||||
|
Future<Integer> future9 = (Future<Integer>) executorService.submit(new ReentranReadWriteLockCounterCallable(reentrantReadWriteLockCounter));
|
||||||
|
Future<Integer> future10 = (Future<Integer>) executorService.submit(new ReentranReadWriteLockCounterCallable(reentrantReadWriteLockCounter));
|
||||||
|
System.out.println(future9.get());
|
||||||
|
System.out.println(future10.get());
|
||||||
|
|
||||||
|
AtomicCounter atomicCounter = new AtomicCounter();
|
||||||
|
Future<Integer> future11 = (Future<Integer>) executorService.submit(new AtomicCounterCallable(atomicCounter));
|
||||||
|
Future<Integer> future12 = (Future<Integer>) executorService.submit(new AtomicCounterCallable(atomicCounter));
|
||||||
|
System.out.println(future11.get());
|
||||||
|
System.out.println(future12.get());
|
||||||
|
|
||||||
|
Collection<Integer> syncCollection = Collections.synchronizedCollection(new ArrayList<>());
|
||||||
|
Thread thread11 = new Thread(() -> syncCollection.addAll(Arrays.asList(1, 2, 3, 4, 5, 6)));
|
||||||
|
Thread thread12 = new Thread(() -> syncCollection.addAll(Arrays.asList(1, 2, 3, 4, 5, 6)));
|
||||||
|
thread11.start();
|
||||||
|
thread12.start();
|
||||||
|
|
||||||
|
Map<String,String> concurrentMap = new ConcurrentHashMap<>();
|
||||||
|
concurrentMap.put("1", "one");
|
||||||
|
concurrentMap.put("2", "two");
|
||||||
|
concurrentMap.put("3", "three");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.callables;
|
||||||
|
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.AtomicCounter;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class AtomicCounterCallable implements Callable<Integer> {
|
||||||
|
|
||||||
|
private final AtomicCounter counter;
|
||||||
|
|
||||||
|
public AtomicCounterCallable(AtomicCounter counter) {
|
||||||
|
this.counter = counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer call() throws Exception {
|
||||||
|
counter.incrementCounter();
|
||||||
|
return counter.getCounter();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.callables;
|
||||||
|
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.Counter;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class CounterCallable implements Callable<Integer> {
|
||||||
|
|
||||||
|
private final Counter counter;
|
||||||
|
|
||||||
|
public CounterCallable(Counter counter) {
|
||||||
|
this.counter = counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer call() throws Exception {
|
||||||
|
counter.incrementCounter();
|
||||||
|
return counter.getCounter();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.callables;
|
||||||
|
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.ExtrinsicLockCounter;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class ExtrinsicLockCounterCallable implements Callable<Integer> {
|
||||||
|
|
||||||
|
private final ExtrinsicLockCounter counter;
|
||||||
|
|
||||||
|
public ExtrinsicLockCounterCallable(ExtrinsicLockCounter counter) {
|
||||||
|
this.counter = counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer call() throws Exception {
|
||||||
|
counter.incrementCounter();
|
||||||
|
return counter.getCounter();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.callables;
|
||||||
|
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.MessageService;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class MessageServiceCallable implements Callable<String> {
|
||||||
|
|
||||||
|
private final MessageService messageService;
|
||||||
|
|
||||||
|
public MessageServiceCallable(MessageService messageService) {
|
||||||
|
this.messageService = messageService;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String call() {
|
||||||
|
return messageService.getMesssage();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.callables;
|
||||||
|
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.ReentrantReadWriteLockCounter;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class ReentranReadWriteLockCounterCallable implements Callable<Integer> {
|
||||||
|
|
||||||
|
private final ReentrantReadWriteLockCounter counter;
|
||||||
|
|
||||||
|
public ReentranReadWriteLockCounterCallable(ReentrantReadWriteLockCounter counter) {
|
||||||
|
this.counter = counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer call() throws Exception {
|
||||||
|
counter.incrementCounter();
|
||||||
|
return counter.getCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.callables;
|
||||||
|
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.ReentrantLockCounter;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class ReentrantLockCounterCallable implements Callable<Integer> {
|
||||||
|
|
||||||
|
private final ReentrantLockCounter counter;
|
||||||
|
|
||||||
|
public ReentrantLockCounterCallable(ReentrantLockCounter counter) {
|
||||||
|
this.counter = counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer call() throws Exception {
|
||||||
|
counter.incrementCounter();
|
||||||
|
return counter.getCounter();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.mathutils;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
public class MathUtils {
|
||||||
|
|
||||||
|
public static BigInteger factorial(int number) {
|
||||||
|
BigInteger f = new BigInteger("1");
|
||||||
|
for (int i = 2; i <= number; i++) {
|
||||||
|
f = f.multiply(BigInteger.valueOf(i));
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.services;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class AtomicCounter {
|
||||||
|
|
||||||
|
private final AtomicInteger counter = new AtomicInteger();
|
||||||
|
|
||||||
|
public AtomicCounter() {}
|
||||||
|
|
||||||
|
public void incrementCounter() {
|
||||||
|
counter.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized int getCounter() {
|
||||||
|
return counter.get();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.services;
|
||||||
|
|
||||||
|
public class Counter {
|
||||||
|
|
||||||
|
private volatile int counter;
|
||||||
|
|
||||||
|
public Counter() {
|
||||||
|
this.counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void incrementCounter() {
|
||||||
|
counter += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCounter() {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.services;
|
||||||
|
|
||||||
|
public class ExtrinsicLockCounter {
|
||||||
|
|
||||||
|
private int counter;
|
||||||
|
private final Object lock = new Object();
|
||||||
|
|
||||||
|
public ExtrinsicLockCounter() {
|
||||||
|
this.counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrementCounter() {
|
||||||
|
synchronized (lock) {
|
||||||
|
counter += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCounter() {
|
||||||
|
synchronized (lock) {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.services;
|
||||||
|
|
||||||
|
public class MessageService {
|
||||||
|
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
public MessageService(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMesssage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.services;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
public class ReentrantLockCounter {
|
||||||
|
|
||||||
|
private int counter;
|
||||||
|
private final ReentrantLock reLock = new ReentrantLock(true);
|
||||||
|
|
||||||
|
public ReentrantLockCounter() {
|
||||||
|
this.counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrementCounter() {
|
||||||
|
reLock.lock();
|
||||||
|
try {
|
||||||
|
counter += 1;
|
||||||
|
} finally {
|
||||||
|
reLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCounter() {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.services;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
|
public class ReentrantReadWriteLockCounter {
|
||||||
|
|
||||||
|
private int counter;
|
||||||
|
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
|
||||||
|
private final Lock readLock = rwLock.readLock();
|
||||||
|
private final Lock writeLock = rwLock.writeLock();
|
||||||
|
|
||||||
|
public ReentrantReadWriteLockCounter() {
|
||||||
|
this.counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrementCounter() {
|
||||||
|
writeLock.lock();
|
||||||
|
try {
|
||||||
|
counter += 1;
|
||||||
|
} finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCounter() {
|
||||||
|
readLock.lock();
|
||||||
|
try {
|
||||||
|
return counter;
|
||||||
|
} finally {
|
||||||
|
readLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.services;
|
||||||
|
|
||||||
|
public class StateHolder {
|
||||||
|
|
||||||
|
private final String state;
|
||||||
|
|
||||||
|
public StateHolder(String state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.tests;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import com.baeldung.concurrent.threadsafety.callables.CounterCallable;
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.Counter;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class CounterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCalledIncrementCounter_thenCorrect() throws Exception {
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(2);
|
||||||
|
Counter counter = new Counter();
|
||||||
|
Future<Integer> future1 = (Future<Integer>) executorService.submit(new CounterCallable(counter));
|
||||||
|
Future<Integer> future2 = (Future<Integer>) executorService.submit(new CounterCallable(counter));
|
||||||
|
|
||||||
|
assertThat(future1.get()).isEqualTo(1);
|
||||||
|
assertThat(future2.get()).isEqualTo(2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.tests;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import com.baeldung.concurrent.threadsafety.callables.ExtrinsicLockCounterCallable;
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.ExtrinsicLockCounter;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class ExtrinsicLockCounterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCalledIncrementCounter_thenCorrect() throws Exception {
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(2);
|
||||||
|
ExtrinsicLockCounter counter = new ExtrinsicLockCounter();
|
||||||
|
Future<Integer> future1 = (Future<Integer>) executorService.submit(new ExtrinsicLockCounterCallable(counter));
|
||||||
|
Future<Integer> future2 = (Future<Integer>) executorService.submit(new ExtrinsicLockCounterCallable(counter));
|
||||||
|
|
||||||
|
assertThat(future1.get()).isEqualTo(1);
|
||||||
|
assertThat(future2.get()).isEqualTo(2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.tests;
|
||||||
|
|
||||||
|
import com.baeldung.concurrent.threadsafety.mathutils.MathUtils;
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class MathUtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCalledFactorialMethod_thenCorrect() {
|
||||||
|
assertThat(MathUtils.factorial(2)).isEqualTo(2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.tests;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import com.baeldung.concurrent.threadsafety.callables.MessageServiceCallable;
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.MessageService;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class MessageServiceTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCalledgetMessage_thenCorrect() throws Exception {
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(2);
|
||||||
|
MessageService messageService = new MessageService("Welcome to Baeldung!");
|
||||||
|
Future<String> future1 = (Future<String>) executorService.submit(new MessageServiceCallable(messageService));
|
||||||
|
Future<String> future2 = (Future<String>) executorService.submit(new MessageServiceCallable(messageService));
|
||||||
|
|
||||||
|
assertThat(future1.get()).isEqualTo("Welcome to Baeldung!");
|
||||||
|
assertThat(future2.get()).isEqualTo("Welcome to Baeldung!");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.tests;
|
||||||
|
|
||||||
|
import com.baeldung.concurrent.threadsafety.callables.ReentrantLockCounterCallable;
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.ReentrantLockCounter;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ReentrantLockCounterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCalledIncrementCounter_thenCorrect() throws Exception {
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(2);
|
||||||
|
ReentrantLockCounter counter = new ReentrantLockCounter();
|
||||||
|
Future<Integer> future1 = (Future<Integer>) executorService.submit(new ReentrantLockCounterCallable(counter));
|
||||||
|
Future<Integer> future2 = (Future<Integer>) executorService.submit(new ReentrantLockCounterCallable(counter));
|
||||||
|
|
||||||
|
assertThat(future1.get()).isEqualTo(1);
|
||||||
|
assertThat(future2.get()).isEqualTo(2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.baeldung.concurrent.threadsafety.tests;
|
||||||
|
|
||||||
|
import com.baeldung.concurrent.threadsafety.callables.ReentranReadWriteLockCounterCallable;
|
||||||
|
import com.baeldung.concurrent.threadsafety.services.ReentrantReadWriteLockCounter;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ReentrantReadWriteLockCounterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCalledIncrementCounter_thenCorrect() throws Exception {
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(2);
|
||||||
|
ReentrantReadWriteLockCounter counter = new ReentrantReadWriteLockCounter();
|
||||||
|
Future<Integer> future1 = (Future<Integer>) executorService.submit(new ReentranReadWriteLockCounterCallable(counter));
|
||||||
|
Future<Integer> future2 = (Future<Integer>) executorService.submit(new ReentranReadWriteLockCounterCallable(counter));
|
||||||
|
|
||||||
|
assertThat(future1.get()).isEqualTo(1);
|
||||||
|
assertThat(future2.get()).isEqualTo(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -35,3 +35,5 @@
|
||||||
- [Guide to Java OutputStream](https://www.baeldung.com/java-outputstream)
|
- [Guide to Java OutputStream](https://www.baeldung.com/java-outputstream)
|
||||||
- [Reading a CSV File into an Array](https://www.baeldung.com/java-csv-file-array)
|
- [Reading a CSV File into an Array](https://www.baeldung.com/java-csv-file-array)
|
||||||
- [Guide to BufferedReader](https://www.baeldung.com/java-buffered-reader)
|
- [Guide to BufferedReader](https://www.baeldung.com/java-buffered-reader)
|
||||||
|
- [How to Get the File Extension of a File in Java](http://www.baeldung.com/java-file-extension)
|
||||||
|
- [Getting a File’s Mime Type in Java](http://www.baeldung.com/java-file-mime-type)
|
|
@ -160,6 +160,17 @@
|
||||||
<version>${opencsv.version}</version>
|
<version>${opencsv.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- Mime Type Resolution Libraries -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.tika</groupId>
|
||||||
|
<artifactId>tika-core</artifactId>
|
||||||
|
<version>${tika.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.sf.jmimemagic</groupId>
|
||||||
|
<artifactId>jmimemagic</artifactId>
|
||||||
|
<version>${jmime-magic.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -264,6 +275,9 @@
|
||||||
<esapi.version>2.1.0.1</esapi.version>
|
<esapi.version>2.1.0.1</esapi.version>
|
||||||
<jmh-generator-annprocess.version>1.19</jmh-generator-annprocess.version>
|
<jmh-generator-annprocess.version>1.19</jmh-generator-annprocess.version>
|
||||||
<async-http-client.version>2.4.5</async-http-client.version>
|
<async-http-client.version>2.4.5</async-http-client.version>
|
||||||
|
<!-- Mime Type Libraries -->
|
||||||
|
<tika.version>1.18</tika.version>
|
||||||
|
<jmime-magic.version>0.1.5</jmime-magic.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.baeldung.csv;
|
||||||
|
|
||||||
|
public class WriteCsvFileExample {
|
||||||
|
|
||||||
|
public String convertToCSV(String[] data) {
|
||||||
|
StringBuilder csvLine = new StringBuilder();
|
||||||
|
|
||||||
|
for (int i = 0; i < data.length; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
csvLine.append(",");
|
||||||
|
}
|
||||||
|
csvLine.append(escapeSpecialCharacters(data[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return csvLine.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String escapeSpecialCharacters(String data) {
|
||||||
|
String escapedData = data.replaceAll("\\R", " ");
|
||||||
|
if (data.contains(",") || data.contains("\"") || data.contains("'")) {
|
||||||
|
data = data.replace("\"", "\"\"");
|
||||||
|
escapedData = "\"" + data + "\"";
|
||||||
|
}
|
||||||
|
return escapedData;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package com.baeldung.csv;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class WriteCsvFileExampleUnitTest {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(WriteCsvFileExampleUnitTest.class);
|
||||||
|
|
||||||
|
private static final String CSV_FILE_NAME = "src/test/resources/exampleOutput.csv";
|
||||||
|
private WriteCsvFileExample csvExample;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setupClass() {
|
||||||
|
csvExample = new WriteCsvFileExample();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCommaContainingData_whenEscapeSpecialCharacters_stringReturnedInQuotes() {
|
||||||
|
String data = "three,two,one";
|
||||||
|
String escapedData = csvExample.escapeSpecialCharacters(data);
|
||||||
|
|
||||||
|
String expectedData = "\"three,two,one\"";
|
||||||
|
assertEquals(expectedData, escapedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenQuoteContainingData_whenEscapeSpecialCharacters_stringReturnedFormatted() {
|
||||||
|
String data = "She said \"Hello\"";
|
||||||
|
String escapedData = csvExample.escapeSpecialCharacters(data);
|
||||||
|
|
||||||
|
String expectedData = "\"She said \"\"Hello\"\"\"";
|
||||||
|
assertEquals(expectedData, escapedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNewlineContainingData_whenEscapeSpecialCharacters_stringReturnedInQuotes() {
|
||||||
|
String dataNewline = "This contains\na newline";
|
||||||
|
String dataCarriageReturn = "This contains\r\na newline and carriage return";
|
||||||
|
String escapedDataNl = csvExample.escapeSpecialCharacters(dataNewline);
|
||||||
|
String escapedDataCr = csvExample.escapeSpecialCharacters(dataCarriageReturn);
|
||||||
|
|
||||||
|
String expectedData = "This contains a newline";
|
||||||
|
assertEquals(expectedData, escapedDataNl);
|
||||||
|
String expectedDataCr = "This contains a newline and carriage return";
|
||||||
|
assertEquals(expectedDataCr, escapedDataCr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNonSpecialData_whenEscapeSpecialCharacters_stringReturnedUnchanged() {
|
||||||
|
String data = "This is nothing special";
|
||||||
|
String returnedData = csvExample.escapeSpecialCharacters(data);
|
||||||
|
|
||||||
|
assertEquals(data, returnedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenBufferedWriter_whenWriteLine_thenOutputCreated() {
|
||||||
|
List<String[]> dataLines = new ArrayList<String[]>();
|
||||||
|
dataLines.add(new String[] { "John", "Doe", "38", "Comment Data\nAnother line of comment data" });
|
||||||
|
dataLines.add(new String[] { "Jane", "Doe, Jr.", "19", "She said \"I'm being quoted\"" });
|
||||||
|
|
||||||
|
File csvOutputFile = new File(CSV_FILE_NAME);
|
||||||
|
try (PrintWriter pw = new PrintWriter(csvOutputFile)) {
|
||||||
|
dataLines.stream()
|
||||||
|
.map(csvExample::convertToCSV)
|
||||||
|
.forEach(pw::println);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
LOG.error("IOException " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue(csvOutputFile.exists());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package org.baeldung.java.io;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
class InputStreamToByteBufferUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUsingCoreClasses_whenWritingAFileIntoAByteBuffer_thenBytesLengthMustMatch() throws IOException {
|
||||||
|
File inputFile = getFile();
|
||||||
|
ByteBuffer bufferByte = ByteBuffer.allocate((int) inputFile.length());
|
||||||
|
FileInputStream in = new FileInputStream(inputFile);
|
||||||
|
in.getChannel().read(bufferByte);
|
||||||
|
|
||||||
|
assertEquals(bufferByte.position(), inputFile.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUsingCommonsIo_whenWritingAFileIntoAByteBuffer_thenBytesLengthMustMatch() throws IOException {
|
||||||
|
File inputFile = getFile();
|
||||||
|
ByteBuffer bufferByte = ByteBuffer.allocateDirect((int) inputFile.length());
|
||||||
|
ReadableByteChannel readableByteChannel = new FileInputStream(inputFile).getChannel();
|
||||||
|
IOUtils.readFully(readableByteChannel, bufferByte);
|
||||||
|
|
||||||
|
assertEquals(bufferByte.position(), inputFile.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUsingGuava_whenWritingAFileIntoAByteBuffer_thenBytesLengthMustMatch() throws IOException {
|
||||||
|
File inputFile = getFile();
|
||||||
|
FileInputStream in = new FileInputStream(inputFile);
|
||||||
|
byte[] targetArray = ByteStreams.toByteArray(in);
|
||||||
|
ByteBuffer bufferByte = ByteBuffer.wrap(targetArray);
|
||||||
|
bufferByte.rewind();
|
||||||
|
while (bufferByte.hasRemaining()) {
|
||||||
|
bufferByte.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(bufferByte.position(), inputFile.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getFile() {
|
||||||
|
ClassLoader classLoader = new InputStreamToByteBufferUnitTest().getClass().getClassLoader();
|
||||||
|
|
||||||
|
String fileName = "frontenac-2257154_960_720.jpg";
|
||||||
|
|
||||||
|
return new File(classLoader.getResource(fileName).getFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
John,Doe,38,Comment Data Another line of comment data
|
||||||
|
Jane,"Doe, Jr.",19,"She said ""I'm being quoted"""
|
|
Binary file not shown.
After Width: | Height: | Size: 190 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
@ -33,3 +33,5 @@
|
||||||
- [How to Separate Double into Integer and Decimal Parts](https://www.baeldung.com/java-separate-double-into-integer-decimal-parts)
|
- [How to Separate Double into Integer and Decimal Parts](https://www.baeldung.com/java-separate-double-into-integer-decimal-parts)
|
||||||
- [“Sneaky Throws” in Java](http://www.baeldung.com/java-sneaky-throws)
|
- [“Sneaky Throws” in Java](http://www.baeldung.com/java-sneaky-throws)
|
||||||
- [Retrieving a Class Name in Java](https://www.baeldung.com/java-class-name)
|
- [Retrieving a Class Name in Java](https://www.baeldung.com/java-class-name)
|
||||||
|
- [Java Compound Operators](https://www.baeldung.com/java-compound-operators)
|
||||||
|
- [Guide to Java Packages](https://www.baeldung.com/java-packages)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue