From eae48a0734850b95df911b02e84e1fe1d3e129d3 Mon Sep 17 00:00:00 2001 From: Oskar Dudycz Date: Sat, 4 May 2024 13:05:31 +0200 Subject: [PATCH] This is not your uncle Java Added slimmed version of Java Exercise using latest Java 22 pattern matching improvements --- .../esdb/tools/EventStoreDBTest.java | 1 + .../e05_business_logic/tools/EventStore.java | 1 + .../immutable/ShoppingCart.java | 76 ------- .../tools/EventStore.java | 1 + .../core/serializer/DefaultSerializer.java | 1 + .../core/serializer/DefaultSerializer.java | 1 + .../tools/Database.java | 1 + .../tools/Database.java | 1 + .../tools/Database.java | 1 + .../esdb/AppendingEventsTests.java | 3 +- .../esdb/tools/EventStoreDBTest.java | 1 + .../e05_business_logic/tools/EventStore.java | 1 + .../immutable/BusinessLogicTests.java | 73 +++---- .../immutable/FunctionalTools.java | 16 ++ .../immutable/ShoppingCart.java | 202 ++++++------------ .../immutable/ShoppingCartDecider.java | 81 +++++++ .../immutable/ShoppingCartEvent.java | 30 --- .../immutable/ShoppingCartService.java | 103 --------- .../immutable/productItems/ProductItems.java | 66 +++--- .../tools/EventStore.java | 1 + .../core/serializer/DefaultSerializer.java | 1 + .../core/serializer/DefaultSerializer.java | 1 + .../tools/Database.java | 1 + .../tools/Database.java | 1 + .../tools/Database.java | 1 + 25 files changed, 233 insertions(+), 433 deletions(-) create mode 100644 workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCartDecider.java delete mode 100644 workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCartService.java diff --git a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e04_getting_state_from_events/esdb/tools/EventStoreDBTest.java b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e04_getting_state_from_events/esdb/tools/EventStoreDBTest.java index 54278e24..ffcdff10 100644 --- a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e04_getting_state_from_events/esdb/tools/EventStoreDBTest.java +++ b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e04_getting_state_from_events/esdb/tools/EventStoreDBTest.java @@ -23,6 +23,7 @@ public abstract class EventStoreDBTest { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);; @BeforeEach diff --git a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e05_business_logic/tools/EventStore.java b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e05_business_logic/tools/EventStore.java index 35ecf57e..97162de0 100644 --- a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e05_business_logic/tools/EventStore.java +++ b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e05_business_logic/tools/EventStore.java @@ -57,6 +57,7 @@ record EventEnvelope(String eventType, String json) { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); } diff --git a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCart.java b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCart.java index 9e1c07c2..4adaa099 100644 --- a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCart.java +++ b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCart.java @@ -78,79 +78,3 @@ case ProductItemRemovedFromShoppingCart(_, var productItem) -> }; } } -// -//static ShoppingCart evolve(EventStoreDBClient eventStore, String streamName) { -// // 1. Add logic here -// ShoppingCart shoppingCart = null; -// -// -// for (var event : getEvents(eventStore, streamName)) { -// switch (event) { -// case ShoppingCartOpened opened -> shoppingCart = new ShoppingCart( -// opened.shoppingCartId(), -// opened.clientId(), -// ShoppingCartStatus.Pending, -// new PricedProductItem[]{}, -// null, -// null -// ); -// case ProductItemAddedToShoppingCart productItemAdded -> -// shoppingCart = new ShoppingCart( -// shoppingCart.id(), -// shoppingCart.clientId(), -// shoppingCart.status(), -// Stream.concat(Arrays.stream(shoppingCart.productItems()), Stream.of(productItemAdded.productItem())) -// .collect(groupingByOrdered(PricedProductItem::productId)) -// .entrySet().stream() -// .map(group -> group.getValue().size() == 1 ? -// group.getValue().get(0) : -// new PricedProductItem( -// group.getKey(), -// group.getValue().stream().mapToInt(PricedProductItem::quantity).sum(), -// group.getValue().get(0).unitPrice() -// ) -// ) -// .toArray(PricedProductItem[]::new), -// shoppingCart.confirmedAt(), -// shoppingCart.canceledAt() -// ); -// case ProductItemRemovedFromShoppingCart productItemRemoved -> -// shoppingCart = new ShoppingCart( -// shoppingCart.id(), -// shoppingCart.clientId(), -// shoppingCart.status(), -// Arrays.stream(shoppingCart.productItems()) -// .map(pi -> pi.productId().equals(productItemRemoved.productItem().productId()) ? -// new PricedProductItem( -// pi.productId(), -// pi.quantity() - productItemRemoved.productItem().quantity(), -// pi.unitPrice() -// ) -// : pi -// ) -// .filter(pi -> pi.quantity > 0) -// .toArray(PricedProductItem[]::new), -// shoppingCart.confirmedAt(), -// shoppingCart.canceledAt() -// ); -// case ShoppingCartConfirmed confirmed -> shoppingCart = new ShoppingCart( -// shoppingCart.id(), -// shoppingCart.clientId(), -// ShoppingCartStatus.Confirmed, -// shoppingCart.productItems(), -// confirmed.confirmedAt(), -// shoppingCart.canceledAt() -// ); -// case ShoppingCartCanceled canceled -> shoppingCart = new ShoppingCart( -// shoppingCart.id(), -// shoppingCart.clientId(), -// ShoppingCartStatus.Canceled, -// shoppingCart.productItems(), -// shoppingCart.confirmedAt(), -// canceled.canceledAt() -// ); -// } -// } -// -// return shoppingCart; -//} diff --git a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/tools/EventStore.java b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/tools/EventStore.java index 27605923..d47f61db 100644 --- a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/tools/EventStore.java +++ b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/tools/EventStore.java @@ -57,6 +57,7 @@ record EventEnvelope(String eventType, String json) { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); } diff --git a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e07_application_logic/esdb/core/serializer/DefaultSerializer.java b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e07_application_logic/esdb/core/serializer/DefaultSerializer.java index e661bf07..86c6dc43 100644 --- a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e07_application_logic/esdb/core/serializer/DefaultSerializer.java +++ b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e07_application_logic/esdb/core/serializer/DefaultSerializer.java @@ -13,5 +13,6 @@ public final class DefaultSerializer { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); } diff --git a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e08_optimistic_concurrency/esdb/core/serializer/DefaultSerializer.java b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e08_optimistic_concurrency/esdb/core/serializer/DefaultSerializer.java index 3b58edda..87a64cfa 100644 --- a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e08_optimistic_concurrency/esdb/core/serializer/DefaultSerializer.java +++ b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e08_optimistic_concurrency/esdb/core/serializer/DefaultSerializer.java @@ -13,5 +13,6 @@ public final class DefaultSerializer { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); } diff --git a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e09_projections_singlestream/tools/Database.java b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e09_projections_singlestream/tools/Database.java index 75e47334..d7abe4e0 100644 --- a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e09_projections_singlestream/tools/Database.java +++ b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e09_projections_singlestream/tools/Database.java @@ -22,6 +22,7 @@ public class Database { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); public void store(Class typeClass, UUID id, Object obj) { diff --git a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e10_projections_singlestream_idempotency/tools/Database.java b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e10_projections_singlestream_idempotency/tools/Database.java index c8914215..f19de549 100644 --- a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e10_projections_singlestream_idempotency/tools/Database.java +++ b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e10_projections_singlestream_idempotency/tools/Database.java @@ -24,6 +24,7 @@ public class Database { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); public void store(Class typeClass, UUID id, Object obj) { diff --git a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e11_projections_singlestream_eventual_consistency/tools/Database.java b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e11_projections_singlestream_eventual_consistency/tools/Database.java index b16ebc22..dddcd2c6 100644 --- a/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e11_projections_singlestream_eventual_consistency/tools/Database.java +++ b/workshops/introduction-to-event-sourcing/exercises/src/test/java/io/eventdriven/introductiontoeventsourcing/e11_projections_singlestream_eventual_consistency/tools/Database.java @@ -27,6 +27,7 @@ public record DataWrapper(Object data, OffsetDateTime validFrom) { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); public void store(Class typeClass, UUID id, Object obj) { diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e03_appending_event/esdb/AppendingEventsTests.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e03_appending_event/esdb/AppendingEventsTests.java index 00a5f852..89293e41 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e03_appending_event/esdb/AppendingEventsTests.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e03_appending_event/esdb/AppendingEventsTests.java @@ -65,7 +65,8 @@ public double totalAmount() { new JsonMapper() .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false); private CompletableFuture appendEvents(EventStoreDBClient eventStore, String streamName, Object[] events) { // 1. Add logic here diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e04_getting_state_from_events/esdb/tools/EventStoreDBTest.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e04_getting_state_from_events/esdb/tools/EventStoreDBTest.java index 54278e24..ffcdff10 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e04_getting_state_from_events/esdb/tools/EventStoreDBTest.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e04_getting_state_from_events/esdb/tools/EventStoreDBTest.java @@ -23,6 +23,7 @@ public abstract class EventStoreDBTest { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);; @BeforeEach diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e05_business_logic/tools/EventStore.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e05_business_logic/tools/EventStore.java index cc00fdd2..07311fb5 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e05_business_logic/tools/EventStore.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e05_business_logic/tools/EventStore.java @@ -57,6 +57,7 @@ record EventEnvelope(String eventType, String json) { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); } diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/BusinessLogicTests.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/BusinessLogicTests.java index d70e9d08..ca069405 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/BusinessLogicTests.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/BusinessLogicTests.java @@ -4,24 +4,24 @@ import io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.tools.EventStore; import org.junit.jupiter.api.Test; +import java.time.OffsetDateTime; import java.util.UUID; import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.FunctionalTools.FoldLeft.foldLeft; import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.productItems.ProductItems.PricedProductItem; import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.productItems.ProductItems.ProductItem; -import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartEvent.*; -import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartService.ShoppingCartCommand.*; -import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartService.handle; +import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCart.Event.*; +import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartDecider.Command.*; +import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartDecider.decide; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; public class BusinessLogicTests { static ShoppingCart getShoppingCart(EventStore eventStore, UUID shoppingCartId) { - var events = eventStore.readStream(ShoppingCartEvent.class, shoppingCartId); + var events = eventStore.readStream(ShoppingCart.Event.class, shoppingCartId); return events.stream() - .collect(foldLeft(ShoppingCart::initial, ShoppingCart::evolve)); + .collect(foldLeft(ShoppingCart.Initial::new, ShoppingCart::evolve)); } @Test @@ -37,45 +37,48 @@ public void runningSequenceOfBusinessLogic_ShouldGenerateSequenceOfEvents() { var shoesPrice = 100; var tShirtPrice = 50; + var pricedTwoPairOfShoes = new PricedProductItem(shoesId, 2, shoesPrice); var pricedPairOfShoes = new PricedProductItem(shoesId, 1, shoesPrice); var pricedTShirt = new PricedProductItem(tShirtId, 1, tShirtPrice); var eventStore = new EventStore(); + var now = OffsetDateTime.now(); // Open - ShoppingCartEvent result = handle(new OpenShoppingCart(shoppingCartId, clientId)); + var shoppingCart = getShoppingCart(eventStore, shoppingCartId); + ShoppingCart.Event result = decide(new Open(shoppingCartId, clientId, now), shoppingCart); eventStore.appendToStream(shoppingCartId, new Object[]{result}); // Add Two Pair of Shoes - var shoppingCart = getShoppingCart(eventStore, shoppingCartId); - result = handle( - FakeProductPriceCalculator.returning(shoesPrice), - new AddProductItemToShoppingCart(shoppingCartId, twoPairsOfShoes), + shoppingCart = getShoppingCart(eventStore, shoppingCartId); + result = decide( + new AddProductItem(shoppingCartId, + FakeProductPriceCalculator.returning(shoesPrice).calculate(twoPairsOfShoes), now), shoppingCart ); eventStore.appendToStream(shoppingCartId, new Object[]{result}); // Add T-Shirt shoppingCart = getShoppingCart(eventStore, shoppingCartId); - result = handle( - FakeProductPriceCalculator.returning(tShirtPrice), - new AddProductItemToShoppingCart(shoppingCartId, tShirt), + result = decide( + new AddProductItem(shoppingCartId, + FakeProductPriceCalculator.returning(tShirtPrice).calculate(tShirt), now), shoppingCart ); eventStore.appendToStream(shoppingCartId, new Object[]{result}); // Remove a pair of shoes shoppingCart = getShoppingCart(eventStore, shoppingCartId); - result = handle( - new RemoveProductItemFromShoppingCart(shoppingCartId, pricedPairOfShoes), + result = decide( + new RemoveProductItem(shoppingCartId, pricedPairOfShoes, now), shoppingCart ); eventStore.appendToStream(shoppingCartId, new Object[]{result}); // Confirm shoppingCart = getShoppingCart(eventStore, shoppingCartId); - result = handle( - new ConfirmShoppingCart(shoppingCartId), + result = decide( + new Confirm(shoppingCartId, now), shoppingCart ); eventStore.appendToStream(shoppingCartId, new Object[]{result}); @@ -83,8 +86,8 @@ public void runningSequenceOfBusinessLogic_ShouldGenerateSequenceOfEvents() { // Try Cancel ShoppingCart finalShoppingCart = getShoppingCart(eventStore, shoppingCartId); assertThrows(IllegalStateException.class, () -> { - var cancelResult = handle( - new CancelShoppingCart(shoppingCartId), + var cancelResult = decide( + new Cancel(shoppingCartId, now), finalShoppingCart ); eventStore.appendToStream(shoppingCartId, new Object[]{cancelResult}); @@ -93,28 +96,14 @@ public void runningSequenceOfBusinessLogic_ShouldGenerateSequenceOfEvents() { shoppingCart = getShoppingCart(eventStore, shoppingCartId); - assertEquals(shoppingCartId, shoppingCart.id()); - assertEquals(clientId, shoppingCart.clientId()); - assertEquals(2, shoppingCart.productItems().size()); - assertEquals(ShoppingCart.Status.Confirmed, shoppingCart.status()); - - assertEquals(shoesId, shoppingCart.productItems().get(0).productId()); - assertEquals(pairOfShoes.quantity(), shoppingCart.productItems().get(0).quantity()); - assertEquals(pricedPairOfShoes.unitPrice(), shoppingCart.productItems().get(0).unitPrice()); - - assertEquals(tShirtId, shoppingCart.productItems().get(1).productId()); - assertEquals(tShirt.quantity(), shoppingCart.productItems().get(1).quantity()); - assertEquals(pricedTShirt.unitPrice(), shoppingCart.productItems().get(1).unitPrice()); - - assertThat(shoppingCart.productItems().get(0)).usingRecursiveComparison().isEqualTo(pricedPairOfShoes); - assertThat(shoppingCart.productItems().get(1)).usingRecursiveComparison().isEqualTo(pricedTShirt); + assertThat(shoppingCart).isInstanceOf(ShoppingCart.Closed.class); - var events = eventStore.readStream(ShoppingCartEvent.class, shoppingCartId); + var events = eventStore.readStream(ShoppingCart.Event.class, shoppingCartId); assertThat(events).hasSize(5); - assertThat(events.get(0)).isInstanceOf(ShoppingCartOpened.class); - assertThat(events.get(1)).isInstanceOf(ProductItemAddedToShoppingCart.class); - assertThat(events.get(2)).isInstanceOf(ProductItemAddedToShoppingCart.class); - assertThat(events.get(3)).isInstanceOf(ProductItemRemovedFromShoppingCart.class); - assertThat(events.get(4)).isInstanceOf(ShoppingCartConfirmed.class); + assertThat(events.get(0)).isEqualTo(new Opened(shoppingCartId, clientId, now)); + assertThat(events.get(1)).isEqualTo(new ProductItemAdded(shoppingCartId, pricedTwoPairOfShoes, now)); + assertThat(events.get(2)).isEqualTo(new ProductItemAdded(shoppingCartId, pricedTShirt, now)); + assertThat(events.get(3)).isEqualTo(new ProductItemRemoved(shoppingCartId, pricedPairOfShoes, now)); + assertThat(events.get(4)).isEqualTo(new Confirmed(shoppingCartId, now)); } } diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/FunctionalTools.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/FunctionalTools.java index de8f0424..8d3a44f9 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/FunctionalTools.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/FunctionalTools.java @@ -64,4 +64,20 @@ public Set characteristics() { LinkedHashMap::new, Collectors.mapping(p -> p, toList())); } + + public static When when(State state, Event event){ + return new When<>(state, event); + } + + public static On on(State state, Event event){ + return new On<>(state, event); + } + + public record When(State state, Event event) { + + } + + public record On(State state, Command command) { + } } + diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCart.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCart.java index 70a24e06..46ac49b7 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCart.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCart.java @@ -5,152 +5,74 @@ import java.time.OffsetDateTime; import java.util.UUID; -import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartEvent.*; - -public record ShoppingCart( - UUID id, - UUID clientId, - Status status, - ProductItems productItems, - OffsetDateTime confirmedAt, - OffsetDateTime canceledAt -) { - public enum Status { - Pending, - Confirmed, - Canceled +import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.FunctionalTools.When; +import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.FunctionalTools.when; + +public sealed interface ShoppingCart { + record Initial() implements ShoppingCart { + } + + record Pending(ProductItems ProductItems) implements ShoppingCart { } - public boolean isClosed() { - return status == Status.Confirmed || status == Status.Canceled; + record Closed() implements ShoppingCart { + } - public static ShoppingCart initial() { - return new ShoppingCart(null, null, null, null, null, null); + sealed interface Event { + record Opened( + UUID shoppingCartId, + UUID clientId, + OffsetDateTime openedAt + ) implements Event { + } + + record ProductItemAdded( + UUID shoppingCartId, + ProductItems.PricedProductItem productItem, + OffsetDateTime addedAt + ) implements Event { + } + + record ProductItemRemoved( + UUID shoppingCartId, + ProductItems.PricedProductItem productItem, + OffsetDateTime removedAt + ) implements Event { + } + + record Confirmed( + UUID shoppingCartId, + OffsetDateTime confirmedAt + ) implements Event { + } + + record Canceled( + UUID shoppingCartId, + OffsetDateTime canceledAt + ) implements Event { + } } - public static ShoppingCart evolve(ShoppingCart state, ShoppingCartEvent event) { - return switch (event) { - case ShoppingCartOpened opened -> new ShoppingCart( - opened.shoppingCartId(), - opened.clientId(), - Status.Pending, - ProductItems.empty(), - null, - null - ); - case ProductItemAddedToShoppingCart(_, var productItem) -> - new ShoppingCart( - state.id, - state.clientId, - state.status, - state.productItems.add(productItem), - state.confirmedAt, - state.canceledAt - ); - case ProductItemRemovedFromShoppingCart(_, var productItem) -> - new ShoppingCart( - state.id, - state.clientId, - state.status, - state.productItems.remove(productItem), - state.confirmedAt, - state.canceledAt - ); - case ShoppingCartConfirmed _ -> - new ShoppingCart( - state.id, - state.clientId, - Status.Confirmed, - state.productItems, - state.confirmedAt, - state.canceledAt - ); - case ShoppingCartCanceled _ -> - new ShoppingCart( - state.id, - state.clientId, - Status.Canceled, - state.productItems, - state.confirmedAt, - state.canceledAt - ); + static ShoppingCart evolve(ShoppingCart state, Event event) { + return switch (when(state, event)) { + case When(Initial _, Event.Opened _) -> + new Pending(ProductItems.empty()); + + case When( + Pending(var productItems), + Event.ProductItemAdded(_, var productItem, _) + ) -> new Pending(productItems.add(productItem)); + + case When( + Pending(var productItems), + Event.ProductItemRemoved(_, var productItem, _) + ) -> new Pending(productItems.remove(productItem)); + + case When(Pending _, Event.Confirmed _), + When(Pending _, Event.Canceled _) -> new Closed(); + + default -> state; }; } } -// -//static ShoppingCart evolve(EventStoreDBClient eventStore, String streamName) { -// // 1. Add logic here -// ShoppingCart shoppingCart = null; -// -// -// for (var event : getEvents(eventStore, streamName)) { -// switch (event) { -// case ShoppingCartOpened opened -> shoppingCart = new ShoppingCart( -// opened.shoppingCartId(), -// opened.clientId(), -// ShoppingCartStatus.Pending, -// new PricedProductItem[]{}, -// null, -// null -// ); -// case ProductItemAddedToShoppingCart productItemAdded -> -// shoppingCart = new ShoppingCart( -// shoppingCart.id(), -// shoppingCart.clientId(), -// shoppingCart.status(), -// Stream.concat(Arrays.stream(shoppingCart.productItems()), Stream.of(productItemAdded.productItem())) -// .collect(groupingByOrdered(PricedProductItem::productId)) -// .entrySet().stream() -// .map(group -> group.getValue().size() == 1 ? -// group.getValue().get(0) : -// new PricedProductItem( -// group.getKey(), -// group.getValue().stream().mapToInt(PricedProductItem::quantity).sum(), -// group.getValue().get(0).unitPrice() -// ) -// ) -// .toArray(PricedProductItem[]::new), -// shoppingCart.confirmedAt(), -// shoppingCart.canceledAt() -// ); -// case ProductItemRemovedFromShoppingCart productItemRemoved -> -// shoppingCart = new ShoppingCart( -// shoppingCart.id(), -// shoppingCart.clientId(), -// shoppingCart.status(), -// Arrays.stream(shoppingCart.productItems()) -// .map(pi -> pi.productId().equals(productItemRemoved.productItem().productId()) ? -// new PricedProductItem( -// pi.productId(), -// pi.quantity() - productItemRemoved.productItem().quantity(), -// pi.unitPrice() -// ) -// : pi -// ) -// .filter(pi -> pi.quantity > 0) -// .toArray(PricedProductItem[]::new), -// shoppingCart.confirmedAt(), -// shoppingCart.canceledAt() -// ); -// case ShoppingCartConfirmed confirmed -> shoppingCart = new ShoppingCart( -// shoppingCart.id(), -// shoppingCart.clientId(), -// ShoppingCartStatus.Confirmed, -// shoppingCart.productItems(), -// confirmed.confirmedAt(), -// shoppingCart.canceledAt() -// ); -// case ShoppingCartCanceled canceled -> shoppingCart = new ShoppingCart( -// shoppingCart.id(), -// shoppingCart.clientId(), -// ShoppingCartStatus.Canceled, -// shoppingCart.productItems(), -// shoppingCart.confirmedAt(), -// canceled.canceledAt() -// ); -// } -// } -// -// return shoppingCart; -//} diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCartDecider.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCartDecider.java new file mode 100644 index 00000000..d9f87100 --- /dev/null +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCartDecider.java @@ -0,0 +1,81 @@ +package io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable; + +import java.time.OffsetDateTime; +import java.util.UUID; + +import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.FunctionalTools.On; +import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.FunctionalTools.on; +import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCart.Initial; +import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCart.Pending; +import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCart.Event.*; +import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartDecider.Command.*; +import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.productItems.ProductItems.PricedProductItem; + +public class ShoppingCartDecider { + public sealed interface Command { + record Open( + UUID shoppingCartId, + UUID clientId, + OffsetDateTime now + ) implements Command { + } + + record AddProductItem( + UUID shoppingCartId, + PricedProductItem productItem, + OffsetDateTime now + ) implements Command { + } + + record RemoveProductItem( + UUID shoppingCartId, + PricedProductItem productItem, + OffsetDateTime now + ) implements Command { + } + + record Confirm( + UUID shoppingCartId, + OffsetDateTime now + ) implements Command { + } + + record Cancel( + UUID shoppingCartId, + OffsetDateTime now + ) implements Command { + } + } + + public static ShoppingCart.Event decide(Command command, ShoppingCart state) { + return switch (on(state, command)) { + case On(Initial _, Open(var id, var clientId, var now)) -> + new Opened(id, clientId, now); + + case On( + Pending _, + AddProductItem(var id, var productItem, var now) + ) -> new ProductItemAdded(id, productItem, now); + + case On( + Pending(var productItems), + RemoveProductItem(var id, var productItem, var now) + ) -> { + if (!productItems.hasEnough(productItem)) + throw new IllegalStateException("Not enough product items to remove"); + + yield new ProductItemRemoved(id, productItem, now); + } + + case On(Pending _, Confirm(var id, var now)) -> + new Confirmed(id, now); + + case On(Pending _, Cancel(var id, var now)) -> + new Canceled(id, now); + + default -> throw new IllegalStateException( + String.format("Cannot %s on %s", command.getClass().getName(), state.getClass().getName()) + ); + }; + } +} diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCartEvent.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCartEvent.java index 74409567..d2a70762 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCartEvent.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCartEvent.java @@ -5,34 +5,4 @@ import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.productItems.ProductItems.PricedProductItem; -public sealed interface ShoppingCartEvent { - record ShoppingCartOpened( - UUID shoppingCartId, - UUID clientId - ) implements ShoppingCartEvent { - } - record ProductItemAddedToShoppingCart( - UUID shoppingCartId, - PricedProductItem productItem - ) implements ShoppingCartEvent { - } - - record ProductItemRemovedFromShoppingCart( - UUID shoppingCartId, - PricedProductItem productItem - ) implements ShoppingCartEvent { - } - - record ShoppingCartConfirmed( - UUID shoppingCartId, - OffsetDateTime confirmedAt - ) implements ShoppingCartEvent { - } - - record ShoppingCartCanceled( - UUID shoppingCartId, - OffsetDateTime canceledAt - ) implements ShoppingCartEvent { - } -} diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCartService.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCartService.java deleted file mode 100644 index 59f3b3c7..00000000 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/ShoppingCartService.java +++ /dev/null @@ -1,103 +0,0 @@ -package io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable; - -import io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.productItems.ProductPriceCalculator; - -import java.time.OffsetDateTime; -import java.util.UUID; - -import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.productItems.ProductItems.PricedProductItem; -import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.productItems.ProductItems.ProductItem; -import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartEvent.*; -import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartService.ShoppingCartCommand.*; - -public class ShoppingCartService { - public sealed interface ShoppingCartCommand { - record OpenShoppingCart( - UUID shoppingCartId, - UUID clientId - ) implements ShoppingCartCommand { - } - - record AddProductItemToShoppingCart( - UUID shoppingCartId, - ProductItem productItem - ) implements ShoppingCartCommand { - } - - record RemoveProductItemFromShoppingCart( - UUID shoppingCartId, - PricedProductItem productItem - ) implements ShoppingCartCommand { - } - - record ConfirmShoppingCart( - UUID shoppingCartId - ) implements ShoppingCartCommand { - } - - record CancelShoppingCart( - UUID shoppingCartId - ) implements ShoppingCartCommand { - } - } - - public static ShoppingCartOpened handle(OpenShoppingCart command) { - return new ShoppingCartOpened( - command.shoppingCartId(), - command.clientId() - ); - } - - public static ProductItemAddedToShoppingCart handle( - ProductPriceCalculator productPriceCalculator, - AddProductItemToShoppingCart command, - ShoppingCart shoppingCart - ) { - if (shoppingCart.isClosed()) - throw new IllegalStateException("Removing product item for cart in '%s' status is not allowed.".formatted(shoppingCart.status())); - - var pricedProductItem = productPriceCalculator.calculate(command.productItem); - - shoppingCart.productItems().add(pricedProductItem); - - return new ProductItemAddedToShoppingCart( - command.shoppingCartId, - pricedProductItem - ); - } - - public static ProductItemRemovedFromShoppingCart handle( - RemoveProductItemFromShoppingCart command, - ShoppingCart shoppingCart - ) { - if (shoppingCart.isClosed()) - throw new IllegalStateException("Adding product item for cart in '%s' status is not allowed.".formatted(shoppingCart.status())); - - shoppingCart.productItems().hasEnough(command.productItem()); - - return new ProductItemRemovedFromShoppingCart( - command.shoppingCartId(), - command.productItem() - ); - } - - public static ShoppingCartConfirmed handle(ConfirmShoppingCart command, ShoppingCart shoppingCart) { - if (shoppingCart.isClosed()) - throw new IllegalStateException("Confirming cart in '%s' status is not allowed.".formatted(shoppingCart.status())); - - return new ShoppingCartConfirmed( - shoppingCart.id(), - OffsetDateTime.now() - ); - } - - public static ShoppingCartCanceled handle(CancelShoppingCart command, ShoppingCart shoppingCart) { - if (shoppingCart.isClosed()) - throw new IllegalStateException("Canceling cart in '%s' status is not allowed.".formatted(shoppingCart.status())); - - return new ShoppingCartCanceled( - shoppingCart.id(), - OffsetDateTime.now() - ); - } -} diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/productItems/ProductItems.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/productItems/ProductItems.java index 493a1e9d..a8f170bf 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/productItems/ProductItems.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/immutable/productItems/ProductItems.java @@ -1,66 +1,50 @@ package io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.productItems; -import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; import java.util.UUID; -import java.util.stream.Stream; -import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.FunctionalTools.groupingByOrdered; +public class ProductItems { + Map values; + + private ProductItems(Map values) { + this.values = values; + } -public record ProductItems( - PricedProductItem[] values -) { public static ProductItems empty() { - return new ProductItems(new PricedProductItem[]{}); + return new ProductItems(new HashMap<>()); } public ProductItems add(PricedProductItem productItem) { - return new ProductItems( - Stream.concat(Arrays.stream(values), Stream.of(productItem)) - .collect(groupingByOrdered(PricedProductItem::productId)) - .entrySet().stream() - .map(group -> group.getValue().size() == 1 ? - group.getValue().getFirst() : - new PricedProductItem( - group.getKey(), - group.getValue().stream().mapToInt(PricedProductItem::quantity).sum(), - group.getValue().getFirst().unitPrice() - ) - ) - .toArray(PricedProductItem[]::new) + var newValues = new HashMap<>(values); + + newValues.compute(key((productItem)), (_, currentQuantity) -> + Optional.ofNullable(currentQuantity).orElse(0) + productItem.quantity ); + + return new ProductItems(newValues); } public ProductItems remove(PricedProductItem productItem) { - return new ProductItems( - Arrays.stream(values()) - .map(pi -> pi.productId().equals(productItem.productId()) ? - new PricedProductItem( - pi.productId(), - pi.quantity() - productItem.quantity(), - pi.unitPrice() - ) - : pi - ) - .filter(pi -> pi.quantity > 0) - .toArray(PricedProductItem[]::new) + var newValues = new HashMap<>(values); + + newValues.compute(key((productItem)), (_, currentQuantity) -> + Optional.ofNullable(currentQuantity).orElse(0) - productItem.quantity ); + + return new ProductItems(newValues); } public boolean hasEnough(PricedProductItem productItem) { - var currentQuantity = Arrays.stream(values) - .filter(pi -> pi.productId().equals(productItem.productId())) - .mapToInt(PricedProductItem::quantity) - .sum(); + var currentQuantity = values.getOrDefault(key(productItem), 0); return currentQuantity >= productItem.quantity(); } - public PricedProductItem get(int index) { - return values[index]; - } - public int size() { - return values.length; + private static String key(PricedProductItem pricedProductItem) { + return String.format("%s_%s", pricedProductItem.productId, pricedProductItem.unitPrice()); } public record ProductItem( diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/tools/EventStore.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/tools/EventStore.java index 27605923..d47f61db 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/tools/EventStore.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e06_business_logic_slimmed/tools/EventStore.java @@ -57,6 +57,7 @@ record EventEnvelope(String eventType, String json) { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); } diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e07_application_logic/esdb/core/serializer/DefaultSerializer.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e07_application_logic/esdb/core/serializer/DefaultSerializer.java index e661bf07..2594135e 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e07_application_logic/esdb/core/serializer/DefaultSerializer.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e07_application_logic/esdb/core/serializer/DefaultSerializer.java @@ -13,5 +13,6 @@ public final class DefaultSerializer { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); } diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e08_optimistic_concurrency/esdb/core/serializer/DefaultSerializer.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e08_optimistic_concurrency/esdb/core/serializer/DefaultSerializer.java index 3b58edda..0336698e 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e08_optimistic_concurrency/esdb/core/serializer/DefaultSerializer.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e08_optimistic_concurrency/esdb/core/serializer/DefaultSerializer.java @@ -13,5 +13,6 @@ public final class DefaultSerializer { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); } diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e09_projections_singlestream/tools/Database.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e09_projections_singlestream/tools/Database.java index f0e01155..b3e61312 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e09_projections_singlestream/tools/Database.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e09_projections_singlestream/tools/Database.java @@ -24,6 +24,7 @@ public class Database { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); public void store(Class typeClass, UUID id, Object obj) { diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e10_projections_singlestream_idempotency/tools/Database.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e10_projections_singlestream_idempotency/tools/Database.java index 9d835b2d..3ab6f8cf 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e10_projections_singlestream_idempotency/tools/Database.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e10_projections_singlestream_idempotency/tools/Database.java @@ -24,6 +24,7 @@ public class Database { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); public void store(Class typeClass, UUID id, long expectedVersion, T obj) { diff --git a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e11_projections_singlestream_eventual_consistency/tools/Database.java b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e11_projections_singlestream_eventual_consistency/tools/Database.java index 9320d899..e41e88bf 100644 --- a/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e11_projections_singlestream_eventual_consistency/tools/Database.java +++ b/workshops/introduction-to-event-sourcing/solved/src/test/java/io/eventdriven/introductiontoeventsourcing/e11_projections_singlestream_eventual_consistency/tools/Database.java @@ -27,6 +27,7 @@ public record DataWrapper(Object data, OffsetDateTime validFrom) { .registerModule(new JavaTimeModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); public void store(Class typeClass, UUID id, T obj) {