[BAEL-2533] fix merge conflict
This commit is contained in:
commit
ffe2f46267
|
@ -66,3 +66,10 @@ jmeter/src/main/resources/*-JMeter.csv
|
||||||
**/nb-configuration.xml
|
**/nb-configuration.xml
|
||||||
core-scala/.cache-main
|
core-scala/.cache-main
|
||||||
core-scala/.cache-tests
|
core-scala/.cache-tests
|
||||||
|
|
||||||
|
|
||||||
|
persistence-modules/hibernate5/transaction.log
|
||||||
|
apache-avro/src/main/java/com/baeldung/avro/model/
|
||||||
|
jta/transaction-logs/
|
||||||
|
software-security/sql-injection-samples/derby.log
|
||||||
|
spring-soap/src/main/java/com/baeldung/springsoap/gen/
|
|
@ -5,9 +5,9 @@
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>JGit</artifactId>
|
<artifactId>JGit</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>JGit</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<url>http://maven.apache.org</url>
|
<url>http://maven.apache.org</url>
|
||||||
<name>JGit</name>
|
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
|
|
|
@ -14,7 +14,7 @@ Java and Spring Tutorials
|
||||||
================
|
================
|
||||||
|
|
||||||
This project is **a collection of small and focused tutorials** - each covering a single and well defined area of development in the Java ecosystem.
|
This project is **a collection of small and focused tutorials** - each covering a single and well defined area of development in the Java ecosystem.
|
||||||
A strong focus of these is, of course, the Spring Framework - Spring, Spring Boot and Spring Securiyt.
|
A strong focus of these is, of course, the Spring Framework - Spring, Spring Boot and Spring Security.
|
||||||
In additional to Spring, the following technologies are in focus: `core Java`, `Jackson`, `HttpClient`, `Guava`.
|
In additional to Spring, the following technologies are in focus: `core Java`, `Jackson`, `HttpClient`, `Guava`.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>Twitter4J</artifactId>
|
<artifactId>Twitter4J</artifactId>
|
||||||
<packaging>jar</packaging>
|
|
||||||
<name>Twitter4J</name>
|
<name>Twitter4J</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
|
|
|
@ -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>${akka.stream.version}</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\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -10,4 +10,10 @@
|
||||||
- [Multi-Swarm Optimization Algorithm in Java](http://www.baeldung.com/java-multi-swarm-algorithm)
|
- [Multi-Swarm Optimization Algorithm in Java](http://www.baeldung.com/java-multi-swarm-algorithm)
|
||||||
- [String Search Algorithms for Large Texts](http://www.baeldung.com/java-full-text-search-algorithms)
|
- [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)
|
- [Check If a String Contains All The Letters of The Alphabet](https://www.baeldung.com/java-string-contains-all-letters)
|
||||||
- [Find the Middle Element of a Linked List](http://www.baeldung.com/java-linked-list-middle-element)
|
- [Find the Middle Element of a Linked List](http://www.baeldung.com/java-linked-list-middle-element)
|
||||||
|
- [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial)
|
||||||
|
- [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)
|
||||||
|
- [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations)
|
||||||
|
- [Implementing Simple State Machines with Java Enums](https://www.baeldung.com/java-enum-simple-state-machine)
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.baeldung.algorithms.enumstatemachine;
|
||||||
|
|
||||||
|
public enum LeaveRequestState {
|
||||||
|
|
||||||
|
Submitted {
|
||||||
|
@Override
|
||||||
|
public LeaveRequestState nextState() {
|
||||||
|
System.out.println("Starting the Leave Request and sending to Team Leader for approval.");
|
||||||
|
return Escalated;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String responsiblePerson() {
|
||||||
|
return "Employee";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Escalated {
|
||||||
|
@Override
|
||||||
|
public LeaveRequestState nextState() {
|
||||||
|
System.out.println("Reviewing the Leave Request and escalating to Department Manager.");
|
||||||
|
return Approved;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String responsiblePerson() {
|
||||||
|
return "Team Leader";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Approved {
|
||||||
|
@Override
|
||||||
|
public LeaveRequestState nextState() {
|
||||||
|
System.out.println("Approving the Leave Request.");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String responsiblePerson() {
|
||||||
|
return "Department Manager";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public abstract String responsiblePerson();
|
||||||
|
|
||||||
|
public abstract LeaveRequestState nextState();
|
||||||
|
|
||||||
|
}
|
|
@ -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, ';');
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung.string;
|
package com.baeldung.algorithms.string;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
|
@ -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.enumstatemachine;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class LeaveRequestStateUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLeaveRequest_whenStateEscalated_thenResponsibleIsTeamLeader() {
|
||||||
|
LeaveRequestState state = LeaveRequestState.Escalated;
|
||||||
|
|
||||||
|
assertEquals(state.responsiblePerson(), "Team Leader");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLeaveRequest_whenStateApproved_thenResponsibleIsDepartmentManager() {
|
||||||
|
LeaveRequestState state = LeaveRequestState.Approved;
|
||||||
|
|
||||||
|
assertEquals(state.responsiblePerson(), "Department Manager");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLeaveRequest_whenNextStateIsCalled_thenStateIsChanged() {
|
||||||
|
LeaveRequestState state = LeaveRequestState.Submitted;
|
||||||
|
|
||||||
|
state = state.nextState();
|
||||||
|
assertEquals(state, LeaveRequestState.Escalated);
|
||||||
|
|
||||||
|
state = state.nextState();
|
||||||
|
assertEquals(state, LeaveRequestState.Approved);
|
||||||
|
|
||||||
|
state = state.nextState();
|
||||||
|
assertEquals(state, LeaveRequestState.Approved);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung.string;
|
package com.baeldung.algorithms.string;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -33,6 +33,11 @@
|
||||||
<artifactId>jgrapht-core</artifactId>
|
<artifactId>jgrapht-core</artifactId>
|
||||||
<version>${org.jgrapht.core.version}</version>
|
<version>${org.jgrapht.core.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jgrapht</groupId>
|
||||||
|
<artifactId>jgrapht-ext</artifactId>
|
||||||
|
<version>${org.jgrapht.ext.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>pl.allegro.finance</groupId>
|
<groupId>pl.allegro.finance</groupId>
|
||||||
<artifactId>tradukisto</artifactId>
|
<artifactId>tradukisto</artifactId>
|
||||||
|
@ -63,7 +68,7 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>cobertura-maven-plugin</artifactId>
|
<artifactId>cobertura-maven-plugin</artifactId>
|
||||||
<version>2.7</version>
|
<version>${cobertura-maven-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<instrumentation>
|
<instrumentation>
|
||||||
<ignores>
|
<ignores>
|
||||||
|
@ -83,8 +88,10 @@
|
||||||
<commons-math3.version>3.6.1</commons-math3.version>
|
<commons-math3.version>3.6.1</commons-math3.version>
|
||||||
<tradukisto.version>1.0.1</tradukisto.version>
|
<tradukisto.version>1.0.1</tradukisto.version>
|
||||||
<org.jgrapht.core.version>1.0.1</org.jgrapht.core.version>
|
<org.jgrapht.core.version>1.0.1</org.jgrapht.core.version>
|
||||||
|
<org.jgrapht.ext.version>1.0.1</org.jgrapht.ext.version>
|
||||||
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||||
<commons-codec.version>1.11</commons-codec.version>
|
<commons-codec.version>1.11</commons-codec.version>
|
||||||
|
<cobertura-maven-plugin.version>2.7</cobertura-maven-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.baeldung.jgrapht;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import org.jgrapht.ext.JGraphXAdapter;
|
||||||
|
import org.jgrapht.graph.DefaultDirectedGraph;
|
||||||
|
import org.jgrapht.graph.DefaultEdge;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import com.mxgraph.layout.mxCircleLayout;
|
||||||
|
import com.mxgraph.layout.mxIGraphLayout;
|
||||||
|
import com.mxgraph.util.mxCellRenderer;
|
||||||
|
|
||||||
|
public class GraphImageGenerationUnitTest {
|
||||||
|
static DefaultDirectedGraph<String, DefaultEdge> g;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void createGraph() throws IOException {
|
||||||
|
File imgFile = new File("src/test/resources/graph.png");
|
||||||
|
imgFile.createNewFile();
|
||||||
|
g = new DefaultDirectedGraph<String, DefaultEdge>(DefaultEdge.class);
|
||||||
|
String x1 = "x1";
|
||||||
|
String x2 = "x2";
|
||||||
|
String x3 = "x3";
|
||||||
|
g.addVertex(x1);
|
||||||
|
g.addVertex(x2);
|
||||||
|
g.addVertex(x3);
|
||||||
|
g.addEdge(x1, x2);
|
||||||
|
g.addEdge(x2, x3);
|
||||||
|
g.addEdge(x3, x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAdaptedGraph_whenWriteBufferedImage_ThenFileShouldExist() throws IOException {
|
||||||
|
JGraphXAdapter<String, DefaultEdge> graphAdapter = new JGraphXAdapter<String, DefaultEdge>(g);
|
||||||
|
mxIGraphLayout layout = new mxCircleLayout(graphAdapter);
|
||||||
|
layout.execute(graphAdapter.getDefaultParent());
|
||||||
|
File imgFile = new File("src/test/resources/graph.png");
|
||||||
|
BufferedImage image = mxCellRenderer.createBufferedImage(graphAdapter, null, 2, Color.WHITE, true, null);
|
||||||
|
ImageIO.write(image, "PNG", imgFile);
|
||||||
|
assertTrue(imgFile.exists());
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
|
@ -34,7 +34,7 @@ public class MergeSort {
|
||||||
|
|
||||||
while (i < left && j < right) {
|
while (i < left && j < right) {
|
||||||
|
|
||||||
if (l[i] < r[j])
|
if (l[i] <= r[j])
|
||||||
a[k++] = l[i++];
|
a[k++] = l[i++];
|
||||||
else
|
else
|
||||||
a[k++] = r[j++];
|
a[k++] = r[j++];
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>animal-sniffer-mvn-plugin</artifactId>
|
<artifactId>animal-sniffer-mvn-plugin</artifactId>
|
||||||
<packaging>jar</packaging>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<name>animal-sniffer-mvn-plugin</name>
|
<name>animal-sniffer-mvn-plugin</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
<url>http://maven.apache.org</url>
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>annotations</artifactId>
|
<artifactId>annotations</artifactId>
|
||||||
<packaging>pom</packaging>
|
|
||||||
<name>annotations</name>
|
<name>annotations</name>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent-modules</artifactId>
|
<artifactId>parent-modules</artifactId>
|
||||||
|
|
|
@ -7,14 +7,6 @@
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<name>apache-avro</name>
|
<name>apache-avro</name>
|
||||||
|
|
||||||
<properties>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<compiler-plugin.version>3.5</compiler-plugin.version>
|
|
||||||
<avro.version>1.8.2</avro.version>
|
|
||||||
<java.version>1.8</java.version>
|
|
||||||
<slf4j.version>1.7.25</slf4j.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>parent-modules</artifactId>
|
<artifactId>parent-modules</artifactId>
|
||||||
|
@ -85,4 +77,13 @@
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<compiler-plugin.version>3.5</compiler-plugin.version>
|
||||||
|
<avro.version>1.8.2</avro.version>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<slf4j.version>1.7.25</slf4j.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>apache-curator</artifactId>
|
<artifactId>apache-curator</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
|
||||||
<name>apache-curator</name>
|
<name>apache-curator</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
<properties>
|
<properties>
|
||||||
<curator.version>4.0.1</curator.version>
|
<curator.version>4.0.1</curator.version>
|
||||||
<zookeeper.version>3.4.11</zookeeper.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 -->
|
<!-- testing -->
|
||||||
<assertj.version>3.6.1</assertj.version>
|
<assertj.version>3.6.1</assertj.version>
|
||||||
<avaitility.version>1.7.0</avaitility.version>
|
<avaitility.version>1.7.0</avaitility.version>
|
||||||
|
|
|
@ -12,22 +12,6 @@
|
||||||
<artifactId>parent-modules</artifactId>
|
<artifactId>parent-modules</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
|
||||||
<geode.core>1.6.0</geode.core>
|
|
||||||
</properties>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<source>1.8</source>
|
|
||||||
<target>1.8</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -38,8 +22,26 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>RELEASE</version>
|
<version>${junit.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>${maven.compiler.source}</source>
|
||||||
|
<target>${maven.compiler.target}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<geode.core>1.6.0</geode.core>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
</project>
|
</project>
|
|
@ -7,51 +7,58 @@
|
||||||
<name>apache-meecrowave</name>
|
<name>apache-meecrowave</name>
|
||||||
<description>A sample REST API application with Meecrowave</description>
|
<description>A sample REST API application with Meecrowave</description>
|
||||||
|
|
||||||
<properties>
|
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
|
||||||
</properties>
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- https://mvnrepository.com/artifact/org.apache.meecrowave/meecrowave-core -->
|
<!-- https://mvnrepository.com/artifact/org.apache.meecrowave/meecrowave-core -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.meecrowave</groupId>
|
<groupId>org.apache.meecrowave</groupId>
|
||||||
<artifactId>meecrowave-core</artifactId>
|
<artifactId>meecrowave-core</artifactId>
|
||||||
<version>1.2.1</version>
|
<version>${meecrowave-core.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.apache.meecrowave/meecrowave-jpa -->
|
<!-- https://mvnrepository.com/artifact/org.apache.meecrowave/meecrowave-jpa -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.meecrowave</groupId>
|
<groupId>org.apache.meecrowave</groupId>
|
||||||
<artifactId>meecrowave-jpa</artifactId>
|
<artifactId>meecrowave-jpa</artifactId>
|
||||||
<version>1.2.1</version>
|
<version>${meecrowave-jpa.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.squareup.okhttp3</groupId>
|
<groupId>com.squareup.okhttp3</groupId>
|
||||||
<artifactId>okhttp</artifactId>
|
<artifactId>okhttp</artifactId>
|
||||||
<version>3.10.0</version>
|
<version>${okhttp.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.meecrowave</groupId>
|
<groupId>org.apache.meecrowave</groupId>
|
||||||
<artifactId>meecrowave-junit</artifactId>
|
<artifactId>meecrowave-junit</artifactId>
|
||||||
<version>1.2.0</version>
|
<version>${meecrowave-junit.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/junit/junit -->
|
<!-- https://mvnrepository.com/artifact/junit/junit -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.10</version>
|
<version>${junit.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.meecrowave</groupId>
|
<groupId>org.apache.meecrowave</groupId>
|
||||||
<artifactId>meecrowave-maven-plugin</artifactId>
|
<artifactId>meecrowave-maven-plugin</artifactId>
|
||||||
<version>1.2.1</version>
|
<version>${meecrowave-maven-plugin.version}</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<junit.version>4.10</junit.version>
|
||||||
|
<meecrowave-junit.version>1.2.0</meecrowave-junit.version>
|
||||||
|
<okhttp.version>3.10.0</okhttp.version>
|
||||||
|
<meecrowave-jpa.version>1.2.1</meecrowave-jpa.version>
|
||||||
|
<meecrowave-core.version>1.2.1</meecrowave-core.version>
|
||||||
|
<meecrowave-maven-plugin.version>1.2.1</meecrowave-maven-plugin.version>
|
||||||
|
</properties>
|
||||||
</project>
|
</project>
|
|
@ -11,12 +11,14 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.pulsar</groupId>
|
<groupId>org.apache.pulsar</groupId>
|
||||||
<artifactId>pulsar-client</artifactId>
|
<artifactId>pulsar-client</artifactId>
|
||||||
<version>2.1.1-incubating</version>
|
<version>${pulsar-client.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<pulsar-client.version>2.1.1-incubating</pulsar-client.version>
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>apache-solrj</artifactId>
|
<artifactId>apache-solrj</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
|
||||||
<name>apache-solrj</name>
|
<name>apache-solrj</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
### Relevant articles
|
### Relevant articles
|
||||||
|
|
||||||
- [Introduction to Apache Spark](http://www.baeldung.com/apache-spark)
|
- [Introduction to Apache Spark](http://www.baeldung.com/apache-spark)
|
||||||
|
- [Building a Data Pipeline with Kafka, Spark Streaming and Cassandra](https://www.baeldung.com/kafka-spark-data-pipeline)
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>apache-spark</artifactId>
|
<artifactId>apache-spark</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
|
||||||
<name>apache-spark</name>
|
<name>apache-spark</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
<url>http://maven.apache.org</url>
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
@ -15,16 +15,79 @@
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-core_2.10 -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.spark</groupId>
|
<groupId>org.apache.spark</groupId>
|
||||||
<artifactId>spark-core_2.10</artifactId>
|
<artifactId>spark-core_2.11</artifactId>
|
||||||
<version>${org.apache.spark.spark-core.version}</version>
|
<version>${org.apache.spark.spark-core.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.spark</groupId>
|
||||||
|
<artifactId>spark-sql_2.11</artifactId>
|
||||||
|
<version>${org.apache.spark.spark-sql.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.spark</groupId>
|
||||||
|
<artifactId>spark-streaming_2.11</artifactId>
|
||||||
|
<version>${org.apache.spark.spark-streaming.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.spark</groupId>
|
||||||
|
<artifactId>spark-streaming-kafka-0-10_2.11</artifactId>
|
||||||
|
<version>${org.apache.spark.spark-streaming-kafka.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.datastax.spark</groupId>
|
||||||
|
<artifactId>spark-cassandra-connector_2.11</artifactId>
|
||||||
|
<version>${com.datastax.spark.spark-cassandra-connector.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.datastax.spark</groupId>
|
||||||
|
<artifactId>spark-cassandra-connector-java_2.11</artifactId>
|
||||||
|
<version>${com.datastax.spark.spark-cassandra-connector-java.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${maven.compiler.source}</source>
|
||||||
|
<target>${maven.compiler.target}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
<properties>
|
<properties>
|
||||||
<org.apache.spark.spark-core.version>2.2.0</org.apache.spark.spark-core.version>
|
<org.apache.spark.spark-core.version>2.3.0</org.apache.spark.spark-core.version>
|
||||||
|
<org.apache.spark.spark-sql.version>2.3.0</org.apache.spark.spark-sql.version>
|
||||||
|
<org.apache.spark.spark-streaming.version>2.3.0</org.apache.spark.spark-streaming.version>
|
||||||
|
<org.apache.spark.spark-streaming-kafka.version>2.3.0</org.apache.spark.spark-streaming-kafka.version>
|
||||||
|
<com.datastax.spark.spark-cassandra-connector.version>2.3.0</com.datastax.spark.spark-cassandra-connector.version>
|
||||||
|
<com.datastax.spark.spark-cassandra-connector-java.version>1.5.2</com.datastax.spark.spark-cassandra-connector-java.version>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<maven-compiler-plugin.version>3.2</maven-compiler-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.data.pipeline;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class Word implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private String word;
|
||||||
|
private int count;
|
||||||
|
Word(String word, int count) {
|
||||||
|
this.word = word;
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
public String getWord() {
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
public void setWord(String word) {
|
||||||
|
this.word = word;
|
||||||
|
}
|
||||||
|
public int getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
public void setCount(int count) {
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package com.baeldung.data.pipeline;
|
||||||
|
|
||||||
|
import static com.datastax.spark.connector.japi.CassandraJavaUtil.javaFunctions;
|
||||||
|
import static com.datastax.spark.connector.japi.CassandraJavaUtil.mapToRow;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
|
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.apache.spark.SparkConf;
|
||||||
|
import org.apache.spark.api.java.JavaRDD;
|
||||||
|
import org.apache.spark.streaming.Durations;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaInputDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaPairDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaStreamingContext;
|
||||||
|
import org.apache.spark.streaming.kafka010.ConsumerStrategies;
|
||||||
|
import org.apache.spark.streaming.kafka010.KafkaUtils;
|
||||||
|
import org.apache.spark.streaming.kafka010.LocationStrategies;
|
||||||
|
|
||||||
|
import scala.Tuple2;
|
||||||
|
|
||||||
|
public class WordCountingApp {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
Logger.getLogger("org")
|
||||||
|
.setLevel(Level.OFF);
|
||||||
|
Logger.getLogger("akka")
|
||||||
|
.setLevel(Level.OFF);
|
||||||
|
|
||||||
|
Map<String, Object> kafkaParams = new HashMap<>();
|
||||||
|
kafkaParams.put("bootstrap.servers", "localhost:9092");
|
||||||
|
kafkaParams.put("key.deserializer", StringDeserializer.class);
|
||||||
|
kafkaParams.put("value.deserializer", StringDeserializer.class);
|
||||||
|
kafkaParams.put("group.id", "use_a_separate_group_id_for_each_stream");
|
||||||
|
kafkaParams.put("auto.offset.reset", "latest");
|
||||||
|
kafkaParams.put("enable.auto.commit", false);
|
||||||
|
|
||||||
|
Collection<String> topics = Arrays.asList("messages");
|
||||||
|
|
||||||
|
SparkConf sparkConf = new SparkConf();
|
||||||
|
sparkConf.setMaster("local[2]");
|
||||||
|
sparkConf.setAppName("WordCountingApp");
|
||||||
|
sparkConf.set("spark.cassandra.connection.host", "127.0.0.1");
|
||||||
|
|
||||||
|
JavaStreamingContext streamingContext = new JavaStreamingContext(sparkConf, Durations.seconds(1));
|
||||||
|
|
||||||
|
JavaInputDStream<ConsumerRecord<String, String>> messages = KafkaUtils.createDirectStream(streamingContext, LocationStrategies.PreferConsistent(), ConsumerStrategies.<String, String> Subscribe(topics, kafkaParams));
|
||||||
|
|
||||||
|
JavaPairDStream<String, String> results = messages.mapToPair(record -> new Tuple2<>(record.key(), record.value()));
|
||||||
|
|
||||||
|
JavaDStream<String> lines = results.map(tuple2 -> tuple2._2());
|
||||||
|
|
||||||
|
JavaDStream<String> words = lines.flatMap(x -> Arrays.asList(x.split("\\s+"))
|
||||||
|
.iterator());
|
||||||
|
|
||||||
|
JavaPairDStream<String, Integer> wordCounts = words.mapToPair(s -> new Tuple2<>(s, 1))
|
||||||
|
.reduceByKey((i1, i2) -> i1 + i2);
|
||||||
|
|
||||||
|
wordCounts.foreachRDD(javaRdd -> {
|
||||||
|
Map<String, Integer> wordCountMap = javaRdd.collectAsMap();
|
||||||
|
for (String key : wordCountMap.keySet()) {
|
||||||
|
List<Word> wordList = Arrays.asList(new Word(key, wordCountMap.get(key)));
|
||||||
|
JavaRDD<Word> rdd = streamingContext.sparkContext()
|
||||||
|
.parallelize(wordList);
|
||||||
|
javaFunctions(rdd).writerBuilder("vocabulary", "words", mapToRow(Word.class))
|
||||||
|
.saveToCassandra();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
streamingContext.start();
|
||||||
|
streamingContext.awaitTermination();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package com.baeldung.data.pipeline;
|
||||||
|
|
||||||
|
import static com.datastax.spark.connector.japi.CassandraJavaUtil.javaFunctions;
|
||||||
|
import static com.datastax.spark.connector.japi.CassandraJavaUtil.mapToRow;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
|
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.apache.spark.SparkConf;
|
||||||
|
import org.apache.spark.api.java.JavaRDD;
|
||||||
|
import org.apache.spark.api.java.JavaSparkContext;
|
||||||
|
import org.apache.spark.api.java.function.Function2;
|
||||||
|
import org.apache.spark.streaming.Durations;
|
||||||
|
import org.apache.spark.streaming.StateSpec;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaInputDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaMapWithStateDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaPairDStream;
|
||||||
|
import org.apache.spark.streaming.api.java.JavaStreamingContext;
|
||||||
|
import org.apache.spark.streaming.kafka010.ConsumerStrategies;
|
||||||
|
import org.apache.spark.streaming.kafka010.KafkaUtils;
|
||||||
|
import org.apache.spark.streaming.kafka010.LocationStrategies;
|
||||||
|
|
||||||
|
import scala.Tuple2;
|
||||||
|
|
||||||
|
public class WordCountingAppWithCheckpoint {
|
||||||
|
|
||||||
|
public static JavaSparkContext sparkContext;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
|
||||||
|
Logger.getLogger("org")
|
||||||
|
.setLevel(Level.OFF);
|
||||||
|
Logger.getLogger("akka")
|
||||||
|
.setLevel(Level.OFF);
|
||||||
|
|
||||||
|
Map<String, Object> kafkaParams = new HashMap<>();
|
||||||
|
kafkaParams.put("bootstrap.servers", "localhost:9092");
|
||||||
|
kafkaParams.put("key.deserializer", StringDeserializer.class);
|
||||||
|
kafkaParams.put("value.deserializer", StringDeserializer.class);
|
||||||
|
kafkaParams.put("group.id", "use_a_separate_group_id_for_each_stream");
|
||||||
|
kafkaParams.put("auto.offset.reset", "latest");
|
||||||
|
kafkaParams.put("enable.auto.commit", false);
|
||||||
|
|
||||||
|
Collection<String> topics = Arrays.asList("messages");
|
||||||
|
|
||||||
|
SparkConf sparkConf = new SparkConf();
|
||||||
|
sparkConf.setMaster("local[2]");
|
||||||
|
sparkConf.setAppName("WordCountingAppWithCheckpoint");
|
||||||
|
sparkConf.set("spark.cassandra.connection.host", "127.0.0.1");
|
||||||
|
|
||||||
|
JavaStreamingContext streamingContext = new JavaStreamingContext(sparkConf, Durations.seconds(1));
|
||||||
|
|
||||||
|
sparkContext = streamingContext.sparkContext();
|
||||||
|
|
||||||
|
streamingContext.checkpoint("./.checkpoint");
|
||||||
|
|
||||||
|
JavaInputDStream<ConsumerRecord<String, String>> messages = KafkaUtils.createDirectStream(streamingContext, LocationStrategies.PreferConsistent(), ConsumerStrategies.<String, String> Subscribe(topics, kafkaParams));
|
||||||
|
|
||||||
|
JavaPairDStream<String, String> results = messages.mapToPair(record -> new Tuple2<>(record.key(), record.value()));
|
||||||
|
|
||||||
|
JavaDStream<String> lines = results.map(tuple2 -> tuple2._2());
|
||||||
|
|
||||||
|
JavaDStream<String> words = lines.flatMap(x -> Arrays.asList(x.split("\\s+"))
|
||||||
|
.iterator());
|
||||||
|
|
||||||
|
JavaPairDStream<String, Integer> wordCounts = words.mapToPair(s -> new Tuple2<>(s, 1))
|
||||||
|
.reduceByKey((Function2<Integer, Integer, Integer>) (i1, i2) -> i1 + i2);
|
||||||
|
|
||||||
|
JavaMapWithStateDStream<String, Integer, Integer, Tuple2<String, Integer>> cumulativeWordCounts = wordCounts.mapWithState(StateSpec.function((word, one, state) -> {
|
||||||
|
int sum = one.orElse(0) + (state.exists() ? state.get() : 0);
|
||||||
|
Tuple2<String, Integer> output = new Tuple2<>(word, sum);
|
||||||
|
state.update(sum);
|
||||||
|
return output;
|
||||||
|
}));
|
||||||
|
|
||||||
|
cumulativeWordCounts.foreachRDD(javaRdd -> {
|
||||||
|
List<Tuple2<String, Integer>> wordCountList = javaRdd.collect();
|
||||||
|
for (Tuple2<String, Integer> tuple : wordCountList) {
|
||||||
|
List<Word> wordList = Arrays.asList(new Word(tuple._1, tuple._2));
|
||||||
|
JavaRDD<Word> rdd = sparkContext.parallelize(wordList);
|
||||||
|
javaFunctions(rdd).writerBuilder("vocabulary", "words", mapToRow(Word.class))
|
||||||
|
.saveToCassandra();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
streamingContext.start();
|
||||||
|
streamingContext.awaitTermination();
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,8 +4,8 @@
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<version>0.1-SNAPSHOT</version>
|
<version>0.1-SNAPSHOT</version>
|
||||||
<artifactId>apache-velocity</artifactId>
|
<artifactId>apache-velocity</artifactId>
|
||||||
<packaging>war</packaging>
|
|
||||||
<name>apache-velocity</name>
|
<name>apache-velocity</name>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>aws-lambda</artifactId>
|
<artifactId>aws-lambda</artifactId>
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
|
||||||
<name>aws-lambda</name>
|
<name>aws-lambda</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent-modules</artifactId>
|
<artifactId>parent-modules</artifactId>
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>aws</artifactId>
|
<artifactId>aws</artifactId>
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
|
||||||
<name>aws</name>
|
<name>aws</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
|
|
46
axon/pom.xml
46
axon/pom.xml
|
@ -4,29 +4,61 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>axon</artifactId>
|
<artifactId>axon</artifactId>
|
||||||
<name>axon</name>
|
<name>axon</name>
|
||||||
|
<description>Basic Axon Framework with Spring Boot configuration tutorial</description>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent-modules</artifactId>
|
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<artifactId>parent-boot-2</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-boot-2</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.axonframework</groupId>
|
||||||
|
<artifactId>axon-spring-boot-starter</artifactId>
|
||||||
|
<version>${axon.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.axonframework</groupId>
|
||||||
|
<artifactId>axon-server-connector</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.axonframework</groupId>
|
<groupId>org.axonframework</groupId>
|
||||||
<artifactId>axon-test</artifactId>
|
<artifactId>axon-test</artifactId>
|
||||||
<version>${axon.version}</version>
|
<version>${axon.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.axonframework</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>axon-core</artifactId>
|
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||||
<version>${axon.version}</version>
|
<version>${spring-boot.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<axon.version>3.0.2</axon.version>
|
<axon.version>4.0.3</axon.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -1,54 +0,0 @@
|
||||||
package com.baeldung.axon;
|
|
||||||
|
|
||||||
import com.baeldung.axon.aggregates.MessagesAggregate;
|
|
||||||
import com.baeldung.axon.commands.CreateMessageCommand;
|
|
||||||
import com.baeldung.axon.commands.MarkReadMessageCommand;
|
|
||||||
import com.baeldung.axon.eventhandlers.MessagesEventHandler;
|
|
||||||
import org.axonframework.commandhandling.AggregateAnnotationCommandHandler;
|
|
||||||
import org.axonframework.commandhandling.CommandBus;
|
|
||||||
import org.axonframework.commandhandling.SimpleCommandBus;
|
|
||||||
import org.axonframework.commandhandling.gateway.CommandGateway;
|
|
||||||
import org.axonframework.commandhandling.gateway.DefaultCommandGateway;
|
|
||||||
import org.axonframework.eventhandling.AnnotationEventListenerAdapter;
|
|
||||||
import org.axonframework.eventsourcing.EventSourcingRepository;
|
|
||||||
import org.axonframework.eventsourcing.eventstore.EmbeddedEventStore;
|
|
||||||
import org.axonframework.eventsourcing.eventstore.EventStore;
|
|
||||||
import org.axonframework.eventsourcing.eventstore.inmemory.InMemoryEventStorageEngine;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class MessagesRunner {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
CommandBus commandBus = new SimpleCommandBus();
|
|
||||||
|
|
||||||
CommandGateway commandGateway = new DefaultCommandGateway(commandBus);
|
|
||||||
|
|
||||||
EventStore eventStore = new EmbeddedEventStore(new InMemoryEventStorageEngine());
|
|
||||||
|
|
||||||
EventSourcingRepository<MessagesAggregate> repository =
|
|
||||||
new EventSourcingRepository<>(MessagesAggregate.class, eventStore);
|
|
||||||
|
|
||||||
|
|
||||||
AggregateAnnotationCommandHandler<MessagesAggregate> messagesAggregateAggregateAnnotationCommandHandler =
|
|
||||||
new AggregateAnnotationCommandHandler<MessagesAggregate>(MessagesAggregate.class, repository);
|
|
||||||
messagesAggregateAggregateAnnotationCommandHandler.subscribe(commandBus);
|
|
||||||
|
|
||||||
final AnnotationEventListenerAdapter annotationEventListenerAdapter =
|
|
||||||
new AnnotationEventListenerAdapter(new MessagesEventHandler());
|
|
||||||
eventStore.subscribe(eventMessages -> eventMessages.forEach(e -> {
|
|
||||||
try {
|
|
||||||
annotationEventListenerAdapter.handle(e);
|
|
||||||
} catch (Exception e1) {
|
|
||||||
throw new RuntimeException(e1);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
));
|
|
||||||
|
|
||||||
final String itemId = UUID.randomUUID().toString();
|
|
||||||
commandGateway.send(new CreateMessageCommand(itemId, "Hello, how is your day? :-)"));
|
|
||||||
commandGateway.send(new MarkReadMessageCommand(itemId));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.axon;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class OrderApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(OrderApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,36 +0,0 @@
|
||||||
package com.baeldung.axon.aggregates;
|
|
||||||
|
|
||||||
import com.baeldung.axon.commands.CreateMessageCommand;
|
|
||||||
import com.baeldung.axon.commands.MarkReadMessageCommand;
|
|
||||||
import com.baeldung.axon.events.MessageCreatedEvent;
|
|
||||||
import com.baeldung.axon.events.MessageReadEvent;
|
|
||||||
import org.axonframework.commandhandling.CommandHandler;
|
|
||||||
import org.axonframework.commandhandling.model.AggregateIdentifier;
|
|
||||||
import org.axonframework.eventhandling.EventHandler;
|
|
||||||
|
|
||||||
import static org.axonframework.commandhandling.model.AggregateLifecycle.apply;
|
|
||||||
|
|
||||||
|
|
||||||
public class MessagesAggregate {
|
|
||||||
|
|
||||||
@AggregateIdentifier
|
|
||||||
private String id;
|
|
||||||
|
|
||||||
public MessagesAggregate() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@CommandHandler
|
|
||||||
public MessagesAggregate(CreateMessageCommand command) {
|
|
||||||
apply(new MessageCreatedEvent(command.getId(), command.getText()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void on(MessageCreatedEvent event) {
|
|
||||||
this.id = event.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@CommandHandler
|
|
||||||
public void markRead(MarkReadMessageCommand command) {
|
|
||||||
apply(new MessageReadEvent(id));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.baeldung.axon.commandmodel;
|
||||||
|
|
||||||
|
import static org.axonframework.modelling.command.AggregateLifecycle.apply;
|
||||||
|
|
||||||
|
import org.axonframework.commandhandling.CommandHandler;
|
||||||
|
import org.axonframework.eventsourcing.EventSourcingHandler;
|
||||||
|
import org.axonframework.modelling.command.AggregateIdentifier;
|
||||||
|
import org.axonframework.spring.stereotype.Aggregate;
|
||||||
|
|
||||||
|
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.commands.PlaceOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderPlacedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
|
||||||
|
|
||||||
|
@Aggregate
|
||||||
|
public class OrderAggregate {
|
||||||
|
|
||||||
|
@AggregateIdentifier
|
||||||
|
private String orderId;
|
||||||
|
private boolean orderConfirmed;
|
||||||
|
|
||||||
|
@CommandHandler
|
||||||
|
public OrderAggregate(PlaceOrderCommand command) {
|
||||||
|
apply(new OrderPlacedEvent(command.getOrderId(), command.getProduct()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@CommandHandler
|
||||||
|
public void handle(ConfirmOrderCommand command) {
|
||||||
|
apply(new OrderConfirmedEvent(orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@CommandHandler
|
||||||
|
public void handle(ShipOrderCommand command) {
|
||||||
|
if (!orderConfirmed) {
|
||||||
|
throw new IllegalStateException("Cannot ship an order which has not been confirmed yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(new OrderShippedEvent(orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventSourcingHandler
|
||||||
|
public void on(OrderPlacedEvent event) {
|
||||||
|
this.orderId = event.getOrderId();
|
||||||
|
orderConfirmed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventSourcingHandler
|
||||||
|
public void on(OrderConfirmedEvent event) {
|
||||||
|
orderConfirmed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected OrderAggregate() {
|
||||||
|
// Required by Axon to build a default Aggregate prior to Event Sourcing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,24 +0,0 @@
|
||||||
package com.baeldung.axon.commands;
|
|
||||||
|
|
||||||
|
|
||||||
import org.axonframework.commandhandling.TargetAggregateIdentifier;
|
|
||||||
|
|
||||||
public class CreateMessageCommand {
|
|
||||||
|
|
||||||
@TargetAggregateIdentifier
|
|
||||||
private final String id;
|
|
||||||
private final String text;
|
|
||||||
|
|
||||||
public CreateMessageCommand(String id, String text) {
|
|
||||||
this.id = id;
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package com.baeldung.axon.commands;
|
|
||||||
|
|
||||||
|
|
||||||
import org.axonframework.commandhandling.TargetAggregateIdentifier;
|
|
||||||
|
|
||||||
public class MarkReadMessageCommand {
|
|
||||||
|
|
||||||
@TargetAggregateIdentifier
|
|
||||||
private final String id;
|
|
||||||
|
|
||||||
public MarkReadMessageCommand(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.baeldung.axon.coreapi.commands;
|
||||||
|
|
||||||
|
import org.axonframework.modelling.command.TargetAggregateIdentifier;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class ConfirmOrderCommand {
|
||||||
|
|
||||||
|
@TargetAggregateIdentifier
|
||||||
|
private final String orderId;
|
||||||
|
|
||||||
|
public ConfirmOrderCommand(String orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final ConfirmOrderCommand other = (ConfirmOrderCommand) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ConfirmOrderCommand{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.baeldung.axon.coreapi.commands;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.axonframework.modelling.command.TargetAggregateIdentifier;
|
||||||
|
|
||||||
|
public class PlaceOrderCommand {
|
||||||
|
|
||||||
|
@TargetAggregateIdentifier
|
||||||
|
private final String orderId;
|
||||||
|
private final String product;
|
||||||
|
|
||||||
|
public PlaceOrderCommand(String orderId, String product) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
this.product = product;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProduct() {
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId, product);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final PlaceOrderCommand other = (PlaceOrderCommand) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId)
|
||||||
|
&& Objects.equals(this.product, other.product);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PlaceOrderCommand{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
", product='" + product + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.baeldung.axon.coreapi.commands;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.axonframework.modelling.command.TargetAggregateIdentifier;
|
||||||
|
|
||||||
|
public class ShipOrderCommand {
|
||||||
|
|
||||||
|
@TargetAggregateIdentifier
|
||||||
|
private final String orderId;
|
||||||
|
|
||||||
|
public ShipOrderCommand(String orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final ShipOrderCommand other = (ShipOrderCommand) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ShipOrderCommand{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.axon.coreapi.events;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class OrderConfirmedEvent {
|
||||||
|
|
||||||
|
private final String orderId;
|
||||||
|
|
||||||
|
public OrderConfirmedEvent(String orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final OrderConfirmedEvent other = (OrderConfirmedEvent) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OrderConfirmedEvent{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.baeldung.axon.coreapi.events;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class OrderPlacedEvent {
|
||||||
|
|
||||||
|
private final String orderId;
|
||||||
|
private final String product;
|
||||||
|
|
||||||
|
public OrderPlacedEvent(String orderId, String product) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
this.product = product;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProduct() {
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId, product);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final OrderPlacedEvent other = (OrderPlacedEvent) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId)
|
||||||
|
&& Objects.equals(this.product, other.product);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OrderPlacedEvent{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
", product='" + product + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.axon.coreapi.events;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class OrderShippedEvent {
|
||||||
|
|
||||||
|
private final String orderId;
|
||||||
|
|
||||||
|
public OrderShippedEvent(String orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final OrderShippedEvent other = (OrderShippedEvent) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OrderShippedEvent{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.axon.coreapi.queries;
|
||||||
|
|
||||||
|
public class FindAllOrderedProductsQuery {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.baeldung.axon.coreapi.queries;
|
||||||
|
|
||||||
|
public enum OrderStatus {
|
||||||
|
|
||||||
|
PLACED, CONFIRMED, SHIPPED
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.baeldung.axon.coreapi.queries;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class OrderedProduct {
|
||||||
|
|
||||||
|
private final String orderId;
|
||||||
|
private final String product;
|
||||||
|
private OrderStatus orderStatus;
|
||||||
|
|
||||||
|
public OrderedProduct(String orderId, String product) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
this.product = product;
|
||||||
|
orderStatus = OrderStatus.PLACED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProduct() {
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrderStatus getOrderStatus() {
|
||||||
|
return orderStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderConfirmed() {
|
||||||
|
this.orderStatus = OrderStatus.CONFIRMED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderShipped() {
|
||||||
|
this.orderStatus = OrderStatus.SHIPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(orderId, product, orderStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final OrderedProduct other = (OrderedProduct) obj;
|
||||||
|
return Objects.equals(this.orderId, other.orderId)
|
||||||
|
&& Objects.equals(this.product, other.product)
|
||||||
|
&& Objects.equals(this.orderStatus, other.orderStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OrderedProduct{" +
|
||||||
|
"orderId='" + orderId + '\'' +
|
||||||
|
", product='" + product + '\'' +
|
||||||
|
", orderStatus=" + orderStatus +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +0,0 @@
|
||||||
package com.baeldung.axon.eventhandlers;
|
|
||||||
|
|
||||||
import com.baeldung.axon.events.MessageReadEvent;
|
|
||||||
import com.baeldung.axon.events.MessageCreatedEvent;
|
|
||||||
import org.axonframework.eventhandling.EventHandler;
|
|
||||||
|
|
||||||
|
|
||||||
public class MessagesEventHandler {
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void handle(MessageCreatedEvent event) {
|
|
||||||
System.out.println("Message received: " + event.getText() + " (" + event.getId() + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void handle(MessageReadEvent event) {
|
|
||||||
System.out.println("Message read: " + event.getId());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package com.baeldung.axon.events;
|
|
||||||
|
|
||||||
public class MessageCreatedEvent {
|
|
||||||
|
|
||||||
private final String id;
|
|
||||||
private final String text;
|
|
||||||
|
|
||||||
public MessageCreatedEvent(String id, String text) {
|
|
||||||
this.id = id;
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package com.baeldung.axon.events;
|
|
||||||
|
|
||||||
public class MessageReadEvent {
|
|
||||||
|
|
||||||
private final String id;
|
|
||||||
|
|
||||||
public MessageReadEvent(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.axon.gui;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.axonframework.commandhandling.gateway.CommandGateway;
|
||||||
|
import org.axonframework.messaging.responsetypes.ResponseTypes;
|
||||||
|
import org.axonframework.queryhandling.QueryGateway;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.commands.PlaceOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery;
|
||||||
|
import com.baeldung.axon.coreapi.queries.OrderedProduct;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class OrderRestEndpoint {
|
||||||
|
|
||||||
|
private final CommandGateway commandGateway;
|
||||||
|
private final QueryGateway queryGateway;
|
||||||
|
|
||||||
|
public OrderRestEndpoint(CommandGateway commandGateway, QueryGateway queryGateway) {
|
||||||
|
this.commandGateway = commandGateway;
|
||||||
|
this.queryGateway = queryGateway;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/ship-order")
|
||||||
|
public void shipOrder() {
|
||||||
|
String orderId = UUID.randomUUID().toString();
|
||||||
|
commandGateway.send(new PlaceOrderCommand(orderId, "Deluxe Chair"));
|
||||||
|
commandGateway.send(new ConfirmOrderCommand(orderId));
|
||||||
|
commandGateway.send(new ShipOrderCommand(orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/ship-unconfirmed-order")
|
||||||
|
public void shipUnconfirmedOrder() {
|
||||||
|
String orderId = UUID.randomUUID().toString();
|
||||||
|
commandGateway.send(new PlaceOrderCommand(orderId, "Deluxe Chair"));
|
||||||
|
// This throws an exception, as an Order cannot be shipped if it has not been confirmed yet.
|
||||||
|
commandGateway.send(new ShipOrderCommand(orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/all-orders")
|
||||||
|
public List<OrderedProduct> findAllOrderedProducts() {
|
||||||
|
return queryGateway.query(new FindAllOrderedProductsQuery(), ResponseTypes.multipleInstancesOf(OrderedProduct.class))
|
||||||
|
.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.baeldung.axon.querymodel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.axonframework.eventhandling.EventHandler;
|
||||||
|
import org.axonframework.queryhandling.QueryHandler;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderPlacedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery;
|
||||||
|
import com.baeldung.axon.coreapi.queries.OrderedProduct;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class OrderedProductsEventHandler {
|
||||||
|
|
||||||
|
private final Map<String, OrderedProduct> orderedProducts = new HashMap<>();
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void on(OrderPlacedEvent event) {
|
||||||
|
String orderId = event.getOrderId();
|
||||||
|
orderedProducts.put(orderId, new OrderedProduct(orderId, event.getProduct()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void on(OrderConfirmedEvent event) {
|
||||||
|
orderedProducts.computeIfPresent(event.getOrderId(), (orderId, orderedProduct) -> {
|
||||||
|
orderedProduct.setOrderConfirmed();
|
||||||
|
return orderedProduct;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void on(OrderShippedEvent event) {
|
||||||
|
orderedProducts.computeIfPresent(event.getOrderId(), (orderId, orderedProduct) -> {
|
||||||
|
orderedProduct.setOrderShipped();
|
||||||
|
return orderedProduct;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@QueryHandler
|
||||||
|
public List<OrderedProduct> handle(FindAllOrderedProductsQuery query) {
|
||||||
|
return new ArrayList<>(orderedProducts.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
POST http://localhost:8080/ship-order
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
POST http://localhost:8080/ship-unconfirmed-order
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
GET http://localhost:8080/all-orders
|
||||||
|
|
||||||
|
###
|
|
@ -1,42 +0,0 @@
|
||||||
package com.baeldung.axon;
|
|
||||||
|
|
||||||
import com.baeldung.axon.aggregates.MessagesAggregate;
|
|
||||||
import com.baeldung.axon.commands.CreateMessageCommand;
|
|
||||||
import com.baeldung.axon.commands.MarkReadMessageCommand;
|
|
||||||
import com.baeldung.axon.events.MessageCreatedEvent;
|
|
||||||
import com.baeldung.axon.events.MessageReadEvent;
|
|
||||||
import org.axonframework.test.aggregate.AggregateTestFixture;
|
|
||||||
import org.axonframework.test.aggregate.FixtureConfiguration;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class MessagesAggregateIntegrationTest {
|
|
||||||
|
|
||||||
private FixtureConfiguration<MessagesAggregate> fixture;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
fixture = new AggregateTestFixture<MessagesAggregate>(MessagesAggregate.class);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void giveAggregateRoot_whenCreateMessageCommand_thenShouldProduceMessageCreatedEvent() throws Exception {
|
|
||||||
String eventText = "Hello, how is your day?";
|
|
||||||
String id = UUID.randomUUID().toString();
|
|
||||||
fixture.given()
|
|
||||||
.when(new CreateMessageCommand(id, eventText))
|
|
||||||
.expectEvents(new MessageCreatedEvent(id, eventText));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenMessageCreatedEvent_whenReadMessageCommand_thenShouldProduceMessageReadEvent() throws Exception {
|
|
||||||
String id = UUID.randomUUID().toString();
|
|
||||||
|
|
||||||
fixture.given(new MessageCreatedEvent(id, "Hello :-)"))
|
|
||||||
.when(new MarkReadMessageCommand(id))
|
|
||||||
.expectEvents(new MessageReadEvent(id));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.baeldung.axon.commandmodel;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.axonframework.test.aggregate.AggregateTestFixture;
|
||||||
|
import org.axonframework.test.aggregate.FixtureConfiguration;
|
||||||
|
import org.junit.*;
|
||||||
|
|
||||||
|
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.commands.PlaceOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderPlacedEvent;
|
||||||
|
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
|
||||||
|
|
||||||
|
public class OrderAggregateUnitTest {
|
||||||
|
|
||||||
|
private FixtureConfiguration<OrderAggregate> fixture;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
fixture = new AggregateTestFixture<>(OrderAggregate.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void giveNoPriorActivity_whenPlaceOrderCommand_thenShouldPublishOrderPlacedEvent() {
|
||||||
|
String orderId = UUID.randomUUID().toString();
|
||||||
|
String product = "Deluxe Chair";
|
||||||
|
fixture.givenNoPriorActivity()
|
||||||
|
.when(new PlaceOrderCommand(orderId, product))
|
||||||
|
.expectEvents(new OrderPlacedEvent(orderId, product));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOrderPlacedEvent_whenConfirmOrderCommand_thenShouldPublishOrderConfirmedEvent() {
|
||||||
|
String orderId = UUID.randomUUID().toString();
|
||||||
|
String product = "Deluxe Chair";
|
||||||
|
fixture.given(new OrderPlacedEvent(orderId, product))
|
||||||
|
.when(new ConfirmOrderCommand(orderId))
|
||||||
|
.expectEvents(new OrderConfirmedEvent(orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOrderPlacedEvent_whenShipOrderCommand_thenShouldThrowIllegalStateException() {
|
||||||
|
String orderId = UUID.randomUUID().toString();
|
||||||
|
String product = "Deluxe Chair";
|
||||||
|
fixture.given(new OrderPlacedEvent(orderId, product))
|
||||||
|
.when(new ShipOrderCommand(orderId))
|
||||||
|
.expectException(IllegalStateException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenOrderPlacedEventAndOrderConfirmedEvent_whenShipOrderCommand_thenShouldPublishOrderShippedEvent() {
|
||||||
|
String orderId = UUID.randomUUID().toString();
|
||||||
|
String product = "Deluxe Chair";
|
||||||
|
fixture.given(new OrderPlacedEvent(orderId, product), new OrderConfirmedEvent(orderId))
|
||||||
|
.when(new ShipOrderCommand(orderId))
|
||||||
|
.expectEvents(new OrderShippedEvent(orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,9 +5,9 @@
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>azure</artifactId>
|
<artifactId>azure</artifactId>
|
||||||
<version>0.1</version>
|
<version>0.1</version>
|
||||||
<packaging>war</packaging>
|
|
||||||
<name>azure</name>
|
<name>azure</name>
|
||||||
<description>Demo project for Spring Boot on Azure</description>
|
<description>Demo project for Spring Boot on Azure</description>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent-boot-2</artifactId>
|
<artifactId>parent-boot-2</artifactId>
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Blade - A Complete GuideBook](http://www.baeldung.com/blade)
|
||||||
|
|
||||||
|
Run Integration Tests with `mvn integration-test`
|
|
@ -0,0 +1,205 @@
|
||||||
|
<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/maven-v4_0_0.xsd">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<!-- WITH THIS mvn integration-test DOES WORK -->
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>blade</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<name>blade</name>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- WITH THIS mvn integration-test DOESN'T WORK -->
|
||||||
|
<!-- <parent> -->
|
||||||
|
<!-- <groupId>com.baeldung</groupId> -->
|
||||||
|
<!-- <artifactId>parent-modules</artifactId> -->
|
||||||
|
<!-- <version>1.0.0-SNAPSHOT</version> -->
|
||||||
|
<!-- </parent> -->
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bladejava</groupId>
|
||||||
|
<artifactId>blade-mvc</artifactId>
|
||||||
|
<version>${blade-mvc.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.webjars</groupId>
|
||||||
|
<artifactId>bootstrap</artifactId>
|
||||||
|
<version>${bootstrap.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- PROVIDED -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- TEST -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj-core.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>${httpclient.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpmime</artifactId>
|
||||||
|
<version>${httpmime.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpcore</artifactId>
|
||||||
|
<version>${httpcore.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<finalName>sample-blade-app</finalName>
|
||||||
|
<plugins>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<forkCount>3</forkCount>
|
||||||
|
<reuseForks>true</reuseForks>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
|
<version>${maven-failsafe-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<includes>
|
||||||
|
<include>**/*LiveTest.java</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>integration-test</goal>
|
||||||
|
<goal>verify</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.bazaarvoice.maven.plugins</groupId>
|
||||||
|
<artifactId>process-exec-maven-plugin</artifactId>
|
||||||
|
<version>${process-exec-maven-plugin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<!--Start Blade -->
|
||||||
|
<execution>
|
||||||
|
<id>blade-process</id>
|
||||||
|
<phase>pre-integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>start</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<name>Blade</name>
|
||||||
|
<waitForInterrupt>false</waitForInterrupt>
|
||||||
|
<arguments>
|
||||||
|
<argument>java</argument>
|
||||||
|
<argument>-jar</argument>
|
||||||
|
<argument>sample-blade-app.jar</argument>
|
||||||
|
</arguments>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
|
||||||
|
<!--Stop all processes in reverse order -->
|
||||||
|
<execution>
|
||||||
|
<id>stop-all</id>
|
||||||
|
<phase>post-integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>stop-all</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<configuration>
|
||||||
|
<finalName>${project.build.finalName}</finalName>
|
||||||
|
<appendAssemblyId>false</appendAssemblyId>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.baeldung.blade.sample.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>make-assembly</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${maven.compiler.source}</source>
|
||||||
|
<target>${maven.compiler.target}</target>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<blade-mvc.version>2.0.14.RELEASE</blade-mvc.version>
|
||||||
|
<bootstrap.version>4.2.1</bootstrap.version>
|
||||||
|
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||||
|
<lombok.version>1.18.4</lombok.version>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
<httpclient.version>4.5.6</httpclient.version>
|
||||||
|
<httpmime.version>4.5.6</httpmime.version>
|
||||||
|
<httpcore.version>4.4.10</httpcore.version>
|
||||||
|
<assertj-core.version>3.11.1</assertj-core.version>
|
||||||
|
<maven-failsafe-plugin.version>3.0.0-M3</maven-failsafe-plugin.version>
|
||||||
|
<process-exec-maven-plugin.version>0.7</process-exec-maven-plugin.version>
|
||||||
|
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
|
||||||
|
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
|
||||||
|
</properties>
|
||||||
|
</project>
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import com.baeldung.blade.sample.interceptors.BaeldungMiddleware;
|
||||||
|
import com.blade.Blade;
|
||||||
|
import com.blade.event.EventType;
|
||||||
|
import com.blade.mvc.WebContext;
|
||||||
|
import com.blade.mvc.http.Session;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(App.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
Blade.of()
|
||||||
|
.get("/", ctx -> ctx.render("index.html"))
|
||||||
|
.get("/basic-route-example", ctx -> ctx.text("GET called"))
|
||||||
|
.post("/basic-route-example", ctx -> ctx.text("POST called"))
|
||||||
|
.put("/basic-route-example", ctx -> ctx.text("PUT called"))
|
||||||
|
.delete("/basic-route-example", ctx -> ctx.text("DELETE called"))
|
||||||
|
.addStatics("/custom-static")
|
||||||
|
// .showFileList(true)
|
||||||
|
.enableCors(true)
|
||||||
|
.before("/user/*", ctx -> log.info("[NarrowedHook] Before '/user/*', URL called: " + ctx.uri()))
|
||||||
|
.on(EventType.SERVER_STARTED, e -> {
|
||||||
|
String version = WebContext.blade()
|
||||||
|
.env("app.version")
|
||||||
|
.orElse("N/D");
|
||||||
|
log.info("[Event::serverStarted] Loading 'app.version' from configuration, value: " + version);
|
||||||
|
})
|
||||||
|
.on(EventType.SESSION_CREATED, e -> {
|
||||||
|
Session session = (Session) e.attribute("session");
|
||||||
|
session.attribute("mySessionValue", "Baeldung");
|
||||||
|
})
|
||||||
|
.use(new BaeldungMiddleware())
|
||||||
|
.start(App.class, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import com.blade.mvc.annotation.GetRoute;
|
||||||
|
import com.blade.mvc.annotation.Path;
|
||||||
|
import com.blade.mvc.http.Request;
|
||||||
|
import com.blade.mvc.http.Response;
|
||||||
|
import com.blade.mvc.http.Session;
|
||||||
|
|
||||||
|
@Path
|
||||||
|
public class AttributesExampleController {
|
||||||
|
|
||||||
|
public final static String REQUEST_VALUE = "Some Request value";
|
||||||
|
public final static String SESSION_VALUE = "1337";
|
||||||
|
public final static String HEADER = "Some Header";
|
||||||
|
|
||||||
|
@GetRoute("/request-attribute-example")
|
||||||
|
public void getRequestAttribute(Request request, Response response) {
|
||||||
|
request.attribute("request-val", REQUEST_VALUE);
|
||||||
|
String requestVal = request.attribute("request-val");
|
||||||
|
response.text(requestVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/session-attribute-example")
|
||||||
|
public void getSessionAttribute(Request request, Response response) {
|
||||||
|
Session session = request.session();
|
||||||
|
session.attribute("session-val", SESSION_VALUE);
|
||||||
|
String sessionVal = session.attribute("session-val");
|
||||||
|
response.text(sessionVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/header-example")
|
||||||
|
public void getHeader(Request request, Response response) {
|
||||||
|
String headerVal = request.header("a-header", HEADER);
|
||||||
|
response.header("a-header", headerVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import com.blade.mvc.annotation.Path;
|
||||||
|
import com.blade.mvc.annotation.Route;
|
||||||
|
import com.blade.mvc.http.Response;
|
||||||
|
|
||||||
|
@Path
|
||||||
|
public class LogExampleController {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExampleController.class);
|
||||||
|
|
||||||
|
@Route(value = "/test-logs")
|
||||||
|
public void testLogs(Response response) {
|
||||||
|
log.trace("This is a TRACE Message");
|
||||||
|
log.debug("This is a DEBUG Message");
|
||||||
|
log.info("This is an INFO Message");
|
||||||
|
log.warn("This is a WARN Message");
|
||||||
|
log.error("This is an ERROR Message");
|
||||||
|
response.text("Check in ./logs");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
|
||||||
|
import com.baeldung.blade.sample.vo.User;
|
||||||
|
import com.blade.mvc.annotation.CookieParam;
|
||||||
|
import com.blade.mvc.annotation.GetRoute;
|
||||||
|
import com.blade.mvc.annotation.HeaderParam;
|
||||||
|
import com.blade.mvc.annotation.JSON;
|
||||||
|
import com.blade.mvc.annotation.MultipartParam;
|
||||||
|
import com.blade.mvc.annotation.Param;
|
||||||
|
import com.blade.mvc.annotation.Path;
|
||||||
|
import com.blade.mvc.annotation.PathParam;
|
||||||
|
import com.blade.mvc.annotation.PostRoute;
|
||||||
|
import com.blade.mvc.http.Response;
|
||||||
|
import com.blade.mvc.multipart.FileItem;
|
||||||
|
import com.blade.mvc.ui.RestResponse;
|
||||||
|
|
||||||
|
@Path
|
||||||
|
public class ParameterInjectionExampleController {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ParameterInjectionExampleController.class);
|
||||||
|
|
||||||
|
@GetRoute("/params/form")
|
||||||
|
public void formParam(@Param String name, Response response) {
|
||||||
|
log.info("name: " + name);
|
||||||
|
response.text(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/params/path/:uid")
|
||||||
|
public void restfulParam(@PathParam Integer uid, Response response) {
|
||||||
|
log.info("uid: " + uid);
|
||||||
|
response.text(String.valueOf(uid));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostRoute("/params-file") // DO NOT USE A SLASH WITHIN THE ROUTE OR IT WILL BREAK (?)
|
||||||
|
@JSON
|
||||||
|
public RestResponse<?> fileParam(@MultipartParam FileItem fileItem) throws Exception {
|
||||||
|
try {
|
||||||
|
byte[] fileContent = fileItem.getData();
|
||||||
|
|
||||||
|
log.debug("Saving the uploaded file");
|
||||||
|
java.nio.file.Path tempFile = Files.createTempFile("baeldung_tempfiles", ".tmp");
|
||||||
|
Files.write(tempFile, fileContent, StandardOpenOption.WRITE);
|
||||||
|
|
||||||
|
return RestResponse.ok();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
return RestResponse.fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/params/header")
|
||||||
|
public void headerParam(@HeaderParam String customheader, Response response) {
|
||||||
|
log.info("Custom header: " + customheader);
|
||||||
|
response.text(customheader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/params/cookie")
|
||||||
|
public void cookieParam(@CookieParam(defaultValue = "default value") String myCookie, Response response) {
|
||||||
|
log.info("myCookie: " + myCookie);
|
||||||
|
response.text(myCookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostRoute("/params/vo")
|
||||||
|
public void voParam(@Param User user, Response response) {
|
||||||
|
log.info("user as voParam: " + user.toString());
|
||||||
|
response.html(user.toString() + "<br/><br/><a href='/'>Back</a>");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package com.baeldung.blade.sample;
|
||||||
|
|
||||||
|
import com.baeldung.blade.sample.configuration.BaeldungException;
|
||||||
|
import com.blade.mvc.WebContext;
|
||||||
|
import com.blade.mvc.annotation.DeleteRoute;
|
||||||
|
import com.blade.mvc.annotation.GetRoute;
|
||||||
|
import com.blade.mvc.annotation.Path;
|
||||||
|
import com.blade.mvc.annotation.PostRoute;
|
||||||
|
import com.blade.mvc.annotation.PutRoute;
|
||||||
|
import com.blade.mvc.annotation.Route;
|
||||||
|
import com.blade.mvc.http.HttpMethod;
|
||||||
|
import com.blade.mvc.http.Request;
|
||||||
|
import com.blade.mvc.http.Response;
|
||||||
|
|
||||||
|
@Path
|
||||||
|
public class RouteExampleController {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(RouteExampleController.class);
|
||||||
|
|
||||||
|
@GetRoute("/route-example")
|
||||||
|
public String get() {
|
||||||
|
return "get.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostRoute("/route-example")
|
||||||
|
public String post() {
|
||||||
|
return "post.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutRoute("/route-example")
|
||||||
|
public String put() {
|
||||||
|
return "put.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteRoute("/route-example")
|
||||||
|
public String delete() {
|
||||||
|
return "delete.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Route(value = "/another-route-example", method = HttpMethod.GET)
|
||||||
|
public String anotherGet() {
|
||||||
|
return "get.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Route(value = "/allmatch-route-example")
|
||||||
|
public String allmatch() {
|
||||||
|
return "allmatch.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Route(value = "/triggerInternalServerError")
|
||||||
|
public void triggerInternalServerError() {
|
||||||
|
int x = 1 / 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Route(value = "/triggerBaeldungException")
|
||||||
|
public void triggerBaeldungException() throws BaeldungException {
|
||||||
|
throw new BaeldungException("Foobar Exception to threat differently");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Route(value = "/user/foo")
|
||||||
|
public void urlCoveredByNarrowedWebhook(Response response) {
|
||||||
|
response.text("Check out for the WebHook covering '/user/*' in the logs");
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/load-configuration-in-a-route")
|
||||||
|
public void loadConfigurationInARoute(Response response) {
|
||||||
|
String authors = WebContext.blade()
|
||||||
|
.env("app.authors", "Unknown authors");
|
||||||
|
log.info("[/load-configuration-in-a-route] Loading 'app.authors' from configuration, value: " + authors);
|
||||||
|
response.render("index.html");
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetRoute("/template-output-test")
|
||||||
|
public void templateOutputTest(Request request, Response response) {
|
||||||
|
request.attribute("name", "Blade");
|
||||||
|
response.render("template-output-test.html");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.blade.sample.configuration;
|
||||||
|
|
||||||
|
public class BaeldungException extends RuntimeException {
|
||||||
|
|
||||||
|
public BaeldungException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.blade.sample.configuration;
|
||||||
|
|
||||||
|
import com.blade.ioc.annotation.Bean;
|
||||||
|
import com.blade.mvc.WebContext;
|
||||||
|
import com.blade.mvc.handler.DefaultExceptionHandler;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public class GlobalExceptionHandler extends DefaultExceptionHandler {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(Exception e) {
|
||||||
|
if (e instanceof BaeldungException) {
|
||||||
|
Exception baeldungException = (BaeldungException) e;
|
||||||
|
String msg = baeldungException.getMessage();
|
||||||
|
log.error("[GlobalExceptionHandler] Intercepted an exception to threat with additional logic. Error message: " + msg);
|
||||||
|
WebContext.response()
|
||||||
|
.render("index.html");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
super.handle(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.blade.sample.configuration;
|
||||||
|
|
||||||
|
import com.blade.Blade;
|
||||||
|
import com.blade.ioc.annotation.Bean;
|
||||||
|
import com.blade.loader.BladeLoader;
|
||||||
|
import com.blade.mvc.WebContext;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public class LoadConfig implements BladeLoader {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoadConfig.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(Blade blade) {
|
||||||
|
String version = WebContext.blade()
|
||||||
|
.env("app.version")
|
||||||
|
.orElse("N/D");
|
||||||
|
String authors = WebContext.blade()
|
||||||
|
.env("app.authors", "Unknown authors");
|
||||||
|
|
||||||
|
log.info("[LoadConfig] loaded 'app.version' (" + version + ") and 'app.authors' (" + authors + ") in a configuration bean");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.blade.sample.configuration;
|
||||||
|
|
||||||
|
import com.blade.ioc.annotation.Bean;
|
||||||
|
import com.blade.task.annotation.Schedule;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public class ScheduleExample {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ScheduleExample.class);
|
||||||
|
|
||||||
|
@Schedule(name = "baeldungTask", cron = "0 */1 * * * ?")
|
||||||
|
public void runScheduledTask() {
|
||||||
|
log.info("[ScheduleExample] This is a scheduled Task running once per minute.");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.blade.sample.interceptors;
|
||||||
|
|
||||||
|
import com.blade.ioc.annotation.Bean;
|
||||||
|
import com.blade.mvc.RouteContext;
|
||||||
|
import com.blade.mvc.hook.WebHook;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public class BaeldungHook implements WebHook {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(BaeldungHook.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean before(RouteContext ctx) {
|
||||||
|
log.info("[BaeldungHook] called before Route method");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.blade.sample.interceptors;
|
||||||
|
|
||||||
|
import com.blade.mvc.RouteContext;
|
||||||
|
import com.blade.mvc.hook.WebHook;
|
||||||
|
|
||||||
|
public class BaeldungMiddleware implements WebHook {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(BaeldungMiddleware.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean before(RouteContext context) {
|
||||||
|
log.info("[BaeldungMiddleware] called before Route method and other WebHooks");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.baeldung.blade.sample.vo;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
public class User {
|
||||||
|
@Getter @Setter private String name;
|
||||||
|
@Getter @Setter private String site;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return ReflectionToStringBuilder.toString(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
mvc.statics.show-list=true
|
||||||
|
mvc.view.404=my-404.html
|
||||||
|
mvc.view.500=my-500.html
|
||||||
|
app.version=0.0.1
|
||||||
|
app.authors=Andrea Ligios
|
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 650 B |
|
@ -0,0 +1 @@
|
||||||
|
/* App CSS */
|
|
@ -0,0 +1,43 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
<script src="https://cdn.staticfile.org/jquery/3.3.1/jquery.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<h1>File Upload and download test</h1>
|
||||||
|
<form id="uploadForm" enctype="multipart/form-data">
|
||||||
|
<input id="file" type="file" name="file" />
|
||||||
|
<button id="upload" type="button">Upload</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<a href="/">Back</a>
|
||||||
|
<script>
|
||||||
|
var data = new FormData();
|
||||||
|
|
||||||
|
$('#upload').click(function() {
|
||||||
|
$.ajax({
|
||||||
|
url : '/params-file',
|
||||||
|
type : 'POST',
|
||||||
|
cache : false,
|
||||||
|
data : new FormData($('#uploadForm')[0]),
|
||||||
|
processData : false,
|
||||||
|
contentType : false
|
||||||
|
}).done(function(res) {
|
||||||
|
console.log(res);
|
||||||
|
if (res.success) {
|
||||||
|
alert('Ok');
|
||||||
|
} else {
|
||||||
|
alert(res.msg || 'Error');
|
||||||
|
}
|
||||||
|
}).fail(function(res) {
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
<script src="https://cdn.staticfile.org/jquery/3.3.1/jquery.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<h1>User POJO post test</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<form id="uploadForm" action="/params/vo" method="post">
|
||||||
|
<span>Person POJO:</span>
|
||||||
|
<input type="text" name="name" placeholder="name"/>
|
||||||
|
<input type="text" name="site" placeholder="site"/>
|
||||||
|
<button id="upload" type="submit">Send user object</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<a href="/">Back</a>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1 @@
|
||||||
|
ALLMATCH called
|
|
@ -0,0 +1 @@
|
||||||
|
DELETE called
|
|
@ -0,0 +1 @@
|
||||||
|
GET called
|
|
@ -0,0 +1,30 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Baeldung Blade App • Written by Andrea Ligios</title>
|
||||||
|
<link href="/static/app.css" rel="stylesheet" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Baeldung Blade App - Showcase</h1>
|
||||||
|
|
||||||
|
<h3>Manual tests</h3>
|
||||||
|
<p>The following are tests which are not covered by integration tests, but that can be run manually in order to check the functionality, either in the browser or in the logs, depending on the case.</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><a href="/static/file-upload.html">File Upload</a></li>
|
||||||
|
<li><a href="/static/user-post.html">User POJO Post</a></li>
|
||||||
|
<li><a href="/user/foo">Webhook narrowed to the '/user/*' URL</a></li>
|
||||||
|
<li><a href="/load-configuration-in-a-route">Load Configuration in a Route</a></li>
|
||||||
|
<li><a href="/triggerInternalServerError">Trigger internal server error (and test the custom error 500 page)</a></li>
|
||||||
|
<li><a href="/triggerBaeldungException">Trigger BaeldungException (and test the Global Exception Handler)</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Session value created in App.java</h3>
|
||||||
|
<p>mySessionValue = ${mySessionValue}</p>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="/static/app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>404 Not found</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
Custom Error 404 Page
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>500 Internal Server Error</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1> Custom Error 500 Page </h1>
|
||||||
|
<p> The following error occurred: "<strong>${message}</strong>"</p>
|
||||||
|
<pre> ${stackTrace} </pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1 @@
|
||||||
|
POST called
|
|
@ -0,0 +1 @@
|
||||||
|
PUT called
|
|
@ -0,0 +1 @@
|
||||||
|
<h1>Hello, ${name}!</h1>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue