Merge commit 'b16039ee5377311aa60f9c71b0a7c1559836b61e' into wip-customer

* commit 'b16039ee5377311aa60f9c71b0a7c1559836b61e':
  - added title and description fields to accountInfo - added GET /accounts?customerId=XXX endpoint - refactored tests
This commit is contained in:
Andrew Revinsky (DART)
2016-03-16 00:29:47 +03:00
21 changed files with 120 additions and 46 deletions

View File

@@ -16,7 +16,7 @@ public class Account extends ReflectiveMutableCommandProcessingAggregate<Account
private BigDecimal balance;
public List<Event> process(OpenAccountCommand cmd) {
return EventUtil.events(new AccountOpenedEvent(cmd.getCustomerId(), cmd.getTitle(), cmd.getInitialBalance()));
return EventUtil.events(new AccountOpenedEvent(cmd.getCustomerId(), cmd.getTitle(), cmd.getInitialBalance(), cmd.getDescription()));
}
public List<Event> process(DebitAccountCommand cmd) {

View File

@@ -14,8 +14,8 @@ public class AccountService {
this.accountRepository = accountRepository;
}
public rx.Observable<EntityWithIdAndVersion<Account>> openAccount(String customerId, String title, BigDecimal initialBalance) {
return accountRepository.save(new OpenAccountCommand(customerId, title, initialBalance));
public rx.Observable<EntityWithIdAndVersion<Account>> openAccount(String customerId, String title, BigDecimal initialBalance, String description) {
return accountRepository.save(new OpenAccountCommand(customerId, title, initialBalance, description));
}
}

View File

@@ -8,11 +8,13 @@ public class OpenAccountCommand implements AccountCommand {
private String customerId;
private String title;
private BigDecimal initialBalance;
private String description;
public OpenAccountCommand(String customerId, String title, BigDecimal initialBalance) {
public OpenAccountCommand(String customerId, String title, BigDecimal initialBalance, String description) {
this.customerId = customerId;
this.title = title;
this.initialBalance = initialBalance;
this.description = description;
}
public BigDecimal getInitialBalance() {
@@ -26,4 +28,8 @@ public class OpenAccountCommand implements AccountCommand {
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
}

View File

@@ -17,7 +17,7 @@ public class AccountTest {
String title = "My Account";
String customerId = "00000000-00000000";
BigDecimal initialBalance = new BigDecimal(512);
List<Event> events = CommandProcessingAggregates.processToList(account, (AccountCommand)new OpenAccountCommand(customerId, title, initialBalance));
List<Event> events = CommandProcessingAggregates.processToList(account, (AccountCommand)new OpenAccountCommand(customerId, title, initialBalance, ""));
Assert.assertEquals(1, events.size());
Assert.assertEquals(AccountOpenedEvent.class, events.get(0).getClass());

View File

@@ -40,10 +40,10 @@ public class AccountsCommandSideServiceIntegrationTest {
String customerId = "00000000-00000000";
String title = "My Account";
final CreateAccountResponse fromAccount = restTemplate.postForEntity(baseUrl("/accounts"), new CreateAccountRequest(customerId, title, initialFromAccountBalance), CreateAccountResponse.class).getBody();
final CreateAccountResponse fromAccount = restTemplate.postForEntity(baseUrl("/accounts"), new CreateAccountRequest(customerId, title, "", initialFromAccountBalance), CreateAccountResponse.class).getBody();
final String fromAccountId = fromAccount.getAccountId();
CreateAccountResponse toAccount = restTemplate.postForEntity(baseUrl("/accounts"), new CreateAccountRequest(customerId, title, initialToAccountBalance), CreateAccountResponse.class).getBody();
CreateAccountResponse toAccount = restTemplate.postForEntity(baseUrl("/accounts"), new CreateAccountRequest(customerId, title, "", initialToAccountBalance), CreateAccountResponse.class).getBody();
String toAccountId = toAccount.getAccountId();
Assert.assertNotNull(fromAccountId);

View File

@@ -22,7 +22,7 @@ public class AccountController {
@RequestMapping(method = RequestMethod.POST)
public Observable<CreateAccountResponse> createAccount(@Validated @RequestBody CreateAccountRequest request) {
return accountService.openAccount(request.getCustomerId(), request.getTitle(), request.getInitialBalance())
return accountService.openAccount(request.getCustomerId(), request.getTitle(), request.getInitialBalance(), request.getDescription())
.map(entityAndEventInfo -> new CreateAccountResponse(entityAndEventInfo.getEntityIdentifier().getId()));
}
}

View File

@@ -12,6 +12,8 @@ public class CreateAccountRequest {
private String title;
private String description;
@NotNull
@DecimalMin("0")
private BigDecimal initialBalance;
@@ -19,9 +21,10 @@ public class CreateAccountRequest {
public CreateAccountRequest() {
}
public CreateAccountRequest(String customerId, String title, BigDecimal initialBalance) {
public CreateAccountRequest(String customerId, String title, String description, BigDecimal initialBalance) {
this.customerId = customerId;
this.title = title;
this.description = description;
this.initialBalance = initialBalance;
}
@@ -48,4 +51,12 @@ public class CreateAccountRequest {
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@@ -10,6 +10,7 @@ public class AccountInfo {
private String id;
private String customerId;
private String title;
private String description;
private long balance;
private List<AccountChangeInfo> changes;
private List<AccountTransactionInfo> transactions;
@@ -18,11 +19,12 @@ public class AccountInfo {
private AccountInfo() {
}
public AccountInfo(String id, String customerId, String title, long balance, List<AccountChangeInfo> changes, List<AccountTransactionInfo> transactions, String version) {
public AccountInfo(String id, String customerId, String title, String description, long balance, List<AccountChangeInfo> changes, List<AccountTransactionInfo> transactions, String version) {
this.id = id;
this.customerId = customerId;
this.title = title;
this.description = description;
this.balance = balance;
this.changes = changes;
this.transactions = transactions;
@@ -41,6 +43,10 @@ public class AccountInfo {
return title;
}
public String getDescription() {
return description;
}
public long getBalance() {
return balance;
}

View File

@@ -2,5 +2,9 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.ac
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;
interface AccountInfoRepository extends MongoRepository<AccountInfo, String> {
List<AccountInfo> findByCustomerId(String customerId);
}

View File

@@ -26,12 +26,13 @@ public class AccountInfoUpdateService {
public void create(String accountId, String customerId, String title, BigDecimal initialBalance, String version) {
public void create(String accountId, String customerId, String title, BigDecimal initialBalance, String description, String version) {
try {
accountInfoRepository.save(new AccountInfo(
accountId,
customerId,
title,
description,
toIntegerRepr(initialBalance),
Collections.<AccountChangeInfo>emptyList(),
Collections.<AccountTransactionInfo>emptyList(),

View File

@@ -3,8 +3,11 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.ac
import net.chrisrichardson.eventstore.Aggregate;
import net.chrisrichardson.eventstore.EntityIdentifier;
import net.chrisrichardson.eventstore.EntityNotFoundException;
import org.springframework.dao.EmptyResultDataAccessException;
import rx.Observable;
import java.util.List;
public class AccountQueryService {
private AccountInfoRepository accountInfoRepository;
@@ -20,4 +23,12 @@ public class AccountQueryService {
else
return Observable.just(account);
}
public Observable<List<AccountInfo>> findByCustomerId(String customerId) {
List<AccountInfo> result = accountInfoRepository.findByCustomerId(customerId);
if(result.isEmpty())
return Observable.error(new EmptyResultDataAccessException(1));
else
return Observable.just(result);
}
}

View File

@@ -39,7 +39,8 @@ public class AccountQueryWorkflow implements CompoundEventHandler {
BigDecimal initialBalance = event.getInitialBalance();
String customerId = event.getCustomerId();
String title = event.getTitle();
accountInfoUpdateService.create(id, customerId, title, initialBalance, eventId);
String description = event.getDescription();
accountInfoUpdateService.create(id, customerId, title, initialBalance, description, eventId);
return Observable.just(null);
}

View File

@@ -9,6 +9,8 @@ import org.springframework.web.bind.annotation.*;
import rx.Observable;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
@RestController
public class AccountQueryController {
@@ -23,7 +25,13 @@ public class AccountQueryController {
@RequestMapping(value="/accounts/{accountId}", method = RequestMethod.GET)
public Observable<GetAccountResponse> get(@PathVariable String accountId) {
return accountInfoQueryService.findByAccountId(new EntityIdentifier(accountId))
.map(accountInfo -> new GetAccountResponse(accountInfo.getId(), new BigDecimal(accountInfo.getBalance())));
.map(accountInfo -> new GetAccountResponse(accountInfo.getId(), new BigDecimal(accountInfo.getBalance()), accountInfo.getTitle(), accountInfo.getDescription()));
}
@RequestMapping(value = "/accounts", method = RequestMethod.GET)
public Observable<List<GetAccountResponse>> getAccountsForCustomer(@RequestParam("customerId") String customerId) {
return accountInfoQueryService.findByCustomerId(customerId)
.map(accountInfoList -> accountInfoList.stream().map(accountInfo -> new GetAccountResponse(accountInfo.getId(), new BigDecimal(accountInfo.getBalance()), accountInfo.getTitle(), accountInfo.getDescription())).collect(Collectors.toList()));
}
@ResponseStatus(value= HttpStatus.NOT_FOUND, reason="account not found")

View File

@@ -4,30 +4,50 @@ import java.math.BigDecimal;
public class GetAccountResponse {
private String accountId;
private BigDecimal balance;
private String accountId;
private BigDecimal balance;
private String title;
private String description;
public GetAccountResponse() {
}
public GetAccountResponse() {
}
public GetAccountResponse(String accountId, BigDecimal balance) {
this.accountId = accountId;
this.balance = balance;
}
public GetAccountResponse(String accountId, BigDecimal balance, String title, String description) {
this.accountId = accountId;
this.balance = balance;
this.title = title;
this.description = description;
}
public void setBalance(BigDecimal balance) {
this.balance = balance;
}
public void setBalance(BigDecimal balance) {
this.balance = balance;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public String getAccountId() {
return accountId;
}
public String getAccountId() {
return accountId;
}
public BigDecimal getBalance() {
return balance;
}
public BigDecimal getBalance() {
return balance;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@@ -43,9 +43,9 @@ public class MoneyTransferIntegrationTest {
@Test
public void shouldTransferMoney() {
final EntityWithIdAndVersion<Account> fromAccount= await(accountService.openAccount("00000000-00000000", "My Account", new BigDecimal(150)));
final EntityWithIdAndVersion<Account> fromAccount= await(accountService.openAccount("00000000-00000000", "My Account", new BigDecimal(150), ""));
final EntityWithIdAndVersion<Account> toAccount = await(accountService.openAccount("00000000-00000000", "My Account", new BigDecimal(300)));
final EntityWithIdAndVersion<Account> toAccount = await(accountService.openAccount("00000000-00000000", "My Account", new BigDecimal(300), ""));
final EntityWithIdAndVersion<MoneyTransfer> transaction = await(
moneyTransferService.transferMoney(new TransferDetails(fromAccount.getEntityIdentifier(),
@@ -98,9 +98,9 @@ public class MoneyTransferIntegrationTest {
@Test
public void shouldFailDueToInsufficientFunds() {
final EntityWithIdAndVersion<Account> fromAccount= await(accountService.openAccount("00000000-00000000", "My Account", new BigDecimal(150)));
final EntityWithIdAndVersion<Account> fromAccount= await(accountService.openAccount("00000000-00000000", "My Account", new BigDecimal(150), ""));
final EntityWithIdAndVersion<Account> toAccount = await(accountService.openAccount("00000000-00000000", "My Account", new BigDecimal(300)));
final EntityWithIdAndVersion<Account> toAccount = await(accountService.openAccount("00000000-00000000", "My Account", new BigDecimal(300), ""));
final EntityWithIdAndVersion<MoneyTransfer> transaction = await(
moneyTransferService.transferMoney(new TransferDetails(fromAccount.getEntityIdentifier(),

View File

@@ -45,9 +45,9 @@ public class AccountQuerySideIntegrationTest {
@Test
public void shouldUpdateQuerySide() throws Exception {
final EntityWithIdAndVersion<Account> fromAccount = await(accountService.openAccount("00000000-00000000", "My Account", new BigDecimal(150)));
final EntityWithIdAndVersion<Account> fromAccount = await(accountService.openAccount("00000000-00000000", "My Account", new BigDecimal(150), ""));
final EntityWithIdAndVersion<Account> toAccount = await(accountService.openAccount("00000000-00000000", "My Account", new BigDecimal(300)));
final EntityWithIdAndVersion<Account> toAccount = await(accountService.openAccount("00000000-00000000", "My Account", new BigDecimal(300), ""));
final EntityWithIdAndVersion<MoneyTransfer> transaction = await(
moneyTransferService.transferMoney(new TransferDetails(fromAccount.getEntityIdentifier(),

View File

@@ -10,14 +10,16 @@ public class AccountOpenedEvent implements Event {
private String customerId;
private String title;
private BigDecimal initialBalance;
private String description;
private AccountOpenedEvent() {
}
public AccountOpenedEvent(String customerId, String title, BigDecimal initialBalance) {
public AccountOpenedEvent(String customerId, String title, BigDecimal initialBalance, String description) {
this.customerId = customerId;
this.title = title;
this.initialBalance = initialBalance;
this.description = description;
}
public String getCustomerId() {
@@ -31,4 +33,8 @@ public class AccountOpenedEvent implements Event {
public BigDecimal getInitialBalance() {
return initialBalance;
}
public String getDescription() {
return description;
}
}

View File

@@ -13,7 +13,7 @@ public class AccountOpenEventSerializationTest {
@Test
public void shouldSerde() {
AccountOpenedEvent event = new AccountOpenedEvent("00000000-00000000", "My Account", new BigDecimal(55));
AccountOpenedEvent event = new AccountOpenedEvent("00000000-00000000", "My Account", new BigDecimal(55), "");
String json = JSonMapper.toJson(event, EventStoreCommonObjectMapping.getObjectMapper());
System.out.println("json=" + json);

View File

@@ -46,7 +46,7 @@ accountsqueryside:
working_dir: /app
volumes:
- ./accounts-query-side-service/build/libs:/app
command: java -jar /app/accounts-query-side-service.jar
command: java -jar /app/accounts-query-side-service.jar
ports:
- "8081:8080"
links:

View File

@@ -91,7 +91,7 @@ public class EndToEndTest {
accountsCommandSideBaseUrl("/accounts"),
HttpMethod.POST,
CreateAccountResponse.class,
new CreateAccountRequest(customerId, "My #1 Account", initialFromAccountBalance)
new CreateAccountRequest(customerId, "My #1 Account", "", initialFromAccountBalance)
);
final String fromAccountId = fromAccount.getAccountId();
@@ -99,7 +99,7 @@ public class EndToEndTest {
accountsCommandSideBaseUrl("/accounts"),
HttpMethod.POST,
CreateAccountResponse.class,
new CreateAccountRequest(customerId, "My #2 Account", initialToAccountBalance)
new CreateAccountRequest(customerId, "My #2 Account", "", initialToAccountBalance)
);
String toAccountId = toAccount.getAccountId();

View File

@@ -67,7 +67,7 @@ public class BankingWebIntegrationTest {
baseUrl("/accounts"),
HttpMethod.POST,
CreateAccountResponse.class,
new CreateAccountRequest("00000000-00000000", "My 1 Account", initialFromAccountBalance)
new CreateAccountRequest("00000000-00000000", "My 1 Account", "", initialFromAccountBalance)
);
final String fromAccountId = fromAccount.getAccountId();
@@ -75,7 +75,7 @@ public class BankingWebIntegrationTest {
baseUrl("/accounts"),
HttpMethod.POST,
CreateAccountResponse.class,
new CreateAccountRequest("00000000-00000000", "My 2 Account", initialToAccountBalance)
new CreateAccountRequest("00000000-00000000", "My 2 Account", "", initialToAccountBalance)
);
String toAccountId = toAccount.getAccountId();