@startuml package com.iluwatar.event.sourcing.journal { class JsonFileJournal { - aFile : File - events : List - index : int + JsonFileJournal() + readNext() : DomainEvent + reset() + write(domainEvent : DomainEvent) } } package com.iluwatar.event.sourcing.processor { class DomainEventProcessor { - precessorJournal : ProcessorJournal + DomainEventProcessor() + process(domainEvent : DomainEvent) + recover() + setPrecessorJournal(precessorJournal : ProcessorJournal) } } package com.iluwatar.event.sourcing.service { class AccountService { - eventProcessor : EventProcessor + AccountService(eventProcessor : EventProcessor) + createAccount(accountNo : int, owner : String) } class MoneyTransactionService { - eventProcessor : EventProcessor + MoneyTransactionService(eventProcessor : EventProcessor) + depositMoney(accountNo : int, money : BigDecimal) + transferMoney(accountNoFrom : int, accountNoTo : int, money : BigDecimal) + withdrawalMoney(accountNo : int, money : BigDecimal) } class SequenceIdGenerator { - sequenceId : long {static} + SequenceIdGenerator() + nextSequenceId() : long {static} } } package com.iluwatar.event.sourcing.event { class AccountCreateEvent { - accountNo : int - owner : String + AccountCreateEvent(sequenceId : long, createdTime : long, accountNo : int, owner : String) + getAccountNo() : int + getOwner() : String + process() } class MoneyDepositEvent { - accountNo : int - money : BigDecimal + MoneyDepositEvent(sequenceId : long, createdTime : long, accountNo : int, money : BigDecimal) + getAccountNo() : int + getMoney() : BigDecimal + process() } class MoneyTransferEvent { - accountNoFrom : int - accountNoTo : int - money : BigDecimal + MoneyTransferEvent(sequenceId : long, createdTime : long, money : BigDecimal, accountNoFrom : int, accountNoTo : int) + getAccountNoFrom() : int + getAccountNoTo() : int + getMoney() : BigDecimal + process() } class MoneyWithdrawalEvent { - accountNo : int - money : BigDecimal + MoneyWithdrawalEvent(sequenceId : long, createdTime : long, accountNo : int, money : BigDecimal) + getAccountNo() : int + getMoney() : BigDecimal + process() } } package com.iluwatar.event.sourcing.gateway { class AccountCreateContractSender { + AccountCreateContractSender() + sendContractInfo(account : Account) } class Gateways { - accountCreateContractSender : AccountCreateContractSender {static} - transactionLogger : TransactionLogger {static} + Gateways() + getAccountCreateContractSender() : AccountCreateContractSender {static} + getTransactionLogger() : TransactionLogger {static} } class TransactionLogger { + TransactionLogger() + log(transaction : Transaction) } } package com.iluwatar.event.sourcing.app { class App { + App() + main(args : String[]) {static} } } package com.iluwatar.event.sourcing.state { class AccountAggregate { - accounts : Map {static} + AccountAggregate() + getAccount(accountNo : int) : Account {static} + putAccount(account : Account) {static} + resetState() {static} } } package com.iluwatar.event.sourcing.domain { class Account { - accountNo : int - money : BigDecimal - owner : String - transactions : List + Account(accountNo : int, owner : String) + copy() : Account - depositMoney(money : BigDecimal) : Transaction + getAccountNo() : int + getMoney() : BigDecimal + getOwner() : String + getTransactions() : List - handleDeposit(money : BigDecimal, realTime : boolean) + handleEvent(accountCreateEvent : AccountCreateEvent) + handleEvent(moneyDepositEvent : MoneyDepositEvent) + handleEvent(moneyWithdrawalEvent : MoneyWithdrawalEvent) + handleTransferFromEvent(moneyTransferEvent : MoneyTransferEvent) + handleTransferToEvent(moneyTransferEvent : MoneyTransferEvent) - handleWithdrawal(money : BigDecimal, realTime : boolean) + setMoney(money : BigDecimal) + setTransactions(transactions : List) + toString() : String - withdrawMoney(money : BigDecimal) : Transaction } class Transaction { - accountNo : int - lastBalance : BigDecimal - moneyIn : BigDecimal - moneyOut : BigDecimal + Transaction(accountNo : int, moneyIn : BigDecimal, moneyOut : BigDecimal, lastBalance : BigDecimal) + getAccountNo() : int + getLastBalance() : BigDecimal + getMoneyIn() : BigDecimal + getMoneyOut() : BigDecimal + toString() : String } } package com.iluwatar.event.sourcing.api { abstract class DomainEvent { - createdTime : long - eventClassName : String - realTime : boolean - sequenceId : long + DomainEvent(sequenceId : long, createdTime : long, eventClassName : String) + getCreatedTime() : long + getEventClassName() : String + getSequenceId() : long + isRealTime() : boolean + process() {abstract} + setRealTime(realTime : boolean) } interface EventProcessor { + process(DomainEvent) {abstract} + recover() {abstract} + setPrecessorJournal(ProcessorJournal) {abstract} } interface ProcessorJournal { + readNext() : DomainEvent {abstract} + reset() {abstract} + write(DomainEvent) {abstract} } } Gateways --> "-accountCreateContractSender" AccountCreateContractSender DomainEventProcessor --> "-precessorJournal" ProcessorJournal Account --> "-transactions" Transaction Gateways --> "-transactionLogger" TransactionLogger AccountService --> "-eventProcessor" EventProcessor MoneyTransactionService --> "-eventProcessor" EventProcessor AccountCreateEvent --|> DomainEvent MoneyDepositEvent --|> DomainEvent MoneyTransferEvent --|> DomainEvent MoneyWithdrawalEvent --|> DomainEvent JsonFileJournal ..|> ProcessorJournal DomainEventProcessor ..|> EventProcessor @enduml