diff --git a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoUpdateService.java b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoUpdateService.java index 82492d2..2161ffb 100644 --- a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoUpdateService.java +++ b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountInfoUpdateService.java @@ -3,6 +3,7 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.ac import com.mongodb.WriteResult; import net.chrisrichardson.eventstore.javaexamples.banking.common.accounts.AccountChangeInfo; import net.chrisrichardson.eventstore.javaexamples.banking.common.accounts.AccountTransactionInfo; +import net.chrisrichardson.eventstore.javaexamples.banking.common.transactions.TransferState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.DuplicateKeyException; @@ -69,5 +70,13 @@ public class AccountInfoUpdateService { AccountInfo.class); } + public void updateTransactionStatus(String accountId, String transactionId, TransferState status) { + AccountInfo account = accountInfoRepository.findOne(accountId); + if (account != null) { + account.getTransactions().stream().filter(ati -> ati.getTransactionId().equals(transactionId)).forEach(ati -> ati.setStatus(status)); + accountInfoRepository.save(account); + } + + } } diff --git a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQueryWorkflow.java b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQueryWorkflow.java index cc87937..39ddded 100644 --- a/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQueryWorkflow.java +++ b/java-spring/accounts-query-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQueryWorkflow.java @@ -3,13 +3,14 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.ac import io.eventuate.DispatchedEvent; import io.eventuate.EventHandlerMethod; import io.eventuate.EventSubscriber; -import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.accounts.AccountChangedEvent; -import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.accounts.AccountCreditedEvent; -import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.accounts.AccountDebitedEvent; -import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.accounts.AccountOpenedEvent; +import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.accounts.*; +import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.transactions.CreditRecordedEvent; +import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.transactions.DebitRecordedEvent; +import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.transactions.FailedDebitRecordedEvent; import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.transactions.MoneyTransferCreatedEvent; import net.chrisrichardson.eventstore.javaexamples.banking.common.accounts.AccountChangeInfo; import net.chrisrichardson.eventstore.javaexamples.banking.common.accounts.AccountTransactionInfo; +import net.chrisrichardson.eventstore.javaexamples.banking.common.transactions.TransferState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,14 +65,30 @@ public class AccountQueryWorkflow { @EventHandlerMethod public void recordDebit(DispatchedEvent de) { + String accountId = de.getEntityId(); + String transactionId = de.getEvent().getTransactionId(); + + accountInfoUpdateService.updateTransactionStatus(accountId, transactionId, TransferState.DEBITED); saveChange(de, -1); } @EventHandlerMethod public void recordCredit(DispatchedEvent de) { + String accountId = de.getEntityId(); + String transactionId = de.getEvent().getTransactionId(); + + accountInfoUpdateService.updateTransactionStatus(accountId, transactionId, TransferState.COMPLETED); saveChange(de, +1); } + @EventHandlerMethod + public void recordFailed(DispatchedEvent de) { + String accountId = de.getEntityId(); + String transactionId = de.getEvent().getTransactionId(); + + accountInfoUpdateService.updateTransactionStatus(accountId, transactionId, TransferState.FAILED_DUE_TO_INSUFFICIENT_FUNDS); + } + public void saveChange(DispatchedEvent de, int delta) { String changeId = de.getEventId().asString(); String transactionId = de.getEvent().getTransactionId(); diff --git a/java-spring/accounts-query-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/accounts/AccountQueryController.java b/java-spring/accounts-query-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/accounts/AccountQueryController.java index 52d4f92..a9b63ee 100644 --- a/java-spring/accounts-query-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/accounts/AccountQueryController.java +++ b/java-spring/accounts-query-side-web/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/web/queryside/accounts/AccountQueryController.java @@ -1,5 +1,6 @@ package net.chrisrichardson.eventstore.javaexamples.banking.web.queryside.accounts; +import com.fasterxml.jackson.databind.ObjectMapper; import net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.accounts.AccountInfo; import net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.accounts.AccountNotFoundException; @@ -11,10 +12,9 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.List; -import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; -import java.util.stream.Stream; @RestController public class AccountQueryController { @@ -51,9 +51,11 @@ public class AccountQueryController { @RequestMapping(value = "/accounts/{accountId}/history", method = RequestMethod.GET) public ResponseEntity getTransactionsHistory(@PathVariable String accountId) { AccountInfo accountInfo = accountInfoQueryService.findByAccountId(accountId); - return ResponseEntity.ok().body(new AccountHistoryResponse(new AccountHistoryEntry(accountInfo.getDate()), - accountInfo.getTransactions(), - accountInfo.getChanges())); + List historyEntries = new ArrayList<>(); + historyEntries.add(new AccountOpenInfo(accountInfo.getDate(), AccountHistoryEntry.EntryType.account)); + accountInfo.getTransactions().forEach(historyEntries::add); + + return ResponseEntity.ok().body(new AccountHistoryResponse(historyEntries)); } @ResponseStatus(value= HttpStatus.NOT_FOUND, reason="account not found") diff --git a/java-spring/backend-integration-tests/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/MoneyTransferIntegrationTest.java b/java-spring/backend-integration-tests/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/MoneyTransferIntegrationTest.java index 6516ee4..0f7df9c 100644 --- a/java-spring/backend-integration-tests/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/MoneyTransferIntegrationTest.java +++ b/java-spring/backend-integration-tests/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/MoneyTransferIntegrationTest.java @@ -6,7 +6,7 @@ import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.a import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.accounts.AccountService; import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.transactions.MoneyTransfer; import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.transactions.MoneyTransferService; -import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.transactions.TransferState; +import net.chrisrichardson.eventstore.javaexamples.banking.common.transactions.TransferState; import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.transactions.TransferDetails; import org.junit.Assert; import org.junit.Test; diff --git a/java-spring/backend-integration-tests/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQuerySideIntegrationTest.java b/java-spring/backend-integration-tests/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQuerySideIntegrationTest.java index 7d6d0df..46cba9b 100644 --- a/java-spring/backend-integration-tests/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQuerySideIntegrationTest.java +++ b/java-spring/backend-integration-tests/src/test/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/queryside/accounts/AccountQuerySideIntegrationTest.java @@ -6,7 +6,7 @@ import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.a import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.accounts.AccountService; import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.transactions.MoneyTransfer; import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.transactions.MoneyTransferService; -import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.transactions.TransferState; +import net.chrisrichardson.eventstore.javaexamples.banking.common.transactions.TransferState; import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.transactions.TransferDetails; import org.junit.Assert; import org.junit.Test; diff --git a/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountHistoryEntry.java b/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountHistoryEntry.java index 11866b0..f91c2e7 100644 --- a/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountHistoryEntry.java +++ b/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountHistoryEntry.java @@ -1,19 +1,31 @@ package net.chrisrichardson.eventstore.javaexamples.banking.common.accounts; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + import java.util.Date; /** * Created by popikyardo on 9/1/16. */ +@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, + include = JsonTypeInfo.As.PROPERTY, + property = "entryType") +@JsonSubTypes({ + @JsonSubTypes.Type(value = AccountTransactionInfo.class, name = "transaction"), + @JsonSubTypes.Type(value = AccountOpenInfo.class, name = "account") +}) public class AccountHistoryEntry { protected Date date; + protected EntryType entryType; public AccountHistoryEntry() { } - public AccountHistoryEntry(Date date) { + public AccountHistoryEntry(Date date, EntryType entryType) { this.date = date; + this.entryType = entryType; } public Date getDate() { @@ -23,4 +35,16 @@ public class AccountHistoryEntry { public void setDate(Date date) { this.date = date; } + + public EntryType getEntryType() { + return entryType; + } + + public void setEntryType(EntryType entryType) { + this.entryType = entryType; + } + + public enum EntryType { + transaction, account + } } diff --git a/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountHistoryResponse.java b/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountHistoryResponse.java index 6f7c0e7..b20d958 100644 --- a/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountHistoryResponse.java +++ b/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountHistoryResponse.java @@ -6,40 +6,21 @@ import java.util.List; * Created by popikyardo on 9/1/16. */ public class AccountHistoryResponse { - private AccountHistoryEntry accountOpened; - private List transactionsHistory; - private List accountChangesHistory; + private List transactionsHistory; public AccountHistoryResponse() { } - public AccountHistoryResponse(AccountHistoryEntry accountOpened, List transactionsHistory, List accountChangesHistory) { - this.accountOpened = accountOpened; + public AccountHistoryResponse(List transactionsHistory) { + this.transactionsHistory = transactionsHistory; - this.accountChangesHistory = accountChangesHistory; } - public AccountHistoryEntry getAccountOpened() { - return accountOpened; - } - - public void setAccountOpened(AccountHistoryEntry accountOpened) { - this.accountOpened = accountOpened; - } - - public List getTransactionsHistory() { + public List getTransactionsHistory() { return transactionsHistory; } - public void setTransactionsHistory(List transactionsHistory) { + public void setTransactionsHistory(List transactionsHistory) { this.transactionsHistory = transactionsHistory; } - - public List getAccountChangesHistory() { - return accountChangesHistory; - } - - public void setAccountChangesHistory(List accountChangesHistory) { - this.accountChangesHistory = accountChangesHistory; - } } diff --git a/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountOpenInfo.java b/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountOpenInfo.java new file mode 100644 index 0000000..8136b22 --- /dev/null +++ b/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountOpenInfo.java @@ -0,0 +1,16 @@ +package net.chrisrichardson.eventstore.javaexamples.banking.common.accounts; + +import java.util.Date; + +/** + * Created by popikyardo on 9/1/16. + */ +public class AccountOpenInfo extends AccountHistoryEntry { + + public AccountOpenInfo() { + } + + public AccountOpenInfo(Date date, EntryType entryType) { + super(date, entryType); + } +} diff --git a/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountTransactionInfo.java b/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountTransactionInfo.java index d168bf5..6cc88d5 100644 --- a/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountTransactionInfo.java +++ b/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/accounts/AccountTransactionInfo.java @@ -1,19 +1,20 @@ package net.chrisrichardson.eventstore.javaexamples.banking.common.accounts; +import net.chrisrichardson.eventstore.javaexamples.banking.common.transactions.TransferState; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import java.util.Date; -public class AccountTransactionInfo { +public class AccountTransactionInfo extends AccountHistoryEntry{ private String transactionId; private String fromAccountId; private String toAccountId; private long amount; - private Date date; private String description; + private TransferState status = TransferState.INITIAL; public AccountTransactionInfo() { } @@ -35,6 +36,7 @@ public class AccountTransactionInfo { this.amount = amount; this.date = date; this.description = description; + this.entryType = EntryType.transaction; } public String getTransactionId() { @@ -69,14 +71,6 @@ public class AccountTransactionInfo { this.amount = amount; } - public Date getDate() { - return date; - } - - public void setDate(Date date) { - this.date = date; - } - public String getDescription() { return description; } @@ -85,6 +79,14 @@ public class AccountTransactionInfo { this.description = description; } + public TransferState getStatus() { + return status; + } + + public void setStatus(TransferState status) { + this.status = status; + } + @Override public boolean equals(Object o) { return EqualsBuilder.reflectionEquals(this, o); diff --git a/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/TransferState.java b/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/transactions/TransferState.java similarity index 51% rename from java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/TransferState.java rename to java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/transactions/TransferState.java index 539d2ad..993f12d 100644 --- a/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/TransferState.java +++ b/java-spring/common/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/common/transactions/TransferState.java @@ -1,4 +1,4 @@ -package net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.transactions; +package net.chrisrichardson.eventstore.javaexamples.banking.common.transactions; public enum TransferState { NEW, INITIAL, DEBITED, COMPLETED, FAILED_DUE_TO_INSUFFICIENT_FUNDS diff --git a/java-spring/testutil/src/main/java/net/chrisrichardson/eventstorestore/javaexamples/testutil/AbstractRestAPITest.java b/java-spring/testutil/src/main/java/net/chrisrichardson/eventstorestore/javaexamples/testutil/AbstractRestAPITest.java index 391668e..a0faecb 100644 --- a/java-spring/testutil/src/main/java/net/chrisrichardson/eventstorestore/javaexamples/testutil/AbstractRestAPITest.java +++ b/java-spring/testutil/src/main/java/net/chrisrichardson/eventstorestore/javaexamples/testutil/AbstractRestAPITest.java @@ -69,11 +69,11 @@ public abstract class AbstractRestAPITest { new Verifier() { @Override public void verify(AccountHistoryResponse accountHistoryResponse) { - Optional first = accountHistoryResponse.getTransactionsHistory().stream().filter(ti -> ti.getTransactionId().equals(moneyTransfer.getMoneyTransferId())).findFirst(); + Optional first = accountHistoryResponse.getTransactionsHistory().stream().filter( ahe -> ahe.getEntryType() == AccountHistoryEntry.EntryType.transaction && ((AccountTransactionInfo)ahe).getTransactionId().equals(moneyTransfer.getMoneyTransferId())).findFirst(); assertTrue(first.isPresent()); - AccountTransactionInfo ti = first.get(); + AccountTransactionInfo ti = (AccountTransactionInfo)first.get(); assertEquals(fromAccountId, ti.getFromAccountId()); assertEquals(toAccountId, ti.getToAccountId()); @@ -111,7 +111,7 @@ public abstract class AbstractRestAPITest { new Producer() { @Override public CompletableFuture produce() { - return CompletableFuture.completedFuture(getAuthenticatedRestTemplate().getForEntity(baseUrl("/accounts?customerId=" + customerId), + return CompletableFuture.completedFuture(getAuthenticatedRestTemplate().getForEntity(baseUrl("/customer/"+customerId+"/accounts"), GetAccountsResponse.class)); } }, diff --git a/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransfer.java b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransfer.java index 896e8b7..849175a 100644 --- a/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransfer.java +++ b/java-spring/transactions-command-side-backend/src/main/java/net/chrisrichardson/eventstore/javaexamples/banking/backend/commandside/transactions/MoneyTransfer.java @@ -4,6 +4,7 @@ import io.eventuate.Event; import io.eventuate.EventUtil; import io.eventuate.ReflectiveMutableCommandProcessingAggregate; import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.transactions.*; +import net.chrisrichardson.eventstore.javaexamples.banking.common.transactions.TransferState; import java.util.List;