diff --git a/event-sourcing/etc/event-sourcing.png b/event-sourcing/etc/event-sourcing.png index ac7192b19..0b0098546 100644 Binary files a/event-sourcing/etc/event-sourcing.png and b/event-sourcing/etc/event-sourcing.png differ diff --git a/event-sourcing/etc/event-sourcing.ucls b/event-sourcing/etc/event-sourcing.ucls index e6944ef70..2df56a479 100644 --- a/event-sourcing/etc/event-sourcing.ucls +++ b/event-sourcing/etc/event-sourcing.ucls @@ -1,50 +1,50 @@ - - - + - - - - - - - - - - - - - - - - + - - + + + + + + + + + + + + + + + @@ -55,203 +55,63 @@ project="event-sourcing" file="/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java" binary="false" corner="BOTTOM_RIGHT"> - + - - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + - - - - - - - - - + - - + + + + + + - + - - - - - - - - - - + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + transactions; /** * Instantiates a new Account. @@ -52,7 +55,6 @@ public class Account { this.accountNo = accountNo; this.owner = owner; money = BigDecimal.ZERO; - transactions = new ArrayList<>(); } /** @@ -91,23 +93,6 @@ public class Account { this.money = money; } - /** - * Gets transactions. - * - * @return the transactions - */ - public List getTransactions() { - return transactions; - } - - /** - * Sets transactions. - * - * @param transactions the transactions - */ - public void setTransactions(List transactions) { - this.transactions = transactions; - } /** * Copy account. @@ -117,7 +102,6 @@ public class Account { public Account copy() { Account account = new Account(accountNo, owner); account.setMoney(money); - account.setTransactions(transactions); return account; } @@ -127,29 +111,22 @@ public class Account { + "accountNo=" + accountNo + ", owner='" + owner + '\'' + ", money=" + money - + ", transactions=" + transactions + '}'; } - private Transaction depositMoney(BigDecimal money) { + private void depositMoney(BigDecimal money) { this.money = this.money.add(money); - Transaction transaction = new Transaction(accountNo, money, BigDecimal.ZERO, this.money); - transactions.add(transaction); - return transaction; } - private Transaction withdrawMoney(BigDecimal money) { + private void withdrawMoney(BigDecimal money) { this.money = this.money.subtract(money); - Transaction transaction = new Transaction(accountNo, BigDecimal.ZERO, money, this.money); - transactions.add(transaction); - return transaction; } private void handleDeposit(BigDecimal money, boolean realTime) { - Transaction transaction = depositMoney(money); + depositMoney(money); AccountAggregate.putAccount(this); if (realTime) { - Gateways.getTransactionLogger().log(transaction); + LOGGER.info("Some external api for only realtime execution could be called here."); } } @@ -158,15 +135,15 @@ public class Account { throw new RuntimeException("Insufficient Account Balance"); } - Transaction transaction = withdrawMoney(money); + withdrawMoney(money); AccountAggregate.putAccount(this); if (realTime) { - Gateways.getTransactionLogger().log(transaction); + LOGGER.info("Some external api for only realtime execution could be called here."); } } /** - * Handle event. + * Handles the MoneyDepositEvent. * * @param moneyDepositEvent the money deposit event */ @@ -176,29 +153,19 @@ public class Account { /** - * Handle event. - * - * @param moneyWithdrawalEvent the money withdrawal event - */ - public void handleEvent(MoneyWithdrawalEvent moneyWithdrawalEvent) { - handleWithdrawal(moneyWithdrawalEvent.getMoney(), moneyWithdrawalEvent.isRealTime()); - } - - /** - * Handle event. + * Handles the AccountCreateEvent. * * @param accountCreateEvent the account create event */ public void handleEvent(AccountCreateEvent accountCreateEvent) { AccountAggregate.putAccount(this); - // check if this event is replicated from journal before calling an external gateway function if (accountCreateEvent.isRealTime()) { - Gateways.getAccountCreateContractSender().sendContractInfo(this); + LOGGER.info("Some external api for only realtime execution could be called here."); } } /** - * Handle transfer from event. + * Handles transfer from account event. * * @param moneyTransferEvent the money transfer event */ @@ -207,7 +174,7 @@ public class Account { } /** - * Handle transfer to event. + * Handles transfer to account event. * * @param moneyTransferEvent the money transfer event */ diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java deleted file mode 100644 index a0d921f5f..000000000 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Transaction.java +++ /dev/null @@ -1,98 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.event.sourcing.domain; - -import java.math.BigDecimal; - -/** - * Created by Serdar Hamzaogullari on 06.08.2017. - */ -public class Transaction { - - private final int accountNo; - private final BigDecimal moneyIn; - private final BigDecimal moneyOut; - private final BigDecimal lastBalance; - - /** - * Instantiates a new Transaction. - * - * @param accountNo the account no - * @param moneyIn the money in - * @param moneyOut the money out - * @param lastBalance the last balance - */ - public Transaction(int accountNo, BigDecimal moneyIn, BigDecimal moneyOut, - BigDecimal lastBalance) { - this.accountNo = accountNo; - this.moneyIn = moneyIn; - this.moneyOut = moneyOut; - this.lastBalance = lastBalance; - } - - /** - * Gets account no. - * - * @return the account no - */ - public int getAccountNo() { - return accountNo; - } - - /** - * Gets money in. - * - * @return the money in - */ - public BigDecimal getMoneyIn() { - return moneyIn; - } - - /** - * Gets money out. - * - * @return the money out - */ - public BigDecimal getMoneyOut() { - return moneyOut; - } - - /** - * Gets last balance. - * - * @return the last balance - */ - public BigDecimal getLastBalance() { - return lastBalance; - } - - @Override - public String toString() { - return "Transaction{" - + "accountNo=" + accountNo - + ", moneyIn=" + moneyIn - + ", moneyOut=" + moneyOut - + ", lastBalance=" + lastBalance - + '}'; - } -} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java index 350104267..c526396f3 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/AccountCreateEvent.java @@ -22,11 +22,15 @@ */ package com.iluwatar.event.sourcing.event; -import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.domain.Account; import com.iluwatar.event.sourcing.state.AccountAggregate; /** + * This is the class that implements account create event. + * Holds the necessary info for an account create event. + * Implements the process function that finds the event related + * domain objects and calls the related domain object's handle event functions + * * Created by Serdar Hamzaogullari on 06.08.2017. */ public class AccountCreateEvent extends DomainEvent { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/DomainEvent.java similarity index 95% rename from event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java rename to event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/DomainEvent.java index 6eb5141a2..fa6539a4f 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/api/DomainEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/DomainEvent.java @@ -20,11 +20,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.event.sourcing.api; +package com.iluwatar.event.sourcing.event; import java.io.Serializable; /** + * This is the base class for domain events. All events must extend this class. + * * Created by Serdar Hamzaogullari on 06.08.2017. */ public abstract class DomainEvent implements Serializable { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java index 3fb61bd08..1629263a7 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyDepositEvent.java @@ -22,18 +22,22 @@ */ package com.iluwatar.event.sourcing.event; -import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.domain.Account; import com.iluwatar.event.sourcing.state.AccountAggregate; import java.math.BigDecimal; /** + * This is the class that implements money deposit event. + * Holds the necessary info for a money deposit event. + * Implements the process function that finds the event related + * domain objects and calls the related domain object's handle event functions + * * Created by Serdar Hamzaogullari on 06.08.2017. */ public class MoneyDepositEvent extends DomainEvent { - private BigDecimal money; - private int accountNo; + private final BigDecimal money; + private final int accountNo; /** * Instantiates a new Money deposit event. diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java index bbba89988..0307d3af7 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyTransferEvent.java @@ -22,19 +22,23 @@ */ package com.iluwatar.event.sourcing.event; -import com.iluwatar.event.sourcing.api.DomainEvent; import com.iluwatar.event.sourcing.domain.Account; import com.iluwatar.event.sourcing.state.AccountAggregate; import java.math.BigDecimal; /** + * This is the class that implements money transfer event. + * Holds the necessary info for a money transfer event. + * Implements the process function that finds the event related + * domain objects and calls the related domain object's handle event functions + * * Created by Serdar Hamzaogullari on 06.08.2017. */ public class MoneyTransferEvent extends DomainEvent { - private BigDecimal money; - private int accountNoFrom; - private int accountNoTo; + private final BigDecimal money; + private final int accountNoFrom; + private final int accountNoTo; /** * Instantiates a new Money transfer event. @@ -63,7 +67,7 @@ public class MoneyTransferEvent extends DomainEvent { } /** - * Gets account no from. + * Gets account no which the money comes from. * * @return the account no from */ @@ -72,7 +76,7 @@ public class MoneyTransferEvent extends DomainEvent { } /** - * Gets account no to. + * Gets account no which the money goes to. * * @return the account no to */ diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java deleted file mode 100644 index d8c295002..000000000 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/event/MoneyWithdrawalEvent.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.event.sourcing.event; - -import com.iluwatar.event.sourcing.api.DomainEvent; -import com.iluwatar.event.sourcing.domain.Account; -import com.iluwatar.event.sourcing.state.AccountAggregate; -import java.math.BigDecimal; - -/** - * Created by Serdar Hamzaogullari on 06.08.2017. - */ -public class MoneyWithdrawalEvent extends DomainEvent { - - private BigDecimal money; - private int accountNo; - - /** - * Instantiates a new Money withdrawal event. - * - * @param sequenceId the sequence id - * @param createdTime the created time - * @param accountNo the account no - * @param money the money - */ - public MoneyWithdrawalEvent(long sequenceId, long createdTime, int accountNo, BigDecimal money) { - super(sequenceId, createdTime, "MoneyWithdrawalEvent"); - this.money = money; - this.accountNo = accountNo; - } - - /** - * Gets money. - * - * @return the money - */ - public BigDecimal getMoney() { - return money; - } - - /** - * Gets account no. - * - * @return the account no - */ - public int getAccountNo() { - return accountNo; - } - - @Override - public void process() { - Account account = AccountAggregate.getAccount(accountNo); - if (account == null) { - throw new RuntimeException("Account not found"); - } - account.handleEvent(this); - } -} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java deleted file mode 100644 index baaf41f56..000000000 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/AccountCreateContractSender.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.event.sourcing.gateway; - -import com.iluwatar.event.sourcing.domain.Account; - -/** - * Created by Serdar Hamzaogullari on 06.08.2017. - */ -public class AccountCreateContractSender { - - /** - * Send contract info. - * - * @param account the account - */ - public void sendContractInfo(Account account) { - // an example imaginary funciton which sends account info to some external end point - } -} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java deleted file mode 100644 index 84bdff3b2..000000000 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/Gateways.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.event.sourcing.gateway; - -/** - * Created by Serdar Hamzaogullari on 06.08.2017. - */ -public class Gateways { - - private static AccountCreateContractSender accountCreateContractSender = new AccountCreateContractSender(); - private static TransactionLogger transactionLogger = new TransactionLogger(); - - /** - * Gets account create contract sender. - * - * @return the account create contract sender - */ - public static AccountCreateContractSender getAccountCreateContractSender() { - return accountCreateContractSender; - } - - /** - * Gets transaction logger. - * - * @return the transaction logger - */ - public static TransactionLogger getTransactionLogger() { - return transactionLogger; - } -} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java deleted file mode 100644 index 42ae7a1f5..000000000 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/gateway/TransactionLogger.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.event.sourcing.gateway; - -import com.iluwatar.event.sourcing.domain.Transaction; - -/** - * Created by Serdar Hamzaogullari on 06.08.2017. - */ -public class TransactionLogger { - - /** - * Log. - * - * @param transaction the transaction - */ - public void log(Transaction transaction) { - // example imaginary function that logs the transaction to somewhere - } -} diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java index 38e72995d..05308c7c1 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/DomainEventProcessor.java @@ -22,33 +22,43 @@ */ package com.iluwatar.event.sourcing.processor; -import com.iluwatar.event.sourcing.api.DomainEvent; -import com.iluwatar.event.sourcing.api.EventProcessor; -import com.iluwatar.event.sourcing.api.ProcessorJournal; +import com.iluwatar.event.sourcing.event.DomainEvent; /** + * This is the implementation of event processor. + * All events are processed by this class. + * This processor uses processorJournal to persist and recover events. + * * Created by Serdar Hamzaogullari on 06.08.2017. */ -public class DomainEventProcessor implements EventProcessor { +public class DomainEventProcessor { - private ProcessorJournal precessorJournal; + private final JsonFileJournal processorJournal = new JsonFileJournal(); - @Override + /** + * Process. + * + * @param domainEvent the domain event + */ public void process(DomainEvent domainEvent) { domainEvent.process(); - precessorJournal.write(domainEvent); + processorJournal.write(domainEvent); } - @Override - public void setPrecessorJournal(ProcessorJournal precessorJournal) { - this.precessorJournal = precessorJournal; + /** + * Reset. + */ + public void reset() { + processorJournal.reset(); } - @Override + /** + * Recover. + */ public void recover() { DomainEvent domainEvent; while (true) { - domainEvent = precessorJournal.readNext(); + domainEvent = processorJournal.readNext(); if (domainEvent == null) { break; } else { diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/JsonFileJournal.java similarity index 84% rename from event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java rename to event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/JsonFileJournal.java index 9379e7b5c..870d8d00f 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/journal/JsonFileJournal.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/processor/JsonFileJournal.java @@ -20,17 +20,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.event.sourcing.journal; +package com.iluwatar.event.sourcing.processor; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonParser; -import com.iluwatar.event.sourcing.api.DomainEvent; -import com.iluwatar.event.sourcing.api.ProcessorJournal; import com.iluwatar.event.sourcing.event.AccountCreateEvent; +import com.iluwatar.event.sourcing.event.DomainEvent; import com.iluwatar.event.sourcing.event.MoneyDepositEvent; import com.iluwatar.event.sourcing.event.MoneyTransferEvent; -import com.iluwatar.event.sourcing.event.MoneyWithdrawalEvent; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -44,12 +42,16 @@ import java.util.ArrayList; import java.util.List; /** + * This is the implementation of event journal. + * This implementation serialize/deserialize the events with JSON + * and writes/reads them on a Journal.json file at the working directory. + * * Created by Serdar Hamzaogullari on 06.08.2017. */ -public class JsonFileJournal implements ProcessorJournal { +public class JsonFileJournal { - private File aFile; - private List events = new ArrayList<>(); + private final File aFile; + private final List events = new ArrayList<>(); private int index = 0; /** @@ -72,7 +74,12 @@ public class JsonFileJournal implements ProcessorJournal { } } - @Override + + /** + * Write. + * + * @param domainEvent the domain event + */ public void write(DomainEvent domainEvent) { Gson gson = new Gson(); JsonElement jsonElement; @@ -80,9 +87,7 @@ public class JsonFileJournal implements ProcessorJournal { jsonElement = gson.toJsonTree(domainEvent, AccountCreateEvent.class); } else if (domainEvent instanceof MoneyDepositEvent) { jsonElement = gson.toJsonTree(domainEvent, MoneyDepositEvent.class); - } else if (domainEvent instanceof MoneyWithdrawalEvent) { - jsonElement = gson.toJsonTree(domainEvent, MoneyWithdrawalEvent.class); - } else if (domainEvent instanceof MoneyTransferEvent) { + } else if (domainEvent instanceof MoneyTransferEvent) { jsonElement = gson.toJsonTree(domainEvent, MoneyTransferEvent.class); } else { throw new RuntimeException("Journal Event not recegnized"); @@ -97,13 +102,20 @@ public class JsonFileJournal implements ProcessorJournal { } } - @Override + + /** + * Reset. + */ public void reset() { aFile.delete(); } - @Override + /** + * Read next domain event. + * + * @return the domain event + */ public DomainEvent readNext() { if (index >= events.size()) { return null; @@ -122,9 +134,7 @@ public class JsonFileJournal implements ProcessorJournal { domainEvent = gson.fromJson(jsonElement, MoneyDepositEvent.class); } else if (eventClassName.equals("MoneyTransferEvent")) { domainEvent = gson.fromJson(jsonElement, MoneyTransferEvent.class); - } else if (eventClassName.equals("MoneyWithdrawalEvent")) { - domainEvent = gson.fromJson(jsonElement, MoneyWithdrawalEvent.class); - } else { + } else { throw new RuntimeException("Journal Event not recegnized"); } diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java index cfe0cfbb3..2d957268e 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/state/AccountAggregate.java @@ -27,12 +27,18 @@ import java.util.HashMap; import java.util.Map; /** + * This is the static accounts map holder class. + * This class holds the state of the accounts. + * * Created by Serdar Hamzaogullari on 06.08.2017. */ public class AccountAggregate { private static Map accounts = new HashMap<>(); + private AccountAggregate() { + } + /** * Put account. * @@ -46,7 +52,7 @@ public class AccountAggregate { * Gets account. * * @param accountNo the account no - * @return the account + * @return the copy of the account or null if not found */ public static Account getAccount(int accountNo) { Account account = accounts.get(accountNo); diff --git a/event-sourcing/src/main/test/java/com/iluwatar/event/sourcing/IntegrationTest.java b/event-sourcing/src/test/java/IntegrationTest.java similarity index 59% rename from event-sourcing/src/main/test/java/com/iluwatar/event/sourcing/IntegrationTest.java rename to event-sourcing/src/test/java/IntegrationTest.java index 8fbed333d..5a3f5718a 100644 --- a/event-sourcing/src/main/test/java/com/iluwatar/event/sourcing/IntegrationTest.java +++ b/event-sourcing/src/test/java/IntegrationTest.java @@ -20,16 +20,18 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.event.sourcing; import static com.iluwatar.event.sourcing.app.App.ACCOUNT_OF_DAENERYS; import static com.iluwatar.event.sourcing.app.App.ACCOUNT_OF_JON; import com.iluwatar.event.sourcing.domain.Account; -import com.iluwatar.event.sourcing.journal.JsonFileJournal; +import com.iluwatar.event.sourcing.event.AccountCreateEvent; +import com.iluwatar.event.sourcing.event.MoneyDepositEvent; +import com.iluwatar.event.sourcing.event.MoneyTransferEvent; import com.iluwatar.event.sourcing.processor.DomainEventProcessor; import com.iluwatar.event.sourcing.state.AccountAggregate; import java.math.BigDecimal; +import java.util.Date; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -44,31 +46,14 @@ public class IntegrationTest { /** * The Domain event processor. */ - DomainEventProcessor domainEventProcessor; - /** - * The Json file journal. - */ - JsonFileJournal jsonFileJournal; - /** - * The Account service. - */ - AccountService accountService; - /** - * The Money transaction service. - */ - MoneyTransactionService moneyTransactionService; + private DomainEventProcessor eventProcessor; /** * Initialize. */ @Before public void initialize() { - domainEventProcessor = new DomainEventProcessor(); - jsonFileJournal = new JsonFileJournal(); - domainEventProcessor.setPrecessorJournal(jsonFileJournal); - accountService = new AccountService(domainEventProcessor); - moneyTransactionService = new MoneyTransactionService( - domainEventProcessor); + eventProcessor = new DomainEventProcessor(); } /** @@ -76,27 +61,31 @@ public class IntegrationTest { */ @Test public void testStateRecovery() { - jsonFileJournal.reset(); + eventProcessor.reset(); - accountService.createAccount(ACCOUNT_OF_DAENERYS, "Daenerys Targaryen"); - accountService.createAccount(ACCOUNT_OF_JON, "Jon Snow"); + eventProcessor.process(new AccountCreateEvent( + 0, new Date().getTime(), ACCOUNT_OF_DAENERYS, "Daenerys Targaryen")); - moneyTransactionService.depositMoney(ACCOUNT_OF_DAENERYS, new BigDecimal("100000")); - moneyTransactionService.depositMoney(ACCOUNT_OF_JON, new BigDecimal("100")); + eventProcessor.process(new AccountCreateEvent( + 1, new Date().getTime(), ACCOUNT_OF_JON, "Jon Snow")); - moneyTransactionService - .transferMoney(ACCOUNT_OF_DAENERYS, ACCOUNT_OF_JON, new BigDecimal("10000")); - moneyTransactionService.withdrawalMoney(ACCOUNT_OF_JON, new BigDecimal("1000")); + 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 MoneyTransferEvent( + 4, new Date().getTime(), new BigDecimal("10000"), ACCOUNT_OF_DAENERYS, + ACCOUNT_OF_JON)); Account accountOfDaenerysBeforeShotDown = AccountAggregate.getAccount(ACCOUNT_OF_DAENERYS); Account accountOfJonBeforeShotDown = AccountAggregate.getAccount(ACCOUNT_OF_JON); AccountAggregate.resetState(); - domainEventProcessor = new DomainEventProcessor(); - jsonFileJournal = new JsonFileJournal(); - domainEventProcessor.setPrecessorJournal(jsonFileJournal); - domainEventProcessor.recover(); + eventProcessor = new DomainEventProcessor(); + eventProcessor.recover(); Account accountOfDaenerysAfterShotDown = AccountAggregate.getAccount(ACCOUNT_OF_DAENERYS); Account accountOfJonAfterShotDown = AccountAggregate.getAccount(ACCOUNT_OF_JON); @@ -105,11 +94,6 @@ public class IntegrationTest { accountOfDaenerysAfterShotDown.getMoney()); Assert .assertEquals(accountOfJonBeforeShotDown.getMoney(), accountOfJonAfterShotDown.getMoney()); - Assert.assertEquals(accountOfDaenerysBeforeShotDown.getTransactions().size(), - accountOfDaenerysAfterShotDown.getTransactions().size()); - Assert.assertEquals(accountOfJonBeforeShotDown.getTransactions().size(), - accountOfJonAfterShotDown.getTransactions().size()); - } } \ No newline at end of file