deps: Refactor dependencies (#3224)

* remove spring dep
move junit, logging, mockito under dep mgmt

* upgrade anti-corruption-layer deps

* async method invocation

* balking, bloc

* bridge to bytecode

* caching

* callback - cqrs

* component - health check

* hexagonal - metadata mapping

* rest of the patterns

* remove checkstyle, take spotless into use
This commit is contained in:
Ilkka Seppälä authored and GitHub committed 2025-03-29 19:34:27 +02:00
1 parent 371439aeaa
commit 0ca162a55c
1863 files changed
+14403 -17632

No files matched your search

+8
View File
@@ -34,6 +34,14 @@
</parent>
<artifactId>event-sourcing</artifactId>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
@@ -53,13 +53,10 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class App {
/**
* The constant ACCOUNT OF DAENERYS.
*/
/** The constant ACCOUNT OF DAENERYS. */
public static final int ACCOUNT_OF_DAENERYS = 1;
/**
* The constant ACCOUNT OF JON.
*/
/** The constant ACCOUNT OF JON. */
public static final int ACCOUNT_OF_JON = 2;
/**
@@ -76,23 +73,24 @@ public class App {
LOGGER.info("Creating the accounts............");
eventProcessor.process(new AccountCreateEvent(
0, new Date().getTime(), ACCOUNT_OF_DAENERYS, "Daenerys Targaryen"));
eventProcessor.process(
new AccountCreateEvent(0, new Date().getTime(), ACCOUNT_OF_DAENERYS, "Daenerys Targaryen"));
eventProcessor.process(new AccountCreateEvent(
1, new Date().getTime(), ACCOUNT_OF_JON, "Jon Snow"));
eventProcessor.process(
new AccountCreateEvent(1, new Date().getTime(), ACCOUNT_OF_JON, "Jon Snow"));
LOGGER.info("Do some money operations............");
eventProcessor.process(new MoneyDepositEvent(
2, new Date().getTime(), ACCOUNT_OF_DAENERYS, new BigDecimal("100000")));
eventProcessor.process(
new MoneyDepositEvent(
2, new Date().getTime(), ACCOUNT_OF_DAENERYS, new BigDecimal("100000")));
eventProcessor.process(new MoneyDepositEvent(
3, new Date().getTime(), ACCOUNT_OF_JON, new BigDecimal("100")));
eventProcessor.process(
new MoneyDepositEvent(3, new Date().getTime(), ACCOUNT_OF_JON, new BigDecimal("100")));
eventProcessor.process(new MoneyTransferEvent(
4, new Date().getTime(), new BigDecimal("10000"), ACCOUNT_OF_DAENERYS,
ACCOUNT_OF_JON));
eventProcessor.process(
new MoneyTransferEvent(
4, new Date().getTime(), new BigDecimal("10000"), ACCOUNT_OF_DAENERYS, ACCOUNT_OF_JON));
LOGGER.info("...............State:............");
LOGGER.info(AccountAggregate.getAccount(ACCOUNT_OF_DAENERYS).toString());
@@ -68,9 +68,13 @@ public class Account {
@Override
public String toString() {
return "Account{"
+ "accountNo=" + accountNo
+ ", owner='" + owner + '\''
+ ", money=" + money
+ "accountNo="
+ accountNo
+ ", owner='"
+ owner
+ '\''
+ ", money="
+ money
+ '}';
}
@@ -111,7 +115,6 @@ public class Account {
handleDeposit(moneyDepositEvent.getMoney(), moneyDepositEvent.isRealTime());
}
/**
* Handles the AccountCreateEvent.
*
@@ -141,6 +144,4 @@ public class Account {
public void handleTransferToEvent(MoneyTransferEvent moneyTransferEvent) {
handleDeposit(moneyTransferEvent.getMoney(), moneyTransferEvent.isRealTime());
}
}
@@ -46,15 +46,17 @@ public class AccountCreateEvent extends DomainEvent {
/**
* Instantiates a new Account created event.
*
* @param sequenceId the sequence id
* @param sequenceId the sequence id
* @param createdTime the created time
* @param accountNo the account no
* @param owner the owner
* @param accountNo the account no
* @param owner the owner
*/
@JsonCreator
public AccountCreateEvent(@JsonProperty("sequenceId") long sequenceId,
public AccountCreateEvent(
@JsonProperty("sequenceId") long sequenceId,
@JsonProperty("createdTime") long createdTime,
@JsonProperty("accountNo") int accountNo, @JsonProperty("owner") String owner) {
@JsonProperty("accountNo") int accountNo,
@JsonProperty("owner") String owner) {
super(sequenceId, createdTime, "AccountCreateEvent");
this.accountNo = accountNo;
this.owner = owner;
@@ -44,9 +44,6 @@ public abstract class DomainEvent implements Serializable {
private final String eventClassName;
private boolean realTime = true;
/**
* Process.
*/
/** Process. */
public abstract void process();
}
@@ -47,15 +47,17 @@ public class MoneyDepositEvent extends DomainEvent {
/**
* Instantiates a new Money deposit event.
*
* @param sequenceId the sequence id
* @param sequenceId the sequence id
* @param createdTime the created time
* @param accountNo the account no
* @param money the money
* @param accountNo the account no
* @param money the money
*/
@JsonCreator
public MoneyDepositEvent(@JsonProperty("sequenceId") long sequenceId,
public MoneyDepositEvent(
@JsonProperty("sequenceId") long sequenceId,
@JsonProperty("createdTime") long createdTime,
@JsonProperty("accountNo") int accountNo, @JsonProperty("money") BigDecimal money) {
@JsonProperty("accountNo") int accountNo,
@JsonProperty("money") BigDecimal money) {
super(sequenceId, createdTime, "MoneyDepositEvent");
this.money = money;
this.accountNo = accountNo;
@@ -63,8 +65,9 @@ public class MoneyDepositEvent extends DomainEvent {
@Override
public void process() {
var account = Optional.ofNullable(AccountAggregate.getAccount(accountNo))
.orElseThrow(() -> new RuntimeException("Account not found"));
var account =
Optional.ofNullable(AccountAggregate.getAccount(accountNo))
.orElseThrow(() -> new RuntimeException("Account not found"));
account.handleEvent(this);
}
}
@@ -48,16 +48,18 @@ public class MoneyTransferEvent extends DomainEvent {
/**
* Instantiates a new Money transfer event.
*
* @param sequenceId the sequence id
* @param createdTime the created time
* @param money the money
* @param sequenceId the sequence id
* @param createdTime the created time
* @param money the money
* @param accountNoFrom the account no from
* @param accountNoTo the account no to
* @param accountNoTo the account no to
*/
@JsonCreator
public MoneyTransferEvent(@JsonProperty("sequenceId") long sequenceId,
public MoneyTransferEvent(
@JsonProperty("sequenceId") long sequenceId,
@JsonProperty("createdTime") long createdTime,
@JsonProperty("money") BigDecimal money, @JsonProperty("accountNoFrom") int accountNoFrom,
@JsonProperty("money") BigDecimal money,
@JsonProperty("accountNoFrom") int accountNoFrom,
@JsonProperty("accountNoTo") int accountNoTo) {
super(sequenceId, createdTime, "MoneyTransferEvent");
this.money = money;
@@ -67,10 +69,12 @@ public class MoneyTransferEvent extends DomainEvent {
@Override
public void process() {
var accountFrom = Optional.ofNullable(AccountAggregate.getAccount(accountNoFrom))
.orElseThrow(() -> new RuntimeException("Account not found " + accountNoFrom));
var accountTo = Optional.ofNullable(AccountAggregate.getAccount(accountNoTo))
.orElseThrow(() -> new RuntimeException("Account not found " + accountNoTo));
var accountFrom =
Optional.ofNullable(AccountAggregate.getAccount(accountNoFrom))
.orElseThrow(() -> new RuntimeException("Account not found " + accountNoFrom));
var accountTo =
Optional.ofNullable(AccountAggregate.getAccount(accountNoTo))
.orElseThrow(() -> new RuntimeException("Account not found " + accountNoTo));
accountFrom.handleTransferFromEvent(this);
accountTo.handleTransferToEvent(this);
}
@@ -50,16 +50,12 @@ public class DomainEventProcessor {
eventJournal.write(domainEvent);
}
/**
* Reset.
*/
/** Reset. */
public void reset() {
eventJournal.reset();
}
/**
* Recover.
*/
/** Recover. */
public void recover() {
DomainEvent domainEvent;
while ((domainEvent = eventJournal.readNext()) != null) {
@@ -28,9 +28,7 @@ import com.iluwatar.event.sourcing.event.DomainEvent;
import java.io.File;
import lombok.extern.slf4j.Slf4j;
/**
* Base class for Journaling implementations.
*/
/** Base class for Journaling implementations. */
@Slf4j
public abstract class EventJournal {
@@ -43,9 +41,7 @@ public abstract class EventJournal {
*/
abstract void write(DomainEvent domainEvent);
/**
* Reset.
*/
/** Reset. */
void reset() {
if (file.delete()) {
LOGGER.info("File cleared successfully............");
@@ -53,14 +53,13 @@ public class JsonFileJournal extends EventJournal {
private final List<String> events = new ArrayList<>();
private int index = 0;
/**
* Instantiates a new Json file journal.
*/
/** Instantiates a new Json file journal. */
public JsonFileJournal() {
file = new File("Journal.json");
if (file.exists()) {
try (var input = new BufferedReader(
new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
try (var input =
new BufferedReader(
new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
String line;
while ((line = input.readLine()) != null) {
events.add(line);
@@ -73,7 +72,6 @@ public class JsonFileJournal extends EventJournal {
}
}
/**
* Write.
*
@@ -82,8 +80,9 @@ public class JsonFileJournal extends EventJournal {
@Override
public void write(DomainEvent domainEvent) {
var mapper = new ObjectMapper();
try (var output = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(file, true), StandardCharsets.UTF_8))) {
try (var output =
new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(file, true), StandardCharsets.UTF_8))) {
var eventString = mapper.writeValueAsString(domainEvent);
output.write(eventString + "\r\n");
} catch (IOException e) {
@@ -91,7 +90,6 @@ public class JsonFileJournal extends EventJournal {
}
}
/**
* Read the next domain event.
*
@@ -109,12 +107,13 @@ public class JsonFileJournal extends EventJournal {
try {
var jsonElement = mapper.readTree(event);
var eventClassName = jsonElement.get("eventClassName").asText();
domainEvent = switch (eventClassName) {
case "AccountCreateEvent" -> mapper.treeToValue(jsonElement, AccountCreateEvent.class);
case "MoneyDepositEvent" -> mapper.treeToValue(jsonElement, MoneyDepositEvent.class);
case "MoneyTransferEvent" -> mapper.treeToValue(jsonElement, MoneyTransferEvent.class);
default -> throw new RuntimeException("Journal Event not recognized");
};
domainEvent =
switch (eventClassName) {
case "AccountCreateEvent" -> mapper.treeToValue(jsonElement, AccountCreateEvent.class);
case "MoneyDepositEvent" -> mapper.treeToValue(jsonElement, MoneyDepositEvent.class);
case "MoneyTransferEvent" -> mapper.treeToValue(jsonElement, MoneyTransferEvent.class);
default -> throw new RuntimeException("Journal Event not recognized");
};
} catch (JsonProcessingException jsonProcessingException) {
throw new RuntimeException("Failed to convert JSON");
}
@@ -38,8 +38,7 @@ public class AccountAggregate {
private static Map<Integer, Account> accounts = new HashMap<>();
private AccountAggregate() {
}
private AccountAggregate() {}
/**
* Put account.
@@ -57,15 +56,10 @@ public class AccountAggregate {
* @return the copy of the account or null if not found
*/
public static Account getAccount(int accountNo) {
return Optional.of(accountNo)
.map(accounts::get)
.map(Account::copy)
.orElse(null);
return Optional.of(accountNo).map(accounts::get).map(Account::copy).orElse(null);
}
/**
* Reset state.
*/
/** Reset state. */
public static void resetState() {
accounts = new HashMap<>();
}
@@ -40,46 +40,41 @@ import org.junit.jupiter.api.Test;
/**
* Integration Test for Event-Sourcing state recovery
* <p>
* Created by Serdar Hamzaogullari on 19.08.2017.
*
* <p>Created by Serdar Hamzaogullari on 19.08.2017.
*/
class IntegrationTest {
/**
* The Domain event processor.
*/
/** The Domain event processor. */
private DomainEventProcessor eventProcessor;
/**
* Initialize.
*/
/** Initialize. */
@BeforeEach
void initialize() {
eventProcessor = new DomainEventProcessor(new JsonFileJournal());
}
/**
* Test state recovery.
*/
/** Test state recovery. */
@Test
void testStateRecovery() {
eventProcessor.reset();
eventProcessor.process(new AccountCreateEvent(
0, new Date().getTime(), ACCOUNT_OF_DAENERYS, "Daenerys Targaryen"));
eventProcessor.process(
new AccountCreateEvent(0, new Date().getTime(), ACCOUNT_OF_DAENERYS, "Daenerys Targaryen"));
eventProcessor.process(new AccountCreateEvent(
1, new Date().getTime(), ACCOUNT_OF_JON, "Jon Snow"));
eventProcessor.process(
new AccountCreateEvent(1, new Date().getTime(), ACCOUNT_OF_JON, "Jon Snow"));
eventProcessor.process(new MoneyDepositEvent(
2, new Date().getTime(), ACCOUNT_OF_DAENERYS, new BigDecimal("100000")));
eventProcessor.process(
new MoneyDepositEvent(
2, new Date().getTime(), ACCOUNT_OF_DAENERYS, new BigDecimal("100000")));
eventProcessor.process(new MoneyDepositEvent(
3, new Date().getTime(), ACCOUNT_OF_JON, new BigDecimal("100")));
eventProcessor.process(
new MoneyDepositEvent(3, new Date().getTime(), ACCOUNT_OF_JON, new BigDecimal("100")));
eventProcessor.process(new MoneyTransferEvent(
4, new Date().getTime(), new BigDecimal("10000"), ACCOUNT_OF_DAENERYS,
ACCOUNT_OF_JON));
eventProcessor.process(
new MoneyTransferEvent(
4, new Date().getTime(), new BigDecimal("10000"), ACCOUNT_OF_DAENERYS, ACCOUNT_OF_JON));
var accountOfDaenerysBeforeShotDown = AccountAggregate.getAccount(ACCOUNT_OF_DAENERYS);
var accountOfJonBeforeShotDown = AccountAggregate.getAccount(ACCOUNT_OF_JON);
@@ -92,9 +87,8 @@ class IntegrationTest {
var accountOfDaenerysAfterShotDown = AccountAggregate.getAccount(ACCOUNT_OF_DAENERYS);
var accountOfJonAfterShotDown = AccountAggregate.getAccount(ACCOUNT_OF_JON);
assertEquals(accountOfDaenerysBeforeShotDown.getMoney(),
accountOfDaenerysAfterShotDown.getMoney());
assertEquals(
accountOfDaenerysBeforeShotDown.getMoney(), accountOfDaenerysAfterShotDown.getMoney());
assertEquals(accountOfJonBeforeShotDown.getMoney(), accountOfJonAfterShotDown.getMoney());
}
}