Merge branch 'master' of https://github.com/eugenp/tutorials
This commit is contained in:
commit
c8fb78143e
|
@ -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.
|
||||
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`.
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
## Relevant articles:
|
||||
|
||||
- [Introduction to Akka HTTP](https://www.baeldung.com/akka-http)
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0"?>
|
||||
<project
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>akka-http</artifactId>
|
||||
<name>akka-http</name>
|
||||
|
||||
<parent>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-http_2.12</artifactId>
|
||||
<version>${akka.http.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-stream_2.12</artifactId>
|
||||
<version>2.5.11</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-http-jackson_2.12</artifactId>
|
||||
<version>${akka.http.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-http-testkit_2.12</artifactId>
|
||||
<version>${akka.http.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<akka.http.version>10.0.11</akka.http.version>
|
||||
<akka.stream.version>2.5.11</akka.stream.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.akkahttp;
|
||||
|
||||
public class User {
|
||||
|
||||
private final Long id;
|
||||
|
||||
private final String name;
|
||||
|
||||
public User() {
|
||||
this.name = "";
|
||||
this.id = null;
|
||||
}
|
||||
|
||||
public User(Long id, String name) {
|
||||
this.name = name;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.baeldung.akkahttp;
|
||||
|
||||
import akka.actor.AbstractActor;
|
||||
import akka.actor.Props;
|
||||
import akka.japi.pf.FI;
|
||||
import com.baeldung.akkahttp.UserMessages.ActionPerformed;
|
||||
import com.baeldung.akkahttp.UserMessages.CreateUserMessage;
|
||||
import com.baeldung.akkahttp.UserMessages.GetUserMessage;
|
||||
|
||||
|
||||
class UserActor extends AbstractActor {
|
||||
|
||||
private UserService userService = new UserService();
|
||||
|
||||
static Props props() {
|
||||
return Props.create(UserActor.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Receive createReceive() {
|
||||
return receiveBuilder()
|
||||
.match(CreateUserMessage.class, handleCreateUser())
|
||||
.match(GetUserMessage.class, handleGetUser())
|
||||
.build();
|
||||
}
|
||||
|
||||
private FI.UnitApply<CreateUserMessage> handleCreateUser() {
|
||||
return createUserMessageMessage -> {
|
||||
userService.createUser(createUserMessageMessage.getUser());
|
||||
sender().tell(new ActionPerformed(String.format("User %s created.", createUserMessageMessage.getUser()
|
||||
.getName())), getSelf());
|
||||
};
|
||||
}
|
||||
|
||||
private FI.UnitApply<GetUserMessage> handleGetUser() {
|
||||
return getUserMessageMessage -> {
|
||||
sender().tell(userService.getUser(getUserMessageMessage.getUserId()), getSelf());
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.baeldung.akkahttp;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface UserMessages {
|
||||
|
||||
class ActionPerformed implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String description;
|
||||
|
||||
public ActionPerformed(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
|
||||
class CreateUserMessage implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final User user;
|
||||
|
||||
public CreateUserMessage(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
class GetUserMessage implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Long userId;
|
||||
|
||||
public GetUserMessage(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package com.baeldung.akkahttp;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import akka.actor.ActorRef;
|
||||
import akka.actor.ActorSystem;
|
||||
import akka.http.javadsl.marshallers.jackson.Jackson;
|
||||
import akka.http.javadsl.model.StatusCodes;
|
||||
import akka.http.javadsl.server.HttpApp;
|
||||
import akka.http.javadsl.server.Route;
|
||||
import akka.pattern.PatternsCS;
|
||||
import akka.util.Timeout;
|
||||
import com.baeldung.akkahttp.UserMessages.ActionPerformed;
|
||||
import com.baeldung.akkahttp.UserMessages.CreateUserMessage;
|
||||
import com.baeldung.akkahttp.UserMessages.GetUserMessage;
|
||||
import scala.concurrent.duration.Duration;
|
||||
import static akka.http.javadsl.server.PathMatchers.*;
|
||||
|
||||
class UserServer extends HttpApp {
|
||||
|
||||
private final ActorRef userActor;
|
||||
|
||||
Timeout timeout = new Timeout(Duration.create(5, TimeUnit.SECONDS));
|
||||
|
||||
UserServer(ActorRef userActor) {
|
||||
this.userActor = userActor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Route routes() {
|
||||
return path("users", this::postUser)
|
||||
.orElse(path(segment("users").slash(longSegment()), id ->
|
||||
route(getUser(id))));
|
||||
}
|
||||
|
||||
private Route getUser(Long id) {
|
||||
return get(() -> {
|
||||
CompletionStage<Optional<User>> user = PatternsCS.ask(userActor, new GetUserMessage(id), timeout)
|
||||
.thenApply(obj -> (Optional<User>) obj);
|
||||
|
||||
return onSuccess(() -> user, performed -> {
|
||||
if (performed.isPresent())
|
||||
return complete(StatusCodes.OK, performed.get(), Jackson.marshaller());
|
||||
else
|
||||
return complete(StatusCodes.NOT_FOUND);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private Route postUser() {
|
||||
return route(post(() -> entity(Jackson.unmarshaller(User.class), user -> {
|
||||
CompletionStage<ActionPerformed> userCreated = PatternsCS.ask(userActor, new CreateUserMessage(user), timeout)
|
||||
.thenApply(obj -> (ActionPerformed) obj);
|
||||
|
||||
return onSuccess(() -> userCreated, performed -> {
|
||||
return complete(StatusCodes.CREATED, performed, Jackson.marshaller());
|
||||
});
|
||||
})));
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ActorSystem system = ActorSystem.create("userServer");
|
||||
ActorRef userActor = system.actorOf(UserActor.props(), "userActor");
|
||||
UserServer server = new UserServer(userActor);
|
||||
server.startServer("localhost", 8080, system);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.akkahttp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class UserService {
|
||||
|
||||
private final static List<User> users = new ArrayList<>();
|
||||
|
||||
static {
|
||||
users.add(new User(1l, "Alice"));
|
||||
users.add(new User(2l, "Bob"));
|
||||
users.add(new User(3l, "Chris"));
|
||||
users.add(new User(4l, "Dick"));
|
||||
users.add(new User(5l, "Eve"));
|
||||
users.add(new User(6l, "Finn"));
|
||||
}
|
||||
|
||||
public Optional<User> getUser(Long id) {
|
||||
return users.stream()
|
||||
.filter(user -> user.getId()
|
||||
.equals(id))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
public void createUser(User user) {
|
||||
users.add(user);
|
||||
}
|
||||
|
||||
public List<User> getUsers(){
|
||||
return users;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.baeldung.akkahttp;
|
||||
|
||||
import akka.actor.ActorRef;
|
||||
import akka.actor.ActorSystem;
|
||||
import akka.http.javadsl.model.ContentTypes;
|
||||
import akka.http.javadsl.model.HttpEntities;
|
||||
import akka.http.javadsl.model.HttpRequest;
|
||||
import akka.http.javadsl.testkit.JUnitRouteTest;
|
||||
import akka.http.javadsl.testkit.TestRoute;
|
||||
import org.junit.Test;
|
||||
|
||||
public class UserServerUnitTest extends JUnitRouteTest {
|
||||
|
||||
ActorSystem system = ActorSystem.create("helloAkkaHttpServer");
|
||||
|
||||
ActorRef userActorRef = system.actorOf(UserActor.props(), "userActor");
|
||||
|
||||
TestRoute appRoute = testRoute(new UserServer(userActorRef).routes());
|
||||
|
||||
@Test
|
||||
public void whenRequest_thenActorResponds() {
|
||||
|
||||
appRoute.run(HttpRequest.GET("/users/1"))
|
||||
.assertEntity(alice())
|
||||
.assertStatusCode(200);
|
||||
|
||||
appRoute.run(HttpRequest.GET("/users/42"))
|
||||
.assertStatusCode(404);
|
||||
|
||||
appRoute.run(HttpRequest.DELETE("/users/1"))
|
||||
.assertStatusCode(200);
|
||||
|
||||
appRoute.run(HttpRequest.DELETE("/users/42"))
|
||||
.assertStatusCode(200);
|
||||
|
||||
appRoute.run(HttpRequest.POST("/users")
|
||||
.withEntity(HttpEntities.create(ContentTypes.APPLICATION_JSON, zaphod())))
|
||||
.assertStatusCode(201);
|
||||
|
||||
}
|
||||
|
||||
private String alice() {
|
||||
return "{\"id\":1,\"name\":\"Alice\"}";
|
||||
}
|
||||
|
||||
private String zaphod() {
|
||||
return "{\"id\":42,\"name\":\"Zaphod\"}";
|
||||
}
|
||||
|
||||
}
|
|
@ -11,3 +11,7 @@
|
|||
- [String Search Algorithms for Large Texts](http://www.baeldung.com/java-full-text-search-algorithms)
|
||||
- [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)
|
||||
- [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 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));
|
||||
}
|
||||
|
||||
}
|
|
@ -59,7 +59,7 @@
|
|||
<properties>
|
||||
<curator.version>4.0.1</curator.version>
|
||||
<zookeeper.version>3.4.11</zookeeper.version>
|
||||
<jackson-databind.version>2.9.4</jackson-databind.version>
|
||||
<jackson-databind.version>2.9.7</jackson-databind.version>
|
||||
<!-- testing -->
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<avaitility.version>1.7.0</avaitility.version>
|
||||
|
|
|
@ -15,16 +15,76 @@
|
|||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-core_2.10 -->
|
||||
<dependency>
|
||||
<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>
|
||||
<scope>provided</scope>
|
||||
</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>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
|
||||
</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();
|
||||
}
|
||||
}
|
44
axon/pom.xml
44
axon/pom.xml
|
@ -4,29 +4,61 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>axon</artifactId>
|
||||
<name>axon</name>
|
||||
<description>Basic Axon Framework with Spring Boot configuration tutorial</description>
|
||||
|
||||
<parent>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<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>
|
||||
|
||||
<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>
|
||||
<groupId>org.axonframework</groupId>
|
||||
<artifactId>axon-test</artifactId>
|
||||
<version>${axon.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.axonframework</groupId>
|
||||
<artifactId>axon-core</artifactId>
|
||||
<version>${axon.version}</version>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
<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>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<axon.version>3.0.2</axon.version>
|
||||
<axon.version>4.0.3</axon.version>
|
||||
</properties>
|
||||
|
||||
</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));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
### Relevant articles
|
||||
|
||||
- [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 String API Additions](https://www.baeldung.com/java-11-string-api)
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class Outer {
|
||||
|
||||
public void outerPublic() {
|
||||
}
|
||||
|
||||
private void outerPrivate() {
|
||||
}
|
||||
|
||||
class Inner {
|
||||
|
||||
public void innerPublic() {
|
||||
outerPrivate();
|
||||
}
|
||||
|
||||
public void innerPublicReflection(Outer ob) throws Exception {
|
||||
Method method = ob.getClass().getDeclaredMethod("outerPrivate");
|
||||
method.invoke(ob);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.baeldung;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class NewStringAPIUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenRepeatStringTwice_thenGetStringTwice() {
|
||||
String output = "La ".repeat(2) + "Land";
|
||||
|
||||
is(output).equals("La La Land");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenStripString_thenReturnStringWithoutWhitespaces() {
|
||||
is("\n\t hello \u2005".strip()).equals("hello");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenTrimAdvanceString_thenReturnStringWithWhitespaces() {
|
||||
is("\n\t hello \u2005".trim()).equals("hello \u2005");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenBlankString_thenReturnTrue() {
|
||||
assertTrue("\n\t\u2005 ".isBlank());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMultilineString_thenReturnNonEmptyLineCount() {
|
||||
String multilineStr = "This is\n \n a multiline\n string.";
|
||||
|
||||
long lineCount = multilineStr.lines()
|
||||
.filter(String::isBlank)
|
||||
.count();
|
||||
|
||||
is(lineCount).equals(3L);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.baeldung;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.junit.Test;
|
||||
|
||||
public class OuterUnitTest {
|
||||
|
||||
private static final String NEST_HOST_NAME = "com.baeldung.Outer";
|
||||
|
||||
@Test
|
||||
public void whenGetNestHostFromOuter_thenGetNestHost() {
|
||||
is(Outer.class.getNestHost().getName()).equals(NEST_HOST_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetNestHostFromInner_thenGetNestHost() {
|
||||
is(Outer.Inner.class.getNestHost().getName()).equals(NEST_HOST_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCheckNestmatesForNestedClasses_thenGetTrue() {
|
||||
is(Outer.Inner.class.isNestmateOf(Outer.class)).equals(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCheckNestmatesForUnrelatedClasses_thenGetFalse() {
|
||||
is(Outer.Inner.class.isNestmateOf(Outer.class)).equals(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGetNestMembersForNestedClasses_thenGetAllNestedClasses() {
|
||||
Set<String> nestMembers = Arrays.stream(Outer.Inner.class.getNestMembers())
|
||||
.map(Class::getName)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
is(nestMembers.size()).equals(2);
|
||||
|
||||
assertTrue(nestMembers.contains("com.baeldung.Outer"));
|
||||
assertTrue(nestMembers.contains("com.baeldung.Outer$Inner"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.optional;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Optional} in Java 11.
|
||||
*/
|
||||
public class OptionalUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenAnEmptyOptional_isEmpty_thenBehavesAsExpected() {
|
||||
Optional<String> opt = Optional.of("Baeldung");
|
||||
assertFalse(opt.isEmpty());
|
||||
|
||||
opt = Optional.ofNullable(null);
|
||||
assertTrue(opt.isEmpty());
|
||||
}
|
||||
}
|
|
@ -15,7 +15,6 @@
|
|||
- [Guide to Java 8 Comparator.comparing()](http://www.baeldung.com/java-8-comparator-comparing)
|
||||
- [Guide To Java 8 Optional](http://www.baeldung.com/java-optional)
|
||||
- [Guide to the Java 8 forEach](http://www.baeldung.com/foreach-java)
|
||||
- [Java Base64 Encoding and Decoding](http://www.baeldung.com/java-base64-encode-and-decode)
|
||||
- [The Difference Between map() and flatMap()](http://www.baeldung.com/java-difference-map-and-flatmap)
|
||||
- [Static and Default Methods in Interfaces in Java](http://www.baeldung.com/java-static-default-methods)
|
||||
- [Efficient Word Frequency Calculator in Java](http://www.baeldung.com/java-word-frequency)
|
||||
|
@ -34,3 +33,8 @@
|
|||
- [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 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)
|
||||
|
|
|
@ -104,6 +104,24 @@
|
|||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>${asspectj.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-module-junit4</artifactId>
|
||||
<version>${powermock.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-mockito2</artifactId>
|
||||
<version>${powermock.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jmockit</groupId>
|
||||
<artifactId>jmockit</artifactId>
|
||||
<version>${jmockit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -119,7 +137,7 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
|
@ -142,6 +160,16 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
<configuration>
|
||||
<argLine>
|
||||
-javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar
|
||||
</argLine>
|
||||
<disableXmlReport>true</disableXmlReport>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -159,9 +187,14 @@
|
|||
<!-- testing -->
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<asspectj.version>1.8.9</asspectj.version>
|
||||
<powermock.version>2.0.0-RC.4</powermock.version>
|
||||
<jmockit.version>1.44</jmockit.version>
|
||||
<avaitility.version>1.7.0</avaitility.version>
|
||||
<jmh-core.version>1.19</jmh-core.version>
|
||||
<jmh-generator.version>1.19</jmh-generator.version>
|
||||
<spring-boot-maven-plugin.version>2.0.4.RELEASE</spring-boot-maven-plugin.version>
|
||||
<!-- plugins -->
|
||||
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
|
||||
<maven-surefire-plugin.version>2.22.1</maven-surefire-plugin.version>
|
||||
</properties>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
package com.baeldung.java8;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class Java8PredicateChainUnitTest {
|
||||
|
||||
private List<String> names = Arrays.asList("Adam", "Alexander", "John", "Tom");
|
||||
|
||||
@Test
|
||||
public void whenFilterList_thenSuccess() {
|
||||
List<String> result = names.stream()
|
||||
.filter(name -> name.startsWith("A"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertEquals(2, result.size());
|
||||
assertThat(result, contains("Adam", "Alexander"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFilterListWithMultipleFilters_thenSuccess() {
|
||||
List<String> result = names.stream()
|
||||
.filter(name -> name.startsWith("A"))
|
||||
.filter(name -> name.length() < 5)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertEquals(1, result.size());
|
||||
assertThat(result, contains("Adam"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFilterListWithComplexPredicate_thenSuccess() {
|
||||
List<String> result = names.stream()
|
||||
.filter(name -> name.startsWith("A") && name.length() < 5)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertEquals(1, result.size());
|
||||
assertThat(result, contains("Adam"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFilterListWithCombinedPredicatesInline_thenSuccess() {
|
||||
List<String> result = names.stream()
|
||||
.filter(((Predicate<String>) name -> name.startsWith("A")).and(name -> name.length() < 5))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertEquals(1, result.size());
|
||||
assertThat(result, contains("Adam"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFilterListWithCombinedPredicatesUsingAnd_thenSuccess() {
|
||||
Predicate<String> predicate1 = str -> str.startsWith("A");
|
||||
Predicate<String> predicate2 = str -> str.length() < 5;
|
||||
|
||||
List<String> result = names.stream()
|
||||
.filter(predicate1.and(predicate2))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertEquals(1, result.size());
|
||||
assertThat(result, contains("Adam"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFilterListWithCombinedPredicatesUsingOr_thenSuccess() {
|
||||
Predicate<String> predicate1 = str -> str.startsWith("J");
|
||||
Predicate<String> predicate2 = str -> str.length() < 4;
|
||||
|
||||
List<String> result = names.stream()
|
||||
.filter(predicate1.or(predicate2))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertEquals(2, result.size());
|
||||
assertThat(result, contains("John", "Tom"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFilterListWithCombinedPredicatesUsingOrAndNegate_thenSuccess() {
|
||||
Predicate<String> predicate1 = str -> str.startsWith("J");
|
||||
Predicate<String> predicate2 = str -> str.length() < 4;
|
||||
|
||||
List<String> result = names.stream()
|
||||
.filter(predicate1.or(predicate2.negate()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertEquals(3, result.size());
|
||||
assertThat(result, contains("Adam", "Alexander", "John"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFilterListWithCollectionOfPredicatesUsingAnd_thenSuccess() {
|
||||
List<Predicate<String>> allPredicates = new ArrayList<Predicate<String>>();
|
||||
allPredicates.add(str -> str.startsWith("A"));
|
||||
allPredicates.add(str -> str.contains("d"));
|
||||
allPredicates.add(str -> str.length() > 4);
|
||||
|
||||
List<String> result = names.stream()
|
||||
.filter(allPredicates.stream()
|
||||
.reduce(x -> true, Predicate::and))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertEquals(1, result.size());
|
||||
assertThat(result, contains("Alexander"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFilterListWithCollectionOfPredicatesUsingOr_thenSuccess() {
|
||||
List<Predicate<String>> allPredicates = new ArrayList<Predicate<String>>();
|
||||
allPredicates.add(str -> str.startsWith("A"));
|
||||
allPredicates.add(str -> str.contains("d"));
|
||||
allPredicates.add(str -> str.length() > 4);
|
||||
|
||||
List<String> result = names.stream()
|
||||
.filter(allPredicates.stream()
|
||||
.reduce(x -> false, Predicate::or))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertEquals(2, result.size());
|
||||
assertThat(result, contains("Adam", "Alexander"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.baeldung.time;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.powermock.api.mockito.PowerMockito.mockStatic;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ Instant.class })
|
||||
public class InstantUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenInstantMock_whenNow_thenGetFixedInstant() {
|
||||
String instantExpected = "2014-12-22T10:15:30Z";
|
||||
Clock clock = Clock.fixed(Instant.parse(instantExpected), ZoneId.of("UTC"));
|
||||
Instant instant = Instant.now(clock);
|
||||
mockStatic(Instant.class);
|
||||
when(Instant.now()).thenReturn(instant);
|
||||
|
||||
Instant now = Instant.now();
|
||||
|
||||
assertThat(now.toString()).isEqualTo(instantExpected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFixedClock_whenNow_thenGetFixedInstant() {
|
||||
String instantExpected = "2014-12-22T10:15:30Z";
|
||||
Clock clock = Clock.fixed(Instant.parse(instantExpected), ZoneId.of("UTC"));
|
||||
|
||||
Instant instant = Instant.now(clock);
|
||||
|
||||
assertThat(instant.toString()).isEqualTo(instantExpected);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.baeldung.time;
|
||||
|
||||
import mockit.Expectations;
|
||||
import mockit.Mock;
|
||||
import mockit.MockUp;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class InstantWithJMockUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenInstantWithJMock_whenNow_thenGetFixedInstant() {
|
||||
String instantExpected = "2014-12-21T10:15:30Z";
|
||||
Clock clock = Clock.fixed(Instant.parse(instantExpected), ZoneId.of("UTC"));
|
||||
new MockUp<Instant>() {
|
||||
@Mock
|
||||
public Instant now() {
|
||||
return Instant.now(clock);
|
||||
}
|
||||
};
|
||||
|
||||
Instant now = Instant.now();
|
||||
|
||||
assertThat(now.toString()).isEqualTo(instantExpected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenInstantWithExpectations_whenNow_thenGetFixedInstant() {
|
||||
Clock clock = Clock.fixed(Instant.parse("2014-12-23T10:15:30.00Z"), ZoneId.of("UTC"));
|
||||
Instant instantExpected = Instant.now(clock);
|
||||
new Expectations(Instant.class) {
|
||||
{
|
||||
Instant.now();
|
||||
result = instantExpected;
|
||||
}
|
||||
};
|
||||
|
||||
Instant now = Instant.now();
|
||||
|
||||
assertThat(now).isEqualTo(instantExpected);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.baeldung.time;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.powermock.api.mockito.PowerMockito.mockStatic;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({ LocalDateTime.class })
|
||||
public class LocalDateTimeUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenLocalDateTimeMock_whenNow_thenGetFixedLocalDateTime() {
|
||||
Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));
|
||||
LocalDateTime dateTime = LocalDateTime.now(clock);
|
||||
mockStatic(LocalDateTime.class);
|
||||
when(LocalDateTime.now()).thenReturn(dateTime);
|
||||
String dateTimeExpected = "2014-12-22T10:15:30";
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
assertThat(now).isEqualTo(dateTimeExpected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFixedClock_whenNow_thenGetFixedLocalDateTime() {
|
||||
Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));
|
||||
String dateTimeExpected = "2014-12-22T10:15:30";
|
||||
|
||||
LocalDateTime dateTime = LocalDateTime.now(clock);
|
||||
|
||||
assertThat(dateTime).isEqualTo(dateTimeExpected);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.baeldung.time;
|
||||
|
||||
import mockit.Expectations;
|
||||
import mockit.Mock;
|
||||
import mockit.MockUp;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class LocalDateTimeWithJMockUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenLocalDateTimeWithJMock_whenNow_thenGetFixedLocalDateTime() {
|
||||
Clock clock = Clock.fixed(Instant.parse("2014-12-21T10:15:30.00Z"), ZoneId.of("UTC"));
|
||||
new MockUp<LocalDateTime>() {
|
||||
@Mock
|
||||
public LocalDateTime now() {
|
||||
return LocalDateTime.now(clock);
|
||||
}
|
||||
};
|
||||
String dateTimeExpected = "2014-12-21T10:15:30";
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
assertThat(now).isEqualTo(dateTimeExpected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLocalDateTimeWithExpectations_whenNow_thenGetFixedLocalDateTime() {
|
||||
Clock clock = Clock.fixed(Instant.parse("2014-12-23T10:15:30.00Z"), ZoneId.of("UTC"));
|
||||
LocalDateTime dateTimeExpected = LocalDateTime.now(clock);
|
||||
new Expectations(LocalDateTime.class) {
|
||||
{
|
||||
LocalDateTime.now();
|
||||
result = dateTimeExpected;
|
||||
}
|
||||
};
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
assertThat(now).isEqualTo(dateTimeExpected);
|
||||
}
|
||||
}
|
|
@ -9,7 +9,6 @@
|
|||
- [Java 9 Convenience Factory Methods for Collections](http://www.baeldung.com/java-9-collections-factory-methods)
|
||||
- [New Stream Collectors in Java 9](http://www.baeldung.com/java9-stream-collectors)
|
||||
- [Java 9 CompletableFuture API Improvements](http://www.baeldung.com/java-9-completablefuture)
|
||||
- [Spring Security – Redirect to the Previous URL After Login](http://www.baeldung.com/spring-security-redirect-login)
|
||||
- [Java 9 Process API Improvements](http://www.baeldung.com/java-9-process-api)
|
||||
- [Introduction to Java 9 StackWalking API](http://www.baeldung.com/java-9-stackwalking-api)
|
||||
- [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity)
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -23,4 +25,14 @@ public class SetExamplesUnitTest {
|
|||
Set<Integer> intSet = Set.of(intArray);
|
||||
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)
|
||||
- [Array Operations in Java](http://www.baeldung.com/java-common-array-operations)
|
||||
- [Intersection Between two Integer Arrays](https://www.baeldung.com/java-array-intersection)
|
||||
- [Sorting Arrays in Java](https://www.baeldung.com/java-sorting-arrays)
|
||||
|
|
|
@ -7,6 +7,14 @@ public class Employee implements Serializable {
|
|||
private int id;
|
||||
private String name;
|
||||
|
||||
public Employee() {
|
||||
}
|
||||
|
||||
public Employee(int id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
package com.baeldung.sort;
|
||||
|
||||
import com.baeldung.arraycopy.model.Employee;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
public class ArraySortUnitTest {
|
||||
private Employee[] employees;
|
||||
private int[] numbers;
|
||||
private String[] strings;
|
||||
|
||||
private Employee john = new Employee(6, "John");
|
||||
private Employee mary = new Employee(3, "Mary");
|
||||
private Employee david = new Employee(4, "David");
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
createEmployeesArray();
|
||||
createNumbersArray();
|
||||
createStringArray();
|
||||
}
|
||||
|
||||
private void createEmployeesArray() {
|
||||
employees = new Employee[]{john, mary, david};
|
||||
}
|
||||
|
||||
private void createNumbersArray() {
|
||||
numbers = new int[]{-8, 7, 5, 9, 10, -2, 3};
|
||||
}
|
||||
|
||||
private void createStringArray() {
|
||||
strings = new String[]{"learning", "java", "with", "baeldung"};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIntArray_whenSortingAscending_thenCorrectlySorted() {
|
||||
Arrays.sort(numbers);
|
||||
|
||||
assertArrayEquals(new int[]{-8, -2, 3, 5, 7, 9, 10}, numbers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIntArray_whenSortingDescending_thenCorrectlySorted() {
|
||||
numbers = IntStream.of(numbers).boxed().sorted(Comparator.reverseOrder()).mapToInt(i -> i).toArray();
|
||||
|
||||
assertArrayEquals(new int[]{10, 9, 7, 5, 3, -2, -8}, numbers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringArray_whenSortingAscending_thenCorrectlySorted() {
|
||||
Arrays.sort(strings);
|
||||
|
||||
assertArrayEquals(new String[]{"baeldung", "java", "learning", "with"}, strings);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringArray_whenSortingDescending_thenCorrectlySorted() {
|
||||
Arrays.sort(strings, Comparator.reverseOrder());
|
||||
|
||||
assertArrayEquals(new String[]{"with", "learning", "java", "baeldung"}, strings);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenObjectArray_whenSortingAscending_thenCorrectlySorted() {
|
||||
Arrays.sort(employees, Comparator.comparing(Employee::getName));
|
||||
|
||||
assertArrayEquals(new Employee[]{david, john, mary}, employees);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenObjectArray_whenSortingDescending_thenCorrectlySorted() {
|
||||
Arrays.sort(employees, Comparator.comparing(Employee::getName).reversed());
|
||||
|
||||
assertArrayEquals(new Employee[]{mary, john, david}, employees);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenObjectArray_whenSortingMultipleAttributesAscending_thenCorrectlySorted() {
|
||||
Arrays.sort(employees, Comparator.comparing(Employee::getName).thenComparing(Employee::getId));
|
||||
|
||||
assertArrayEquals(new Employee[]{david, john, mary}, employees);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
=========
|
||||
|
||||
## Core Java Collections List Cookbooks and Examples
|
||||
|
||||
### Relevant Articles:
|
||||
- [Immutable ArrayList in Java](http://www.baeldung.com/java-immutable-list)
|
||||
- [Guide to the Java ArrayList](http://www.baeldung.com/java-arraylist)
|
||||
- [Random List Element](http://www.baeldung.com/java-random-list-element)
|
||||
- [Removing all nulls from a List in Java](http://www.baeldung.com/java-remove-nulls-from-list)
|
||||
- [Removing all duplicates from a List in Java](http://www.baeldung.com/java-remove-duplicates-from-list)
|
||||
- [How to TDD a List Implementation in Java](http://www.baeldung.com/java-test-driven-list)
|
||||
- [Iterating Backward Through a List](http://www.baeldung.com/java-list-iterate-backwards)
|
||||
- [Add Multiple Items to an Java ArrayList](http://www.baeldung.com/java-add-items-array-list)
|
||||
- [Remove the First Element from a List](http://www.baeldung.com/java-remove-first-element-from-list)
|
||||
- [How to Find an Element in a List with Java](http://www.baeldung.com/find-list-element-java)
|
||||
- [Copy a List to Another List in Java](http://www.baeldung.com/java-copy-list-to-another)
|
||||
- [Finding Max/Min of a List or Collection](http://www.baeldung.com/java-collection-min-max)
|
||||
- [Collections.emptyList() vs. New List Instance](https://www.baeldung.com/java-collections-emptylist-new-list)
|
||||
- [Remove All Occurrences of a Specific Value from a List](https://www.baeldung.com/java-remove-value-from-list)
|
||||
- [Check If Two Lists are Equal in Java](http://www.baeldung.com/java-test-a-list-for-ordinality-and-equality)
|
||||
- [Java 8 Streams: Find Items From One List Based On Values From Another List](https://www.baeldung.com/java-streams-find-list-items)
|
||||
- [A Guide to the Java LinkedList](http://www.baeldung.com/java-linkedlist)
|
||||
- [Java List UnsupportedOperationException](http://www.baeldung.com/java-list-unsupported-operation-exception)
|
||||
- [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)
|
||||
- [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)
|
||||
- [Intersection of Two Lists in Java](https://www.baeldung.com/java-lists-intersection)
|
|
@ -0,0 +1,48 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-collections-list</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-collections-list</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-java</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections4.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<commons-collections4.version>4.1</commons-collections4.version>
|
||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||
<avaitility.version>1.7.0</avaitility.version>
|
||||
<assertj.version>3.11.1</assertj.version>
|
||||
<lombok.version>1.16.12</lombok.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -6,30 +6,29 @@ public class ArrayListOfArrayList {
|
|||
|
||||
public static void main(String args[]) {
|
||||
|
||||
int vertex = 5;
|
||||
ArrayList<ArrayList<Integer>> graph = new ArrayList<>(vertex);
|
||||
int vertexCount = 3;
|
||||
ArrayList<ArrayList<Integer>> graph = new ArrayList<>(vertexCount);
|
||||
|
||||
//Initializing each element of ArrayList with ArrayList
|
||||
for(int i=0; i< vertex; i++) {
|
||||
for(int i = 0; i< vertexCount; i++) {
|
||||
graph.add(new ArrayList<Integer>());
|
||||
}
|
||||
|
||||
//We can add any number of columns to each row
|
||||
graph.get(0).add(1);
|
||||
graph.get(0).add(5);
|
||||
graph.get(1).add(0);
|
||||
graph.get(1).add(2);
|
||||
graph.get(2).add(0);
|
||||
graph.get(1).add(0);
|
||||
graph.get(2).add(1);
|
||||
graph.get(2).add(3);
|
||||
graph.get(3).add(2);
|
||||
graph.get(3).add(4);
|
||||
graph.get(4).add(3);
|
||||
graph.get(4).add(5);
|
||||
graph.get(0).add(2);
|
||||
|
||||
//Printing all the edges
|
||||
for(int i=0; i<vertex; i++) {
|
||||
for(int j=0; j<graph.get(i).size(); j++) {
|
||||
System.out.println("Edge between vertex "+i+"and "+graph.get(i).get(j));
|
||||
vertexCount = graph.size();
|
||||
for(int i = 0; i < vertexCount; i++) {
|
||||
int edgeCount = graph.get(i).size();
|
||||
for(int j = 0; j < edgeCount; j++) {
|
||||
Integer startVertex = i;
|
||||
Integer endVertex = graph.get(i).get(j);
|
||||
System.out.printf("Vertex %d is connected to vertex %d%n", startVertex, endVertex);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,17 +20,17 @@ public class ThreeDimensionalArrayList {
|
|||
}
|
||||
|
||||
//Set Red color for points (0,0,0) and (0,0,1)
|
||||
space.get(0).get(0).add("Red");
|
||||
space.get(0).get(0).add("Red");
|
||||
space.get(0).get(0).add(0,"Red");
|
||||
space.get(0).get(0).add(1,"Red");
|
||||
//Set Blue color for points (0,1,0) and (0,1,1)
|
||||
space.get(0).get(1).add("Blue");
|
||||
space.get(0).get(1).add("Blue");
|
||||
space.get(0).get(1).add(0,"Blue");
|
||||
space.get(0).get(1).add(1,"Blue");
|
||||
//Set Green color for points (1,0,0) and (1,0,1)
|
||||
space.get(1).get(0).add("Green");
|
||||
space.get(1).get(0).add("Green");
|
||||
space.get(1).get(0).add(0,"Green");
|
||||
space.get(1).get(0).add(1,"Green");
|
||||
//Set Yellow color for points (1,1,0) and (1,1,1)
|
||||
space.get(1).get(1).add("Yellow");
|
||||
space.get(1).get(1).add("Yellow");
|
||||
space.get(1).get(1).add(0,"Yellow");
|
||||
space.get(1).get(1).add(1,"Yellow");
|
||||
|
||||
//Printing colors for all the points
|
||||
for(int i = 0; i < x_axis_length; i++) {
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue