From 89335ee9191828699647cc94e0f2e3458ee73a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20G=C3=BCnther?= Date: Fri, 10 Nov 2017 11:07:50 +0100 Subject: [PATCH] Issue #003: Improve documentation of service documents --- .../serialization/ItemEventConverter.java | 42 ++++++++++++++----- .../serialization/ItemEventDeserializer.java | 3 ++ .../serialization/ItemEventSerializer.java | 3 ++ .../mguenther/gtd/domain/CommandHandler.java | 4 ++ .../gtd/domain/ItemEventPublisher.java | 2 + .../gtd/kafka/ItemEventConsumer.java | 4 ++ .../TransactionalItemEventPublisher.java | 2 + ...TransactionalItemEventPublisherConfig.java | 1 - .../mguenther/gtd/domain/EventHandler.java | 2 + .../java/net/mguenther/gtd/domain/Item.java | 19 ++++++--- 10 files changed, 65 insertions(+), 17 deletions(-) diff --git a/gtd-codec/src/main/java/net/mguenther/gtd/kafka/serialization/ItemEventConverter.java b/gtd-codec/src/main/java/net/mguenther/gtd/kafka/serialization/ItemEventConverter.java index 85a76b0..3e6610d 100644 --- a/gtd-codec/src/main/java/net/mguenther/gtd/kafka/serialization/ItemEventConverter.java +++ b/gtd-codec/src/main/java/net/mguenther/gtd/kafka/serialization/ItemEventConverter.java @@ -14,22 +14,25 @@ import java.time.Instant; import java.util.Date; /** + * Converts bidirectionally between domain events and their respective Avro representation. + * This is a bit of a mess, but we have to cope with it due to the lack of polymorphy and + * inheritance in Avro. + * * @author Markus Günther (markus.guenther@gmail.com) * @author Boris Fresow (bfresow@gmail.com) */ @Component public class ItemEventConverter { - private AvroItemEvent wrap(final ItemEvent event, final Object eventPayload) { - - return AvroItemEvent - .newBuilder() - .setEventId(event.getEventId()) - .setTimestamp(event.getTimestamp()) - .setData(eventPayload) - .build(); - } - + /** + * Consumes a domain event of type {@code ItemEvent} and returns its corresponding + * Avro type (cf. {@code AvroItemEvent}). + * + * @param event + * the domain event that ought to be converted + * @return + * instance of {@code AvroItemEvent} that mirrors the domain event + */ public AvroItemEvent from(final ItemEvent event) { if (event instanceof ItemCreated) return from((ItemCreated) event); @@ -111,6 +114,25 @@ public class ItemEventConverter { return wrap(event, avroEvent); } + private AvroItemEvent wrap(final ItemEvent event, final Object eventPayload) { + + return AvroItemEvent + .newBuilder() + .setEventId(event.getEventId()) + .setTimestamp(event.getTimestamp()) + .setData(eventPayload) + .build(); + } + + /** + * Consumes an Avro event of type {@code AvroItemEvent} and returns its corresponding + * domain event (cf. {@code ItemEvent}). + * + * @param event + * the Avro event that ought to be converted + * @return + * instance of {@code ItemEvent} that mirrros the Avro event + */ public ItemEvent to(final AvroItemEvent event) { final String eventId = String.valueOf(event.getEventId()); diff --git a/gtd-codec/src/main/java/net/mguenther/gtd/kafka/serialization/ItemEventDeserializer.java b/gtd-codec/src/main/java/net/mguenther/gtd/kafka/serialization/ItemEventDeserializer.java index 39f8781..ac2d55b 100644 --- a/gtd-codec/src/main/java/net/mguenther/gtd/kafka/serialization/ItemEventDeserializer.java +++ b/gtd-codec/src/main/java/net/mguenther/gtd/kafka/serialization/ItemEventDeserializer.java @@ -11,6 +11,9 @@ import java.io.IOException; import java.util.Map; /** + * Simple {@code Deserializer} that operates on {@code AvroItemEvent}. This {@code Deserializer} does + * not support multiple versions of the same schema. + * * @author Markus Günther (markus.guenther@gmail.com) * @author Boris Fresow (bfresow@gmail.com) */ diff --git a/gtd-codec/src/main/java/net/mguenther/gtd/kafka/serialization/ItemEventSerializer.java b/gtd-codec/src/main/java/net/mguenther/gtd/kafka/serialization/ItemEventSerializer.java index fc4846a..5b553a2 100644 --- a/gtd-codec/src/main/java/net/mguenther/gtd/kafka/serialization/ItemEventSerializer.java +++ b/gtd-codec/src/main/java/net/mguenther/gtd/kafka/serialization/ItemEventSerializer.java @@ -12,6 +12,9 @@ import java.io.IOException; import java.util.Map; /** + * Simple {@code Serializer} that operates on {@code AvroItemEvent}. This {@code Serializer} does + * not support multiple versions of the same schema. + * * @author Markus Günther (markus.guenther@gmail.com) * @author Boris Fresow (bfresow@gmail.com) */ diff --git a/gtd-command-side/src/main/java/net/mguenther/gtd/domain/CommandHandler.java b/gtd-command-side/src/main/java/net/mguenther/gtd/domain/CommandHandler.java index 6179844..193ca49 100644 --- a/gtd-command-side/src/main/java/net/mguenther/gtd/domain/CommandHandler.java +++ b/gtd-command-side/src/main/java/net/mguenther/gtd/domain/CommandHandler.java @@ -6,6 +6,10 @@ import java.util.List; import java.util.concurrent.CompletableFuture; /** + * Accepts a command (or a list of commands) and attempts to validate them against the current + * state of the referenced aggregate. If the validation holds, the {@code CommandHandler} emits + * corresponding events to the event log. + * * @author Markus Günther (markus.guenther@gmail.com) * @author Boris Fresow (bfresow@gmail.com) */ diff --git a/gtd-command-side/src/main/java/net/mguenther/gtd/domain/ItemEventPublisher.java b/gtd-command-side/src/main/java/net/mguenther/gtd/domain/ItemEventPublisher.java index c1c8413..e838d08 100644 --- a/gtd-command-side/src/main/java/net/mguenther/gtd/domain/ItemEventPublisher.java +++ b/gtd-command-side/src/main/java/net/mguenther/gtd/domain/ItemEventPublisher.java @@ -3,6 +3,8 @@ package net.mguenther.gtd.domain; import net.mguenther.gtd.domain.event.ItemEvent; /** + * Publishes a given {@code ItemEvent} to an event log. + * * @author Markus Günther (markus.guenther@gmail.com) * @author Boris Fresow (bfresow@gmail.com) */ diff --git a/gtd-command-side/src/main/java/net/mguenther/gtd/kafka/ItemEventConsumer.java b/gtd-command-side/src/main/java/net/mguenther/gtd/kafka/ItemEventConsumer.java index cf75996..133bfb2 100644 --- a/gtd-command-side/src/main/java/net/mguenther/gtd/kafka/ItemEventConsumer.java +++ b/gtd-command-side/src/main/java/net/mguenther/gtd/kafka/ItemEventConsumer.java @@ -12,6 +12,10 @@ import org.springframework.kafka.support.Acknowledgment; import org.springframework.stereotype.Component; /** + * Consumes {@code AvroItemEvent}s that update the internal state of domain for the command-side. This is + * essential so that the validation that a {@code CommandHandler} performs always goes against the most + * recent state. + * * @author Markus Günther (markus.guenther@gmail.com) * @author Boris Fresow (bfresow@gmail.com) */ diff --git a/gtd-command-side/src/main/java/net/mguenther/gtd/kafka/TransactionalItemEventPublisher.java b/gtd-command-side/src/main/java/net/mguenther/gtd/kafka/TransactionalItemEventPublisher.java index 26a8ecc..966e5cc 100644 --- a/gtd-command-side/src/main/java/net/mguenther/gtd/kafka/TransactionalItemEventPublisher.java +++ b/gtd-command-side/src/main/java/net/mguenther/gtd/kafka/TransactionalItemEventPublisher.java @@ -13,6 +13,8 @@ import org.springframework.kafka.support.SendResult; import org.springframework.stereotype.Component; /** + * Publisher for {@code ItemEvent}s that exhibits transactional guarantees. + * * @author Markus Günther (markus.guenther@gmail.com) * @author Boris Fresow (bfresow@gmail.com) */ diff --git a/gtd-command-side/src/main/java/net/mguenther/gtd/kafka/TransactionalItemEventPublisherConfig.java b/gtd-command-side/src/main/java/net/mguenther/gtd/kafka/TransactionalItemEventPublisherConfig.java index d257b3e..25290cf 100644 --- a/gtd-command-side/src/main/java/net/mguenther/gtd/kafka/TransactionalItemEventPublisherConfig.java +++ b/gtd-command-side/src/main/java/net/mguenther/gtd/kafka/TransactionalItemEventPublisherConfig.java @@ -24,7 +24,6 @@ public class TransactionalItemEventPublisherConfig { @Bean public ProducerFactory producerFactory() { final Map config = new HashMap<>(); - // TODO (mgu): Extract to config value config.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka:9092"); config.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); config.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, ItemEventSerializer.class); diff --git a/gtd-common/src/main/java/net/mguenther/gtd/domain/EventHandler.java b/gtd-common/src/main/java/net/mguenther/gtd/domain/EventHandler.java index 81b31b6..b51203f 100644 --- a/gtd-common/src/main/java/net/mguenther/gtd/domain/EventHandler.java +++ b/gtd-common/src/main/java/net/mguenther/gtd/domain/EventHandler.java @@ -5,6 +5,8 @@ import net.mguenther.gtd.domain.event.ItemEvent; import java.util.concurrent.CompletableFuture; /** + * Consumes {@code ItemEvent}s and acts upon them. + * * @author Markus Günther (markus.guenther@gmail.com) * @author Boris Fresow (bfresow@gmail.com) */ diff --git a/gtd-common/src/main/java/net/mguenther/gtd/domain/Item.java b/gtd-common/src/main/java/net/mguenther/gtd/domain/Item.java index be8600c..c682489 100644 --- a/gtd-common/src/main/java/net/mguenther/gtd/domain/Item.java +++ b/gtd-common/src/main/java/net/mguenther/gtd/domain/Item.java @@ -91,6 +91,13 @@ public class Item implements Serializable { return associatedList; } + /** + * Mutates the state of this {@code Item} in compliance with the given {@code ItemEvent}. + * + * @param event + * an event that occured in the system and that signals a change of state + * for the aggregate {@code Item} + */ public void project(final ItemEvent event) { if (event instanceof DueDateAssigned) project((DueDateAssigned) event); else if (event instanceof RequiredTimeAssigned) project((RequiredTimeAssigned) event); @@ -101,15 +108,15 @@ public class Item implements Serializable { else throw new IllegalStateException("Unrecognized event: " + event.toString()); } - public void project(final DueDateAssigned event) { + private void project(final DueDateAssigned event) { this.dueDate = event.getDueDate(); } - public void project(final RequiredTimeAssigned event) { + private void project(final RequiredTimeAssigned event) { this.requiredTime = event.getRequiredTime(); } - public void project(final TagAssigned event) { + private void project(final TagAssigned event) { synchronized (this) { if (!tags.contains(event.getTag())) { tags.add(event.getTag()); @@ -117,17 +124,17 @@ public class Item implements Serializable { } } - public void project(final TagRemoved event) { + private void project(final TagRemoved event) { synchronized (this) { tags.remove(event.getTag()); } } - public void project(final ItemConcluded event) { + private void project(final ItemConcluded event) { this.done = true; } - public void project(final ItemMovedToList event) { + private void project(final ItemMovedToList event) { this.associatedList = event.getList(); } }