This repository has been archived by the owner on Apr 30, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 34
Created separate recipe for cassandra write and postgres read side #66
Open
marvinmarnold
wants to merge
1
commit into
lagom:master
Choose a base branch
from
marvinmarnold:postgres-read
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
4 changes: 4 additions & 0 deletions
4
mixed-persistence/mixed-persistence-java-sbt-postgres/.sbtopts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
-J-Xms512M | ||
-J-Xmx4096M | ||
-J-Xss2M | ||
-J-XX:MaxMetaspaceSize=1024M |
61 changes: 61 additions & 0 deletions
61
mixed-persistence/mixed-persistence-java-sbt-postgres/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Mixed Persistence Service with PostgreSQL | ||
This recipe demonstrates how to create a service in Lagom for Java that uses Cassandra for write-side persistence and JPA for a read-side view. | ||
It was inspired by the | ||
[Mixed Persistence Java SBT](https://github.com/marvinmarnold/lagom-recipes/tree/master/mixed-persistence/mixed-persistence-java-sbt) recipe. | ||
It has been modified to use a PostgreSQL read-side instead of H2. | ||
|
||
## Implementation details | ||
|
||
The key changes are in [`application.conf`](hello-impl/src/main/resources/application.conf) and [`HelloModule`](hello-impl/src/main/java/com/lightbend/lagom/recipes/mixedpersistence/hello/impl/HelloModule.java). | ||
|
||
Specifcally, `JdbcPersistenceModule` is explicitly disabled: | ||
|
||
``` | ||
play.modules.disabled += com.lightbend.lagom.javadsl.persistence.jdbc.JdbcPersistenceModule | ||
``` | ||
|
||
Then, an explicit binding for the JDBC offset store is added back: | ||
|
||
```java | ||
bind(SlickOffsetStore.class).to(JavadslJdbcOffsetStore.class); | ||
``` | ||
|
||
### Supporting PostgreSQL instead of H2 | ||
1. Add `lagom.persistence.jdbc.create-tables.auto = false` to application.conf | ||
2. Create a PostgreSQL db (note this example runs on the host at post 5431): `docker run -p 5431:5432 --name psql1 -e POSTGRES_PASSWORD=somethingsknown -d postgres | ||
3. Manually create the offset table: | ||
``` | ||
CREATE TABLE read_side_offsets ( | ||
read_side_id VARCHAR(255), tag VARCHAR(255), | ||
sequence_offset bytea, time_uuid_offset char(36), | ||
PRIMARY KEY (read_side_id, tag) | ||
) | ||
``` | ||
|
||
## Testing the recipe | ||
|
||
You can test this recipe using 2 separate terminals. | ||
|
||
On one terminal start the service: | ||
|
||
``` | ||
sbt runAll | ||
``` | ||
|
||
On a separate terminal, use `curl` to trigger some events in `HelloService`: | ||
|
||
``` | ||
curl -H "Content-Type: application/json" -X POST -d '{"message": "Hi"}' http://localhost:9000/api/hello/Alice | ||
curl -H "Content-Type: application/json" -X POST -d '{"message": "Good day"}' http://localhost:9000/api/hello/Bob | ||
curl -H "Content-Type: application/json" -X POST -d '{"message": "Hi"}' http://localhost:9000/api/hello/Carol | ||
curl -H "Content-Type: application/json" -X POST -d '{"message": "Howdy"}' http://localhost:9000/api/hello/David | ||
``` | ||
|
||
After a few seconds, use `curl` to retrieve a list of all of the stored greetings: | ||
|
||
``` | ||
curl http://localhost:9000/api/greetings | ||
[{"id":"Alice","message":"Hi"},{"id":"Bob","message":"Good day"},{"id":"Carol","message":"Hi"},{"id":"David","message":"Howdy"}] | ||
``` | ||
|
||
This is eventually consistent, so it might take a few tries before you see all of the results. |
47 changes: 47 additions & 0 deletions
47
mixed-persistence/mixed-persistence-java-sbt-postgres/build.sbt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import scala.concurrent.duration._ | ||
|
||
organization in ThisBuild := "com.lightbend.lagom.recipes" | ||
version in ThisBuild := "1.0-SNAPSHOT" | ||
|
||
// the Scala version that will be used for cross-compiled libraries | ||
scalaVersion in ThisBuild := "2.12.4" | ||
|
||
lazy val `hello` = (project in file(".")) | ||
.aggregate(`hello-api`, `hello-impl`) | ||
|
||
lazy val `hello-api` = (project in file("hello-api")) | ||
.settings(common: _*) | ||
.settings( | ||
libraryDependencies ++= Seq( | ||
lagomJavadslApi, | ||
lombok | ||
) | ||
) | ||
|
||
val lombok = "org.projectlombok" % "lombok" % "1.16.10" | ||
val postgresjdbc = "org.postgresql" % "postgresql" % "42.2.5" | ||
val hibernate = "org.hibernate" % "hibernate-core" % "5.2.12.Final" | ||
|
||
lazy val `hello-impl` = (project in file("hello-impl")) | ||
.enablePlugins(LagomJava) | ||
.settings(common: _*) | ||
.settings( | ||
libraryDependencies ++= Seq( | ||
lagomJavadslPersistenceCassandra, | ||
lagomJavadslPersistenceJpa, | ||
lagomJavadslTestKit, | ||
lombok, | ||
postgresjdbc, | ||
hibernate | ||
) | ||
) | ||
.settings(lagomForkedTestSettings: _*) | ||
.dependsOn(`hello-api`) | ||
|
||
|
||
def common = Seq( | ||
javacOptions in compile += "-parameters" | ||
) | ||
|
||
lagomKafkaEnabled in ThisBuild := false | ||
lagomCassandraMaxBootWaitingTime in ThisBuild := 60.seconds |
9 changes: 9 additions & 0 deletions
9
...src/main/java/com/lightbend/lagom/recipes/mixedpersistence/hello/api/GreetingMessage.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.lightbend.lagom.recipes.mixedpersistence.hello.api; | ||
|
||
import lombok.NonNull; | ||
import lombok.Value; | ||
|
||
@Value | ||
public final class GreetingMessage { | ||
@NonNull String message; | ||
} |
69 changes: 69 additions & 0 deletions
69
...pi/src/main/java/com/lightbend/lagom/recipes/mixedpersistence/hello/api/HelloService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package com.lightbend.lagom.recipes.mixedpersistence.hello.api; | ||
|
||
import akka.Done; | ||
import akka.NotUsed; | ||
import com.lightbend.lagom.javadsl.api.Descriptor; | ||
import com.lightbend.lagom.javadsl.api.Service; | ||
import com.lightbend.lagom.javadsl.api.ServiceCall; | ||
import org.pcollections.PSequence; | ||
|
||
import static com.lightbend.lagom.javadsl.api.Service.named; | ||
import static com.lightbend.lagom.javadsl.api.Service.pathCall; | ||
|
||
/** | ||
* The hello service interface. | ||
* <p> | ||
* This describes everything that Lagom needs to know about how to serve and | ||
* consume the HelloService. | ||
*/ | ||
public interface HelloService extends Service { | ||
|
||
/** | ||
* Example: curl http://localhost:9000/api/hello/Alice | ||
*/ | ||
ServiceCall<NotUsed, String> hello(String id); | ||
|
||
/** | ||
* Examples: | ||
* curl -H "Content-Type: application/json" -X POST -d '{"message": "Hi"}' http://localhost:9000/api/hello/Alice | ||
* curl -H "Content-Type: application/json" -X POST -d '{"message": "Good day"}' http://localhost:9000/api/hello/Bob | ||
* curl -H "Content-Type: application/json" -X POST -d '{"message": "Hi"}' http://localhost:9000/api/hello/Carol | ||
* curl -H "Content-Type: application/json" -X POST -d '{"message": "Howdy"}' http://localhost:9000/api/hello/David | ||
*/ | ||
ServiceCall<GreetingMessage, Done> useGreeting(String id); | ||
|
||
/** | ||
* Example: curl http://localhost:9000/api/greetings | ||
* Response (pretty-printed): | ||
* <pre> | ||
* [ | ||
* { | ||
* "id": "Alice", | ||
* "message": "Hi" | ||
* }, | ||
* { | ||
* "id": "Bob", | ||
* "message": "Good day" | ||
* }, | ||
* { | ||
* "id": "Carol", | ||
* "message": "Hi" | ||
* }, | ||
* { | ||
* "id": "David", | ||
* "message": "Howdy" | ||
* } | ||
* ] | ||
* </pre> | ||
*/ | ||
ServiceCall<NotUsed, PSequence<UserGreeting>> allGreetings(); | ||
|
||
@Override | ||
default Descriptor descriptor() { | ||
return named("hello").withCalls( | ||
pathCall("/api/hello/:id", this::hello), | ||
pathCall("/api/hello/:id", this::useGreeting), | ||
pathCall("/api/greetings", this::allGreetings) | ||
).withAutoAcl(true); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
...pi/src/main/java/com/lightbend/lagom/recipes/mixedpersistence/hello/api/UserGreeting.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.lightbend.lagom.recipes.mixedpersistence.hello.api; | ||
|
||
import lombok.NonNull; | ||
import lombok.Value; | ||
|
||
@Value | ||
public class UserGreeting { | ||
@NonNull String id; | ||
@NonNull String message; | ||
} |
32 changes: 32 additions & 0 deletions
32
...pl/src/main/java/com/lightbend/lagom/recipes/mixedpersistence/hello/impl/HelloModule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.lightbend.lagom.recipes.mixedpersistence.hello.impl; | ||
|
||
import com.google.inject.AbstractModule; | ||
import com.lightbend.lagom.internal.javadsl.persistence.jdbc.JavadslJdbcOffsetStore; | ||
import com.lightbend.lagom.internal.javadsl.persistence.jdbc.JdbcReadSideImpl; | ||
import com.lightbend.lagom.internal.javadsl.persistence.jdbc.JdbcSessionImpl; | ||
import com.lightbend.lagom.internal.javadsl.persistence.jdbc.SlickProvider; | ||
import com.lightbend.lagom.internal.persistence.jdbc.SlickOffsetStore; | ||
import com.lightbend.lagom.javadsl.persistence.jdbc.JdbcReadSide; | ||
import com.lightbend.lagom.javadsl.persistence.jdbc.JdbcSession; | ||
import com.lightbend.lagom.javadsl.server.ServiceGuiceSupport; | ||
import com.lightbend.lagom.recipes.mixedpersistence.hello.api.HelloService; | ||
import com.lightbend.lagom.recipes.mixedpersistence.hello.impl.readside.Greetings; | ||
import com.lightbend.lagom.javadsl.persistence.jdbc.GuiceSlickProvider; | ||
/** | ||
* The module that binds the HelloService so that it can be served. | ||
*/ | ||
public class HelloModule extends AbstractModule implements ServiceGuiceSupport { | ||
@Override | ||
protected void configure() { | ||
bindService(HelloService.class, HelloServiceImpl.class); | ||
bind(Greetings.class).asEagerSingleton(); | ||
|
||
// JdbcPersistenceModule is disabled in application.conf to avoid conflicts with CassandraPersistenceModule. | ||
// We need to explicitly re-add the SlickOffsetStore binding that is required by the JpaPersistenceModule. | ||
bind(SlickProvider.class).toProvider(GuiceSlickProvider.class); | ||
bind(SlickOffsetStore.class).to(JavadslJdbcOffsetStore.class); | ||
// To use JdbcReadSide instead of JpaReadSide, uncomment these lines: | ||
// bind(JdbcReadSide.class).to(JdbcReadSideImpl.class); | ||
// bind(JdbcSession.class).to(JdbcSessionImpl.class); | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
...c/main/java/com/lightbend/lagom/recipes/mixedpersistence/hello/impl/HelloServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package com.lightbend.lagom.recipes.mixedpersistence.hello.impl; | ||
|
||
import akka.Done; | ||
import akka.NotUsed; | ||
import com.lightbend.lagom.javadsl.api.ServiceCall; | ||
import com.lightbend.lagom.javadsl.persistence.PersistentEntityRef; | ||
import com.lightbend.lagom.javadsl.persistence.PersistentEntityRegistry; | ||
import com.lightbend.lagom.recipes.mixedpersistence.hello.api.GreetingMessage; | ||
import com.lightbend.lagom.recipes.mixedpersistence.hello.api.HelloService; | ||
import com.lightbend.lagom.recipes.mixedpersistence.hello.api.UserGreeting; | ||
import com.lightbend.lagom.recipes.mixedpersistence.hello.impl.entity.HelloCommand; | ||
import com.lightbend.lagom.recipes.mixedpersistence.hello.impl.entity.HelloCommand.Hello; | ||
import com.lightbend.lagom.recipes.mixedpersistence.hello.impl.entity.HelloCommand.UseGreetingMessage; | ||
import com.lightbend.lagom.recipes.mixedpersistence.hello.impl.entity.HelloEntity; | ||
import com.lightbend.lagom.recipes.mixedpersistence.hello.impl.readside.Greetings; | ||
import org.pcollections.PSequence; | ||
|
||
import javax.inject.Inject; | ||
import java.util.concurrent.CompletionStage; | ||
|
||
/** | ||
* Implementation of the HelloService. | ||
*/ | ||
public class HelloServiceImpl implements HelloService { | ||
private final PersistentEntityRegistry persistentEntityRegistry; | ||
private final Greetings greetings; | ||
|
||
@Inject | ||
public HelloServiceImpl(PersistentEntityRegistry persistentEntityRegistry, Greetings greetings) { | ||
this.persistentEntityRegistry = persistentEntityRegistry; | ||
this.greetings = greetings; | ||
persistentEntityRegistry.register(HelloEntity.class); | ||
} | ||
|
||
@Override | ||
public ServiceCall<NotUsed, String> hello(String id) { | ||
return request -> { | ||
// Look up the hello world entity for the given ID. | ||
PersistentEntityRef<HelloCommand> ref = persistentEntityRegistry.refFor(HelloEntity.class, id); | ||
// Ask the entity the Hello command. | ||
return ref.ask(new Hello(id)); | ||
}; | ||
} | ||
|
||
@Override | ||
public ServiceCall<GreetingMessage, Done> useGreeting(String id) { | ||
return request -> { | ||
// Look up the hello world entity for the given ID. | ||
PersistentEntityRef<HelloCommand> ref = persistentEntityRegistry.refFor(HelloEntity.class, id); | ||
// Tell the entity to use the greeting message specified. | ||
return ref.ask(new UseGreetingMessage(request.getMessage())); | ||
}; | ||
|
||
} | ||
|
||
@Override | ||
public ServiceCall<NotUsed, PSequence<UserGreeting>> allGreetings() { | ||
return request -> null; | ||
// return request -> CompletedFuture.oTreePVector.empty(); | ||
// return request -> greetings.all(); | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
...ain/java/com/lightbend/lagom/recipes/mixedpersistence/hello/impl/entity/HelloCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.lightbend.lagom.recipes.mixedpersistence.hello.impl.entity; | ||
|
||
import akka.Done; | ||
import com.lightbend.lagom.javadsl.persistence.PersistentEntity; | ||
import com.lightbend.lagom.serialization.CompressedJsonable; | ||
import com.lightbend.lagom.serialization.Jsonable; | ||
import lombok.NonNull; | ||
import lombok.Value; | ||
|
||
/** | ||
* This interface defines all the commands that the HelloEntity supports. | ||
* <p> | ||
* By convention, the commands should be inner classes of the interface, which | ||
* makes it simple to get a complete picture of what commands an entity | ||
* supports. | ||
*/ | ||
public interface HelloCommand extends Jsonable { | ||
|
||
/** | ||
* A command to switch the greeting message. | ||
* <p> | ||
* It has a reply type of {@link akka.Done}, which is sent back to the caller | ||
* when all the events emitted by this command are successfully persisted. | ||
*/ | ||
@Value | ||
final class UseGreetingMessage implements HelloCommand, CompressedJsonable, PersistentEntity.ReplyType<Done> { | ||
@NonNull String message; | ||
} | ||
|
||
/** | ||
* A command to say hello to someone using the current greeting message. | ||
* <p> | ||
* The reply type is String, and will contain the message to say to that | ||
* person. | ||
*/ | ||
@Value | ||
final class Hello implements HelloCommand, PersistentEntity.ReplyType<String> { | ||
@NonNull String name; | ||
} | ||
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.