Skip to content

Commit 4321be4

Browse files
committed
merge
2 parents 36decb4 + 91cc251 commit 4321be4

8 files changed

Lines changed: 1327 additions & 966 deletions

File tree

akka-http/pom.xml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?xml version="1.0"?>
2+
<project
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
4+
xmlns="http://maven.apache.org/POM/4.0.0"
5+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
6+
7+
<modelVersion>4.0.0</modelVersion>
8+
<artifactId>akka-http</artifactId>
9+
<name>akka-http</name>
10+
11+
<parent>
12+
<artifactId>parent-modules</artifactId>
13+
<groupId>com.baeldung</groupId>
14+
<version>1.0.0-SNAPSHOT</version>
15+
</parent>
16+
17+
<dependencies>
18+
<dependency>
19+
<groupId>com.typesafe.akka</groupId>
20+
<artifactId>akka-http_2.12</artifactId>
21+
<version>${akka.http.version}</version>
22+
</dependency>
23+
<dependency>
24+
<groupId>com.typesafe.akka</groupId>
25+
<artifactId>akka-stream_2.12</artifactId>
26+
<version>2.5.11</version>
27+
</dependency>
28+
<dependency>
29+
<groupId>com.typesafe.akka</groupId>
30+
<artifactId>akka-http-jackson_2.12</artifactId>
31+
<version>${akka.http.version}</version>
32+
</dependency>
33+
<dependency>
34+
<groupId>com.typesafe.akka</groupId>
35+
<artifactId>akka-http-testkit_2.12</artifactId>
36+
<version>${akka.http.version}</version>
37+
<scope>test</scope>
38+
</dependency>
39+
</dependencies>
40+
41+
<properties>
42+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
43+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
44+
<java.version>1.8</java.version>
45+
<akka.http.version>10.0.11</akka.http.version>
46+
<akka.stream.version>2.5.11</akka.stream.version>
47+
</properties>
48+
</project>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.baeldung.akkahttp;
2+
3+
/**
4+
* User Entity
5+
*
6+
*/
7+
public class User {
8+
9+
private final String name;
10+
private final String address;
11+
12+
public User() {
13+
this.name = "";
14+
this.address = "";
15+
}
16+
17+
public User(String name, String address) {
18+
this.name = name;
19+
this.address = address;
20+
}
21+
22+
public String getName() {
23+
return name;
24+
}
25+
26+
public String getAddress() {
27+
return address;
28+
}
29+
30+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.baeldung.akkahttp;
2+
3+
import akka.actor.AbstractActor;
4+
import akka.actor.Props;
5+
import akka.japi.pf.FI;
6+
import com.baeldung.akkahttp.UserMessages.ActionPerformed;
7+
import com.baeldung.akkahttp.UserMessages.CreateUserMessage;
8+
import com.baeldung.akkahttp.UserMessages.GetUserMessage;
9+
10+
11+
class UserActor extends AbstractActor {
12+
13+
private UserService userService = new UserService();
14+
15+
static Props props() {
16+
return Props.create(UserActor.class);
17+
}
18+
19+
@Override
20+
public Receive createReceive() {
21+
return receiveBuilder()
22+
.match(CreateUserMessage.class, handleCreateUser())
23+
.match(GetUserMessage.class, handleGetUser())
24+
.build();
25+
}
26+
27+
private FI.UnitApply<CreateUserMessage> handleCreateUser() {
28+
return createUserMessageMessage -> {
29+
userService.createUser(createUserMessageMessage.getUser());
30+
sender().tell(new ActionPerformed(String.format("User %s created.", createUserMessageMessage.getUser()
31+
.getName())), getSelf());
32+
};
33+
}
34+
35+
private FI.UnitApply<GetUserMessage> handleGetUser() {
36+
return getUserMessageMessage -> {
37+
sender().tell(userService.getUser(getUserMessageMessage.getUserId()), getSelf());
38+
};
39+
}
40+
41+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.baeldung.akkahttp;
2+
3+
import java.io.Serializable;
4+
5+
/**
6+
* Defines all messages related to User Actor
7+
*
8+
*/
9+
public interface UserRegistryMessages {
10+
11+
class GetUsers implements Serializable {
12+
13+
private static final long serialVersionUID = 1L;
14+
}
15+
16+
class ActionPerformed implements Serializable {
17+
18+
private static final long serialVersionUID = 1L;
19+
20+
private final String description;
21+
22+
public ActionPerformed(String description) {
23+
this.description = description;
24+
}
25+
26+
public String getDescription() {
27+
return description;
28+
}
29+
}
30+
31+
class CreateUser implements Serializable {
32+
33+
private static final long serialVersionUID = 1L;
34+
private final User user;
35+
36+
public CreateUser(User user) {
37+
this.user = user;
38+
}
39+
40+
public User getUser() {
41+
return user;
42+
}
43+
}
44+
45+
class GetUser implements Serializable {
46+
47+
private static final long serialVersionUID = 1L;
48+
private final String name;
49+
50+
public GetUser(String name) {
51+
this.name = name;
52+
}
53+
54+
public String getName() {
55+
return name;
56+
}
57+
}
58+
59+
class DeleteUser implements Serializable {
60+
61+
private static final long serialVersionUID = 1L;
62+
private final String name;
63+
64+
public DeleteUser(String name) {
65+
this.name = name;
66+
}
67+
68+
public String getName() {
69+
return name;
70+
}
71+
}
72+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.baeldung.akkahttp;
2+
3+
import java.util.Optional;
4+
import java.util.concurrent.CompletionStage;
5+
import java.util.concurrent.TimeUnit;
6+
7+
import akka.actor.ActorRef;
8+
import akka.http.javadsl.marshallers.jackson.Jackson;
9+
import akka.http.javadsl.model.StatusCodes;
10+
import akka.http.javadsl.server.AllDirectives;
11+
import akka.http.javadsl.server.Route;
12+
import akka.pattern.PatternsCS;
13+
import akka.util.Timeout;
14+
import com.baeldung.akkahttp.UserMessages.ActionPerformed;
15+
import com.baeldung.akkahttp.UserMessages.CreateUser;
16+
import scala.concurrent.duration.Duration;
17+
import static akka.http.javadsl.server.PathMatchers.*;
18+
19+
class UserRoutes extends AllDirectives {
20+
21+
private final ActorRef userActor;
22+
23+
Timeout timeout = new Timeout(Duration.create(5, TimeUnit.SECONDS));
24+
25+
UserRoutes(ActorRef userActor) {
26+
this.userActor = userActor;
27+
}
28+
29+
Route routes() {
30+
return path("users", this::postUser)
31+
.orElse(path(segment("users").slash(longSegment()), id ->
32+
route(getUser(id),
33+
deleteUser(id))));
34+
}
35+
36+
private Route getUser(Long id) {
37+
return get(() -> {
38+
CompletionStage<Optional<User>> user = PatternsCS.ask(userActor, new UserMessages.GetUser(id), timeout)
39+
.thenApply(obj -> (Optional<User>) obj);
40+
41+
return onSuccess(() -> user, performed -> {
42+
if (performed.isPresent())
43+
return complete(StatusCodes.OK, performed.get(), Jackson.marshaller());
44+
else
45+
return complete(StatusCodes.NOT_FOUND);
46+
});
47+
});
48+
}
49+
50+
private Route deleteUser(Long id) {
51+
return delete(() -> {
52+
CompletionStage<ActionPerformed> userDeleted = PatternsCS.ask(userActor, new UserMessages.DeleteUser(id), timeout)
53+
.thenApply(obj -> (ActionPerformed) obj);
54+
55+
return onSuccess(() -> userDeleted, performed -> {
56+
return complete(StatusCodes.OK, performed, Jackson.marshaller());
57+
});
58+
});
59+
}
60+
61+
private Route postUser() {
62+
return route(post(() -> entity(Jackson.unmarshaller(User.class), user -> {
63+
CompletionStage<ActionPerformed> userCreated = PatternsCS.ask(userActor, new CreateUser(user), timeout)
64+
.thenApply(obj -> (ActionPerformed) obj);
65+
66+
return onSuccess(() -> userCreated, performed -> {
67+
return complete(StatusCodes.CREATED, performed, Jackson.marshaller());
68+
});
69+
})));
70+
}
71+
72+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.baeldung.akkahttp;
2+
3+
public class UserService {
4+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.baeldung.akkahttp;
2+
3+
import akka.actor.ActorRef;
4+
import akka.actor.ActorSystem;
5+
import akka.http.javadsl.model.ContentTypes;
6+
import akka.http.javadsl.model.HttpEntities;
7+
import akka.http.javadsl.model.HttpRequest;
8+
import akka.http.javadsl.testkit.JUnitRouteTest;
9+
import akka.http.javadsl.testkit.TestRoute;
10+
import org.junit.Test;
11+
12+
public class UserRoutesUnitTest extends JUnitRouteTest {
13+
14+
ActorSystem system = ActorSystem.create("helloAkkaHttpServer");
15+
16+
ActorRef userActorRef = system.actorOf(UserActor.props(), "userActor");
17+
18+
TestRoute appRoute = testRoute(new UserRoutes(userActorRef).routes());
19+
20+
@Test
21+
public void whenRequest_thenActorResponds() {
22+
23+
appRoute.run(HttpRequest.GET("/users/1"))
24+
.assertEntity(alice())
25+
.assertStatusCode(200);
26+
27+
appRoute.run(HttpRequest.GET("/users/42"))
28+
.assertStatusCode(404);
29+
30+
appRoute.run(HttpRequest.DELETE("/users/1"))
31+
.assertStatusCode(200);
32+
33+
appRoute.run(HttpRequest.DELETE("/users/42"))
34+
.assertStatusCode(200);
35+
36+
appRoute.run(HttpRequest.POST("/users")
37+
.withEntity(HttpEntities.create(ContentTypes.APPLICATION_JSON, zaphod())))
38+
.assertStatusCode(201);
39+
40+
}
41+
42+
private String alice() {
43+
return "{\"id\":1,\"name\":\"Alice\"}";
44+
}
45+
46+
private String zaphod() {
47+
return "{\"id\":42,\"name\":\"Zaphod\"}";
48+
}
49+
50+
}

0 commit comments

Comments
 (0)