Compare commits
1 Commits
master
...
wip-docume
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ed323db03 |
@@ -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());
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,6 @@ public class TransactionalItemEventPublisherConfig {
|
||||
@Bean
|
||||
public ProducerFactory<String, AvroItemEvent> producerFactory() {
|
||||
final Map<String, Object> 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);
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user