Created
June 22, 2024 02:32
-
-
Save veganaize/0a1b23297d0fbe5fcea3f4bd7d02cccd to your computer and use it in GitHub Desktop.
Example of event sourcing in java
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 characters
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.HashSet; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Set; | |
/** | |
* Main entry point | |
*/ | |
class EventSource { | |
public static void | |
main(String args[]) { | |
Service.startRepeatingEvent(); | |
EventStore eventStore = new EventStore(); | |
Client clientA = new Client(eventStore); | |
System.out.println("\nAccumlating events..."); | |
try { Thread.sleep(3000L); } catch (Exception e) { } | |
System.out.println("\nFinal state: "+ clientA.state); | |
System.out.println("\nEvent store contents..."); | |
for (Object event : eventStore.events) { | |
System.out.println((Map) event); | |
} | |
EventStore newStore = new EventStore(); | |
Client clientB = new Client(newStore); | |
System.out.println("\nReplaying events on new instance..."); | |
eventStore.replay(clientA, clientB); | |
System.out.println("\nFinal state: "+ clientB.state); | |
} | |
} | |
/** | |
* Handles events | |
*/ | |
interface EventHandler { | |
void handle(Object event, Object data); | |
} | |
/** | |
* Can be subscribed to | |
*/ | |
interface Subscribable { | |
void subscribe(EventHandler subscriber, Object publisher, Object event); | |
} | |
/** | |
* Example of a client object | |
*/ | |
class Client implements EventHandler { | |
EventStore eventStore; | |
String state = ""; | |
Client(EventStore es) { | |
eventStore = es; | |
eventStore.subscribe(this, new Service(), Service.Event.TIMER); | |
} | |
@Override public void | |
handle(Object event, Object data) { | |
state = event +": "+ data; | |
System.out.println(state); | |
} | |
} | |
/** | |
* All (state changing) events routed through an event store instance | |
*/ | |
class EventStore implements EventHandler, Subscribable { | |
List events = new ArrayList(); | |
Map subscriptions = new HashMap(); | |
void | |
addSubscriber(EventHandler subscriber, Object event) { | |
Set subscribers = (Set) subscriptions.getOrDefault(event, new HashSet()); | |
subscribers.add(subscriber); | |
subscriptions.put(event, subscribers); | |
} | |
@Override public void | |
subscribe(EventHandler subscriber, | |
Object publisher, | |
Object event) | |
{ | |
addSubscriber(subscriber, event); | |
((Subscribable) publisher).subscribe(this, publisher, event); | |
System.out.println("\nSubscribe to class: "+ publisher); | |
} | |
@Override public void | |
handle(Object event, Object data) { | |
/* Save event */ | |
Map map = new HashMap(); | |
map.put("event", event); | |
map.put("data", data); | |
events.add(map); | |
/* Notify subscribers */ | |
Set subscribers = (Set) subscriptions.getOrDefault(event, new HashSet()); | |
for (Object subscriber : subscribers) { | |
((EventHandler) subscriber).handle(event, data); | |
} | |
} | |
void | |
replay(EventHandler oldClient, EventHandler newClient) { | |
Set emptySet = new HashSet(); | |
for (Object event : events) { | |
Set subscribers = (Set) subscriptions.getOrDefault( | |
((Map) event).get("event"), emptySet); | |
if (subscribers.contains(oldClient)) { | |
newClient.handle( | |
((Map) event).get("event"), ((Map) event).get("data")); | |
} | |
} | |
} | |
} | |
/** | |
* An example of a service | |
*/ | |
class Service extends java.util.TimerTask implements Subscribable { | |
static enum Event { TIMER } | |
static Set subscribers = new HashSet(); | |
static void | |
startRepeatingEvent() { | |
new java.util.Timer(true).scheduleAtFixedRate(new Service(), 0L, 1000L); | |
} | |
/* Publish repeating event */ | |
@Override public void | |
run() { | |
for (Object subscriber : subscribers) { | |
((EventHandler) subscriber).handle( | |
Event.TIMER, java.time.LocalDateTime.now()); | |
} | |
} | |
@Override public void | |
subscribe(EventHandler subscriber, | |
Object publisher, | |
Object event) | |
{ | |
subscribers.add(subscriber); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment