Last active
September 6, 2023 04:07
-
-
Save aleixmorgadas/be30c6030db2fd9b560ac31cb873f68c to your computer and use it in GitHub Desktop.
Revisions
-
aleixmorgadas revised this gist
Sep 6, 2023 . 2 changed files with 38 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1 @@ # Entity Event Sourced with Spring Boot and MongoDB This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,37 @@ package dev.aleixmorgadas.eventsourcedmongo.domain; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.testcontainers.containers.MongoDBContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; import static org.assertj.core.api.Assertions.assertThat; @DataMongoTest @Testcontainers public class ProfileRepositoryTest { @Container @ServiceConnection static MongoDBContainer mongo = new MongoDBContainer(DockerImageName.parse("mongo:6.0.7")); @Autowired ProfileRepository repository; @Test void savesProfileIntoDB() { var profile = Profile.of("Aleix"); profile.withAge(30); repository.save(profile); var id = profile.id; var savedProfile = repository.findById(id).orElseThrow(); assertThat(savedProfile.events).hasSize(2); assertThat(savedProfile.name()).isEqualTo("Aleix"); assertThat(savedProfile.age()).isEqualTo(30); } } -
aleixmorgadas revised this gist
Aug 25, 2023 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -27,6 +27,7 @@ public Profile(String id, String name) { void apply(Event event) { events.add(event); // update with pattern matching in Java 21 if (event instanceof Event.Created created) { on(created); } else if (event instanceof Event.AgeUpdated ageUpdated) { -
aleixmorgadas revised this gist
Aug 25, 2023 . 1 changed file with 7 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -16,7 +16,7 @@ public class Profile { final List<Event> events = new ArrayList<>(); public Profile(String id, String name) { apply(new Event.Created(id, name)); } @PersistenceCreator @@ -27,16 +27,19 @@ public Profile(String id, String name) { void apply(Event event) { events.add(event); if (event instanceof Event.Created created) { on(created); } else if (event instanceof Event.AgeUpdated ageUpdated) { on(ageUpdated); } } void on(Event.Created created) { id = created.id; state.name = created.name; } void on(Event.AgeUpdated ageUpdated) { state.age = ageUpdated.age(); } @@ -53,7 +56,7 @@ public int age() { } public void withAge(int age) { apply(new Event.AgeUpdated(age)); } static class State { -
aleixmorgadas created this gist
Aug 25, 2023 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,68 @@ package dev.aleixmorgadas.eventsourcedmongo.domain; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.annotation.Transient; import org.springframework.data.mongodb.core.mapping.Document; import java.util.*; @Document public class Profile { @Id String id; @Transient final State state = new State(); final List<Event> events = new ArrayList<>(); public Profile(String id, String name) { on(new Event.Created(id, name)); } @PersistenceCreator Profile(String id, List<Event> events) { this.id = id; events.forEach(this::apply); } void apply(Event event) { events.add(event); } void on(Event.Created created) { events.add(created); id = created.id; state.name = created.name; } void on(Event.AgeUpdated ageUpdated) { events.add(ageUpdated); state.age = ageUpdated.age(); } String name() { return state.name; } public static Profile of(String name) { return new Profile(UUID.randomUUID().toString(), name); } public int age() { return state.age; } public void withAge(int age) { on(new Event.AgeUpdated(age)); } static class State { String name; int age; } sealed interface Event { record Created(String id, String name) implements Event {} record AgeUpdated(int age) implements Event {} } } This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,26 @@ package dev.aleixmorgadas.eventsourcedmongo.domain; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; public class ProfileTest { @Test void createsAProfile() { var profile = Profile.of("Aleix"); assertThat(profile.name()).isEqualTo("Aleix"); assertThat(profile.events).hasSize(1); } @Test void addsAge() { var profile = Profile.of("Aleix"); profile.withAge(30); assertThat(profile.age()).isEqualTo(30); assertThat(profile.events).hasSize(2); assertThat(profile.events.get(1)).isInstanceOf(Profile.Event.AgeUpdated.class); } }