diff --git a/akka-docs/src/main/paradox/typed/persistence.md b/akka-docs/src/main/paradox/typed/persistence.md index 33c17607fa..66f1d3b4f5 100644 --- a/akka-docs/src/main/paradox/typed/persistence.md +++ b/akka-docs/src/main/paradox/typed/persistence.md @@ -194,36 +194,17 @@ Java : @@snip [BlogPostExample.java](/akka-persistence-typed/src/test/java/jdocs/akka/persistence/typed/BlogPostExample.java) { #commands } @java[The commandler handler to process each command is decided by the state class (or state predicate) that is -given to the `commandHandlerBuilder` and the match cases in the builders. Several builders can be composed with `orElse`:] +given to the `forStateType` of the `CommandHandlerBuilder` and the match cases in the builders.] @scala[The command handler to process each command is decided by first looking at the state and then the command. -It typically becomes two levels of pattern matching, first on the state and then on the command. Delegating to methods -is a good practise because the one-line cases give a nice overview of the message dispatch.] - -@@@ div { .group-scala } +It typically becomes two levels of pattern matching, first on the state and then on the command.] +Delegating to methods is a good practise because the one-line cases give a nice overview of the message dispatch. Scala : @@snip [BlogPostExample.scala](/akka-persistence-typed/src/test/scala/docs/akka/persistence/typed/BlogPostExample.scala) { #command-handler } -@@@ - -@@@ div { .group-java } - -TODO rewrite this example to be more like the Scala example - Java : @@snip [BlogPostExample.java](/akka-persistence-typed/src/test/java/jdocs/akka/persistence/typed/BlogPostExample.java) { #command-handler } -The `CommandHandlerBuilder` for a post that hasn't been initialized with content: - -Java -: @@snip [BlogPostExample.java](/akka-persistence-typed/src/test/java/jdocs/akka/persistence/typed/BlogPostExample.java) { #initial-command-handler } - -And a different `CommandHandlerBuilder` for after the post content has been added: - -Java -: @@snip [BlogPostExample.java](/akka-persistence-typed/src/test/java/jdocs/akka/persistence/typed/BlogPostExample.java) { #post-added-command-handler } - -@@@ The event handler: diff --git a/akka-persistence-typed/src/test/java/jdocs/akka/persistence/typed/BlogPostExample.java b/akka-persistence-typed/src/test/java/jdocs/akka/persistence/typed/BlogPostExample.java index f97c2fdc36..7768ea9678 100644 --- a/akka-persistence-typed/src/test/java/jdocs/akka/persistence/typed/BlogPostExample.java +++ b/akka-persistence-typed/src/test/java/jdocs/akka/persistence/typed/BlogPostExample.java @@ -12,12 +12,12 @@ import akka.actor.typed.javadsl.Behaviors; import akka.persistence.typed.PersistenceId; import akka.persistence.typed.javadsl.*; -public class BlogPostExample { +public interface BlogPostExample { // #event interface BlogEvent {} - public static class PostAdded implements BlogEvent { + public class PostAdded implements BlogEvent { private final String postId; private final PostContent content; @@ -27,7 +27,7 @@ public class BlogPostExample { } } - public static class BodyChanged implements BlogEvent { + public class BodyChanged implements BlogEvent { private final String postId; private final String newBody; @@ -37,7 +37,7 @@ public class BlogPostExample { } } - public static class Published implements BlogEvent { + public class Published implements BlogEvent { private final String postId; public Published(String postId) { @@ -53,35 +53,43 @@ public class BlogPostExample { INSTANCE } - public static class DraftState implements BlogState { - final PostContent postContent; + public class DraftState implements BlogState { + final PostContent content; - DraftState(PostContent postContent) { - this.postContent = postContent; + DraftState(PostContent content) { + this.content = content; } public DraftState withContent(PostContent newContent) { return new DraftState(newContent); } + public DraftState withBody(String newBody) { + return withContent(new PostContent(postId(), content.title, newBody)); + } + public String postId() { - return postContent.postId; + return content.postId; } } - public static class PublishedState implements BlogState { - final PostContent postContent; + public class PublishedState implements BlogState { + final PostContent content; - PublishedState(PostContent postContent) { - this.postContent = postContent; + PublishedState(PostContent content) { + this.content = content; } public PublishedState withContent(PostContent newContent) { return new PublishedState(newContent); } + public PublishedState withBody(String newBody) { + return withContent(new PostContent(postId(), content.title, newBody)); + } + public String postId() { - return postContent.postId; + return content.postId; } } // #state @@ -89,7 +97,7 @@ public class BlogPostExample { // #commands public interface BlogCommand {} // #reply-command - public static class AddPost implements BlogCommand { + public class AddPost implements BlogCommand { final PostContent content; final ActorRef replyTo; @@ -99,7 +107,7 @@ public class BlogPostExample { } } - public static class AddPostDone implements BlogCommand { + public class AddPostDone implements BlogCommand { final String postId; public AddPostDone(String postId) { @@ -107,7 +115,7 @@ public class BlogPostExample { } } // #reply-command - public static class GetPost implements BlogCommand { + public class GetPost implements BlogCommand { final ActorRef replyTo; public GetPost(ActorRef replyTo) { @@ -115,7 +123,7 @@ public class BlogPostExample { } } - public static class ChangeBody implements BlogCommand { + public class ChangeBody implements BlogCommand { final String newBody; final ActorRef replyTo; @@ -125,7 +133,7 @@ public class BlogPostExample { } } - public static class Publish implements BlogCommand { + public class Publish implements BlogCommand { final ActorRef replyTo; public Publish(ActorRef replyTo) { @@ -133,7 +141,7 @@ public class BlogPostExample { } } - public static class PostContent implements BlogCommand { + public class PostContent implements BlogCommand { final String postId; final String title; final String body; @@ -147,97 +155,74 @@ public class BlogPostExample { // #commands // #behavior - public static class BlogBehavior extends EventSourcedBehavior { - // #behavior + public class BlogBehavior extends EventSourcedBehavior { - private final ActorContext ctx; - - public BlogBehavior(PersistenceId persistenceId, ActorContext ctx) { + public BlogBehavior(PersistenceId persistenceId) { super(persistenceId); - this.ctx = ctx; } - // #initial-command-handler - private CommandHandlerBuilderByState - initialCommandHandler() { - return newCommandHandlerBuilder() - .forStateType(BlankState.class) - .matchCommand( - AddPost.class, - (state, cmd) -> { - // #reply - PostAdded event = new PostAdded(cmd.content.postId, cmd.content); - return Effect() - .persist(event) - .thenRun(() -> cmd.replyTo.tell(new AddPostDone(cmd.content.postId))); - // #reply - }); - } - // #initial-command-handler - - // #post-added-command-handler - private CommandHandlerBuilderByState - draftCommandHandler() { - return newCommandHandlerBuilder() - .forStateType(DraftState.class) - .matchCommand( - ChangeBody.class, - (state, cmd) -> { - BodyChanged event = new BodyChanged(state.postId(), cmd.newBody); - return Effect().persist(event).thenRun(() -> cmd.replyTo.tell(Done.getInstance())); - }) - .matchCommand( - Publish.class, - (state, cmd) -> - Effect() - .persist(new Published(state.postId())) - .thenRun( - () -> { - System.out.println("Blog post published: " + state.postId()); - cmd.replyTo.tell(Done.getInstance()); - })) - .matchCommand( - GetPost.class, - (state, cmd) -> { - cmd.replyTo.tell(state.postContent); - return Effect().none(); - }); - } - - private CommandHandlerBuilderByState - publishedCommandHandler() { - return newCommandHandlerBuilder() - .forStateType(PublishedState.class) - .matchCommand( - ChangeBody.class, - (state, cmd) -> { - BodyChanged event = new BodyChanged(state.postId(), cmd.newBody); - return Effect().persist(event).thenRun(() -> cmd.replyTo.tell(Done.getInstance())); - }) - .matchCommand( - GetPost.class, - (state, cmd) -> { - cmd.replyTo.tell(state.postContent); - return Effect().none(); - }); - } - - private CommandHandlerBuilderByState - commonCommandHandler() { - return newCommandHandlerBuilder() - .forStateType(BlogState.class) - .matchCommand(AddPost.class, (state, cmd) -> Effect().unhandled()); - } - // #post-added-command-handler + // #behavior // #command-handler @Override public CommandHandler commandHandler() { - return initialCommandHandler() - .orElse(draftCommandHandler()) - .orElse(publishedCommandHandler()) - .orElse(commonCommandHandler()) - .build(); + CommandHandlerBuilder builder = newCommandHandlerBuilder(); + + builder.forStateType(BlankState.class).matchCommand(AddPost.class, this::addPost); + + builder + .forStateType(DraftState.class) + .matchCommand(ChangeBody.class, this::changeBody) + .matchCommand(Publish.class, this::publish) + .matchCommand(GetPost.class, this::getPost); + + builder + .forStateType(PublishedState.class) + .matchCommand(ChangeBody.class, this::changeBody) + .matchCommand(GetPost.class, this::getPost); + + builder.forAnyState().matchCommand(AddPost.class, (state, cmd) -> Effect().unhandled()); + + return builder.build(); + } + + private Effect addPost(AddPost cmd) { + // #reply + PostAdded event = new PostAdded(cmd.content.postId, cmd.content); + return Effect() + .persist(event) + .thenRun(() -> cmd.replyTo.tell(new AddPostDone(cmd.content.postId))); + // #reply + } + + private Effect changeBody(DraftState state, ChangeBody cmd) { + BodyChanged event = new BodyChanged(state.postId(), cmd.newBody); + return Effect().persist(event).thenRun(() -> cmd.replyTo.tell(Done.getInstance())); + } + + private Effect changeBody(PublishedState state, ChangeBody cmd) { + BodyChanged event = new BodyChanged(state.postId(), cmd.newBody); + return Effect().persist(event).thenRun(() -> cmd.replyTo.tell(Done.getInstance())); + } + + private Effect publish(DraftState state, Publish cmd) { + return Effect() + .persist(new Published(state.postId())) + .thenRun( + () -> { + System.out.println("Blog post published: " + state.postId()); + cmd.replyTo.tell(Done.getInstance()); + }); + } + + private Effect getPost(DraftState state, GetPost cmd) { + cmd.replyTo.tell(state.content); + return Effect().none(); + } + + private Effect getPost(PublishedState state, GetPost cmd) { + cmd.replyTo.tell(state.content); + return Effect().none(); } // #command-handler @@ -253,20 +238,12 @@ public class BlogPostExample { builder .forStateType(DraftState.class) - .matchEvent( - BodyChanged.class, - (state, chg) -> - state.withContent( - new PostContent(state.postId(), state.postContent.title, chg.newBody))) - .matchEvent(Published.class, (state, event) -> new PublishedState(state.postContent)); + .matchEvent(BodyChanged.class, (state, chg) -> state.withBody(chg.newBody)) + .matchEvent(Published.class, (state, event) -> new PublishedState(state.content)); builder .forStateType(PublishedState.class) - .matchEvent( - BodyChanged.class, - (state, chg) -> - state.withContent( - new PostContent(state.postId(), state.postContent.title, chg.newBody))); + .matchEvent(BodyChanged.class, (state, chg) -> state.withBody(chg.newBody)); return builder.build(); } @@ -274,7 +251,7 @@ public class BlogPostExample { // #behavior public static Behavior behavior(String entityId) { - return Behaviors.setup(ctx -> new BlogBehavior(new PersistenceId("Blog-" + entityId), ctx)); + return Behaviors.setup(ctx -> new BlogBehavior(new PersistenceId("Blog-" + entityId))); } @Override