Skip to content

Commit d2194b0

Browse files
authored
Vanilla API
1 parent 32ec92e commit d2194b0

File tree

105 files changed

+3683
-425
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+3683
-425
lines changed

.sdkmanrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# Enable auto-env through the sdkman_auto_env config
22
# Add key=value pairs of SDKs to use below
3-
java=17.0.7-tem
3+
java=open-21

build.gradle

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,24 @@ subprojects {
2222
withSourcesJar()
2323
withJavadocJar()
2424
toolchain {
25-
languageVersion = JavaLanguageVersion.of(17)
25+
languageVersion = JavaLanguageVersion.of(21)
2626
}
2727
}
2828

2929
ext {
3030
scalaVersion = "2.13"
3131
alpakkaKafkaVersion = "2.0.7"
32-
jacksonVersion = "2.10.5"
32+
jacksonVersion = "2.18.4"
3333
akkaVersion = "2.6.14"
34-
vavrVersion = "0.10.3"
35-
jooqVersion = "3.17.4"
36-
jooqAsyncVersion = "2.0.0"
37-
functionalJsonVersion = "1.0.3"
34+
vavrVersion = "0.10.6"
35+
vavrJacksonVersion = "0.10.3"
36+
jooqVersion = "3.20.4"
37+
jooqAsyncVersion = "2.4.0-rc1"
38+
functionalJsonVersion = "1.0.5-rc1"
3839
kafkaVersion = "3.0.1"
39-
reactorKafkaVersion = "1.3.22"
40-
reactorVersion = "3.5.7"
41-
vertxSqlVersion = "4.3.3"
40+
reactorKafkaVersion = "1.3.23"
41+
reactorVersion = "3.7.7"
42+
vertxSqlVersion = "5.0.0"
4243
testContainerVersion = "1.21.1"
4344
}
4445

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package fr.maif.eventsourcing;
2+
3+
import java.util.function.Supplier;
4+
5+
public class Lazy<T> {
6+
private final io.vavr.Lazy<T> inner;
7+
8+
private Lazy(io.vavr.Lazy<T> inner) {
9+
this.inner = inner;
10+
}
11+
12+
public T get() {
13+
return inner.get();
14+
}
15+
16+
public static <T> Lazy<T> of(Supplier<T> supplier) {
17+
return new Lazy<>(io.vavr.Lazy.of(supplier));
18+
}
19+
20+
public io.vavr.Lazy<T> toVavr() {
21+
return inner;
22+
}
23+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package fr.maif.eventsourcing;
2+
3+
import io.vavr.control.Either;
4+
5+
import java.util.Optional;
6+
import java.util.function.Consumer;
7+
import java.util.function.Function;
8+
import java.util.function.Supplier;
9+
10+
public sealed interface Result<E, V> {
11+
12+
record Success<E, V>(V value) implements Result<E, V> {}
13+
record Error<E, V>(E value) implements Result<E, V> {}
14+
15+
static <E, V> Result<E, V> success(V value) {
16+
return new Success<>(value);
17+
}
18+
static <E, V> Result<E, V> error(E value) {
19+
return new Error<>(value);
20+
}
21+
22+
static <E, V> Result<E, V> fromEither(Either<? extends E, ? extends V> either) {
23+
return either.fold(Result::error, Result::success);
24+
}
25+
26+
static <E, V> Result<E, V> fromOptional(Optional<V> optional, Supplier<E> onEmpty) {
27+
return optional.map(v -> Result.<E, V>success(v)).orElseGet(() -> Result.<E, V>error(onEmpty.get()));
28+
}
29+
30+
default V get() {
31+
return switch (this) {
32+
case Success(var value) -> value;
33+
case Error(var err) -> throw new RuntimeException(err.toString());
34+
};
35+
}
36+
37+
default <U> Result<E, U> map(Function<V, U> f) {
38+
return switch (this) {
39+
case Success(var value) -> new Success<E, U>(f.apply(value));
40+
case Error(var err) -> new Error<E, U>(err);
41+
};
42+
}
43+
default <E1> Result<E1, V> mapError(Function<E, E1> f) {
44+
return switch (this) {
45+
case Success(var value) -> new Success<E1, V>(value);
46+
case Error(var err) -> new Error<E1, V>(f.apply(err));
47+
};
48+
}
49+
50+
default Result<E, V> onError(Consumer<E> f) {
51+
if (this instanceof Result.Error<E,V>(var err)) {
52+
f.accept(err);
53+
}
54+
return this;
55+
}
56+
57+
default Result<E, V> onSuccess(Consumer<V> f) {
58+
if (this instanceof Result.Success<E,V>(var s)) {
59+
f.accept(s);
60+
}
61+
return this;
62+
}
63+
64+
default <U> Result<E, U> flatMap(Function<V, Result<E, U>> f) {
65+
return switch (this) {
66+
case Success(var value) -> f.apply(value);
67+
case Error(var err) -> new Error<E, U>(err);
68+
};
69+
}
70+
71+
default <U> U fold(Function<E, U> onError, Function<V, U> onSuccess) {
72+
return switch (this) {
73+
case Success(var value) -> onSuccess.apply(value);
74+
case Error(var err) -> onError.apply(err);
75+
};
76+
}
77+
78+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package fr.maif.eventsourcing;
2+
3+
public class Unit {
4+
5+
public static Unit unit = new Unit();
6+
7+
public static Unit unit() {
8+
return unit;
9+
}
10+
11+
private Unit() {
12+
}
13+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
3+
4+
tasks.withType(PublishToMavenRepository).configureEach { it.enabled = false }
5+
/* Parametre de compilation java */
6+
compileJava {
7+
// To enable argument names in reporting and debugging
8+
options.compilerArgs += '-parameters'
9+
}
10+
11+
compileTestJava {
12+
// To enable argument names in reporting and debugging
13+
options.compilerArgs += '-parameters'
14+
}
15+
16+
dependencies {
17+
18+
implementation project(':commons-events')
19+
implementation project(':thoth-core')
20+
implementation project(':thoth-core-reactor')
21+
implementation project(':thoth-kafka-consumer-reactor')
22+
implementation("io.vavr:vavr:$vavrVersion")
23+
implementation("fr.maif:functional-json:$functionalJsonVersion")
24+
implementation("com.fasterxml.uuid:java-uuid-generator:4.0.1")
25+
implementation('org.postgresql:postgresql:42.7.7')
26+
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.example.demo;
2+
3+
import fr.maif.eventsourcing.AbstractState;
4+
5+
import java.math.BigDecimal;
6+
7+
public class Account extends AbstractState<Account> {
8+
public String id;
9+
public BigDecimal balance;
10+
public long sequenceNum;
11+
12+
@Override
13+
public Long sequenceNum() {
14+
return sequenceNum;
15+
}
16+
17+
@Override
18+
public String entityId() {
19+
return id;
20+
}
21+
22+
@Override
23+
public Account withSequenceNum(Long sequenceNum) {
24+
this.sequenceNum = sequenceNum;
25+
return this;
26+
}
27+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.example.demo;
2+
3+
import com.fasterxml.uuid.Generators;
4+
import com.fasterxml.uuid.impl.TimeBasedGenerator;
5+
import fr.maif.eventsourcing.Lazy;
6+
import fr.maif.eventsourcing.Result;
7+
import fr.maif.eventsourcing.TransactionManager;
8+
import fr.maif.eventsourcing.Unit;
9+
import fr.maif.eventsourcing.vanilla.*;
10+
import fr.maif.reactor.eventsourcing.vanilla.DefaultAggregateStore;
11+
import fr.maif.reactor.eventsourcing.vanilla.InMemoryEventStore;
12+
import fr.maif.reactor.eventsourcing.vanilla.InMemoryEventStore.Transaction;
13+
14+
import java.math.BigDecimal;
15+
import java.util.List;
16+
import java.util.Optional;
17+
import java.util.concurrent.CompletionStage;
18+
import java.util.concurrent.ExecutorService;
19+
import java.util.concurrent.Executors;
20+
import java.util.function.Function;
21+
22+
public class Bank {
23+
private final EventProcessor<String, Account, BankCommand, BankEvent, Transaction<BankEvent, Unit, Unit>, Unit, Unit, Unit> eventProcessor;
24+
private static final TimeBasedGenerator UUIDgenerator = Generators.timeBasedGenerator();
25+
26+
27+
public Bank(
28+
BankCommandHandler commandHandler,
29+
BankEventHandler eventHandler) {
30+
31+
EventStore<Transaction<BankEvent, Unit, Unit>, BankEvent, Unit, Unit> eventStore = InMemoryEventStore.create();
32+
TransactionManager<Transaction<BankEvent, Unit, Unit>> transactionManager = noOpTransactionManager();
33+
ExecutorService executor = Executors.newCachedThreadPool();
34+
DefaultAggregateStore<Account, BankEvent, Unit, Unit, Transaction<BankEvent, Unit, Unit>> aggregateStore = new DefaultAggregateStore<>(eventStore, eventHandler, transactionManager);
35+
this.eventProcessor = new EventProcessorImpl<>(
36+
eventStore,
37+
transactionManager,
38+
aggregateStore,
39+
commandHandler.toCommandHandler(executor),
40+
eventHandler,
41+
List.of()
42+
);
43+
}
44+
45+
private TransactionManager<Transaction<BankEvent, Unit, Unit>> noOpTransactionManager() {
46+
return new TransactionManager<>() {
47+
@Override
48+
public <T> CompletionStage<T> withTransaction(Function<Transaction<BankEvent, Unit, Unit>, CompletionStage<T>> function) {
49+
return function.apply(new Transaction<>());
50+
}
51+
};
52+
}
53+
54+
public CompletionStage<Result<String, ProcessingSuccess<Account, BankEvent, Unit, Unit, Unit>>> createAccount(
55+
BigDecimal amount) {
56+
Lazy<String> lazyId = Lazy.of(() -> UUIDgenerator.generate().toString());
57+
return eventProcessor.processCommand(new BankCommand.OpenAccount(lazyId, amount));
58+
}
59+
60+
public CompletionStage<Result<String, ProcessingSuccess<Account, BankEvent, Unit, Unit, Unit>>> withdraw(
61+
String account, BigDecimal amount) {
62+
return eventProcessor.processCommand(new BankCommand.Withdraw(account, amount));
63+
}
64+
65+
public CompletionStage<Result<String, ProcessingSuccess<Account, BankEvent, Unit, Unit, Unit>>> deposit(
66+
String account, BigDecimal amount) {
67+
return eventProcessor.processCommand(new BankCommand.Deposit(account, amount));
68+
}
69+
70+
public CompletionStage<Result<String, ProcessingSuccess<Account, BankEvent, Unit, Unit, Unit>>> close(
71+
String account) {
72+
return eventProcessor.processCommand(new BankCommand.CloseAccount(account));
73+
}
74+
75+
public CompletionStage<Optional<Account>> findAccountById(String id) {
76+
return eventProcessor.getAggregate(id);
77+
}
78+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.example.demo;
2+
3+
import fr.maif.eventsourcing.Lazy;
4+
import fr.maif.eventsourcing.vanilla.SimpleCommand;
5+
6+
import java.math.BigDecimal;
7+
8+
public sealed interface BankCommand extends SimpleCommand {
9+
10+
record Withdraw(String account, BigDecimal amount) implements BankCommand {
11+
@Override
12+
public Lazy<String> getEntityId() {
13+
return Lazy.of(() -> account);
14+
}
15+
}
16+
17+
record OpenAccount(Lazy<String> id, BigDecimal initialBalance) implements BankCommand {
18+
19+
@Override
20+
public Lazy<String> getEntityId() {
21+
return id;
22+
}
23+
24+
@Override
25+
public Boolean hasId() {
26+
return false;
27+
}
28+
}
29+
30+
record Deposit(String account, BigDecimal amount) implements BankCommand {
31+
@Override
32+
public Lazy<String> getEntityId() {
33+
return Lazy.of(() -> account);
34+
}
35+
}
36+
37+
record CloseAccount(String id) implements BankCommand {
38+
@Override
39+
public Lazy<String> getEntityId() {
40+
return Lazy.of(() -> id);
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)