mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-10-14 00:16:48 +00:00
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:
1 parent
371439aeaa
commit
0ca162a55c
1863 files changed
+14403
-17632
No files matched your search
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+7
-5
@@ -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();
|
||||
|
||||
}
|
||||
+10
-7
@@ -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);
|
||||
}
|
||||
}
|
||||
+14
-10
@@ -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);
|
||||
}
|
||||
|
||||
+2
-6
@@ -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) {
|
||||
|
||||
+2
-6
@@ -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............");
|
||||
|
||||
+14
-15
@@ -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");
|
||||
}
|
||||
|
||||
+3
-9
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user