Skip to content

Commit

Permalink
simplifiex code examples
Browse files Browse the repository at this point in the history
  • Loading branch information
thombergs committed Sep 30, 2019
1 parent e828509 commit 8bde954
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 34 deletions.
Expand Up @@ -12,9 +12,10 @@
import io.reflectoring.buckpal.domain.Account.AccountId;
import io.reflectoring.buckpal.domain.Activity;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@RequiredArgsConstructor
@PersistenceAdapter
@Component
class AccountPersistenceAdapter implements
LoadAccountPort,
UpdateAccountStatePort {
Expand All @@ -24,7 +25,9 @@ class AccountPersistenceAdapter implements
private final AccountMapper accountMapper;

@Override
public Account loadAccount(AccountId accountId, LocalDateTime baselineDate) {
public Account loadAccount(
AccountId accountId,
LocalDateTime baselineDate) {

AccountJpaEntity account =
accountRepository.findById(accountId.getValue())
Expand Down
Expand Up @@ -15,7 +15,7 @@ public class SendMoneyController {

private final SendMoneyUseCase sendMoneyUseCase;

@PostMapping(path = "/accounts/sendMoney/{sourceAccountId}/{targetAccountId}/{amount}")
@PostMapping(path = "/accounts/send/{sourceAccountId}/{targetAccountId}/{amount}")
void sendMoney(
@PathVariable("sourceAccountId") Long sourceAccountId,
@PathVariable("targetAccountId") Long targetAccountId,
Expand Down
Expand Up @@ -25,7 +25,7 @@ class SendMoneyControllerTest {
@Test
void testSendMoney() throws Exception {

mockMvc.perform(post("/accounts/sendMoney/{sourceAccountId}/{targetAccountId}/{amount}",
mockMvc.perform(post("/accounts/send/{sourceAccountId}/{targetAccountId}/{amount}",
41L, 42L, 500)
.header("Content-Type", "application/json"))
.andExpect(status().isOk());
Expand All @@ -37,4 +37,4 @@ void testSendMoney() throws Exception {
Money.of(500L))));
}

}
}
@@ -1,13 +1,13 @@
package io.reflectoring.buckpal.application.port.in;

import javax.validation.constraints.NotNull;

import io.reflectoring.buckpal.domain.Account;
import io.reflectoring.buckpal.domain.Account.AccountId;
import io.reflectoring.buckpal.domain.Money;
import io.reflectoring.buckpal.testdata.SelfValidating;
import lombok.EqualsAndHashCode;
import lombok.Value;

import javax.validation.constraints.NotNull;

public interface SendMoneyUseCase {

boolean sendMoney(SendMoneyCommand command);
Expand All @@ -17,17 +17,17 @@ public interface SendMoneyUseCase {
class SendMoneyCommand extends SelfValidating<SendMoneyCommand> {

@NotNull
private final Account.AccountId sourceAccountId;
private final AccountId sourceAccountId;

@NotNull
private final Account.AccountId targetAccountId;
private final AccountId targetAccountId;

@NotNull
private final Money money;

public SendMoneyCommand(
Account.AccountId sourceAccountId,
Account.AccountId targetAccountId,
AccountId sourceAccountId,
AccountId targetAccountId,
Money money) {
this.sourceAccountId = sourceAccountId;
this.targetAccountId = targetAccountId;
Expand Down
Expand Up @@ -5,14 +5,16 @@
import io.reflectoring.buckpal.application.port.out.LoadAccountPort;
import io.reflectoring.buckpal.application.port.out.UpdateAccountStatePort;
import io.reflectoring.buckpal.domain.Account;
import io.reflectoring.buckpal.domain.Account.AccountId;
import io.reflectoring.buckpal.testdata.UseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import javax.transaction.Transactional;
import java.time.LocalDateTime;

@RequiredArgsConstructor
@UseCase
@Component
@Transactional
public class SendMoneyService implements SendMoneyUseCase {

Expand All @@ -24,9 +26,7 @@ public class SendMoneyService implements SendMoneyUseCase {
@Override
public boolean sendMoney(SendMoneyCommand command) {

if(command.getMoney().isGreaterThan(moneyTransferProperties.getMaximumTransferThreshold())){
throw new ThresholdExceededException(moneyTransferProperties.getMaximumTransferThreshold(), command.getMoney());
}
checkThreshold(command);

LocalDateTime baselineDate = LocalDateTime.now().minusDays(10);

Expand All @@ -38,25 +38,36 @@ public boolean sendMoney(SendMoneyCommand command) {
command.getTargetAccountId(),
baselineDate);

accountLock.lockAccount(sourceAccount.getId());
if (!sourceAccount.withdraw(command.getMoney(), targetAccount.getId())) {
accountLock.releaseAccount(sourceAccount.getId());
AccountId sourceAccountId = sourceAccount.getId()
.orElseThrow(() -> new IllegalStateException("expected source account ID not to be empty"));
AccountId targetAccountId = targetAccount.getId()
.orElseThrow(() -> new IllegalStateException("expected target account ID not to be empty"));

accountLock.lockAccount(sourceAccountId);
if (!sourceAccount.withdraw(command.getMoney(), targetAccountId)) {
accountLock.releaseAccount(sourceAccountId);
return false;
}

accountLock.lockAccount(targetAccount.getId());
if (!targetAccount.deposit(command.getMoney(), sourceAccount.getId())) {
accountLock.releaseAccount(sourceAccount.getId());
accountLock.releaseAccount(targetAccount.getId());
accountLock.lockAccount(targetAccountId);
if (!targetAccount.deposit(command.getMoney(), sourceAccountId)) {
accountLock.releaseAccount(sourceAccountId);
accountLock.releaseAccount(targetAccountId);
return false;
}

updateAccountStatePort.updateActivities(sourceAccount);
updateAccountStatePort.updateActivities(targetAccount);

accountLock.releaseAccount(sourceAccount.getId());
accountLock.releaseAccount(targetAccount.getId());
accountLock.releaseAccount(sourceAccountId);
accountLock.releaseAccount(targetAccountId);
return true;
}

private void checkThreshold(SendMoneyCommand command) {
if(command.getMoney().isGreaterThan(moneyTransferProperties.getMaximumTransferThreshold())){
throw new ThresholdExceededException(moneyTransferProperties.getMaximumTransferThreshold(), command.getMoney());
}
}

}
@@ -1,6 +1,7 @@
package io.reflectoring.buckpal.domain;

import java.time.LocalDateTime;
import java.util.Optional;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
Expand All @@ -19,36 +20,43 @@ public class Account {
/**
* The unique ID of the account.
*/
@Getter
private AccountId id;
@Getter private final AccountId id;

/**
* The baseline balance of the account. This was the balance of the account before the first
* activity in the activityWindow.
*/
private Money baselineBalance;
@Getter private final Money baselineBalance;

/**
* The window of latest activities on this account.
*/
@Getter
private ActivityWindow activityWindow;
@Getter private final ActivityWindow activityWindow;

/**
* Creates an {@link Account} entity without an ID. Use to create a new entity that is not yet
* persisted.
*/
public static Account withoutId(Money baselineBalance, ActivityWindow activityWindow) {
public static Account withoutId(
Money baselineBalance,
ActivityWindow activityWindow) {
return new Account(null, baselineBalance, activityWindow);
}

/**
* Creates an {@link Account} entity with an ID. Use to reconstitute a persisted entity.
*/
public static Account withId(AccountId accountId, Money baselineBalance, ActivityWindow activityWindow) {
public static Account withId(
AccountId accountId,
Money baselineBalance,
ActivityWindow activityWindow) {
return new Account(accountId, baselineBalance, activityWindow);
}

public Optional<AccountId> getId(){
return Optional.ofNullable(this.id);
}

/**
* Calculates the total balance of the account by adding the activity values to the baseline balance.
*/
Expand Down
Expand Up @@ -3,6 +3,7 @@
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

Expand Down Expand Up @@ -66,7 +67,7 @@ public ActivityWindow(@NonNull Activity... activities) {
}

public List<Activity> getActivities() {
return new ArrayList<>(this.activities);
return Collections.unmodifiableList(this.activities);
}

public void addActivity(Activity activity) {
Expand Down
Expand Up @@ -75,7 +75,7 @@ private ResponseEntity whenSendMoney(
HttpEntity<Void> request = new HttpEntity<>(null, headers);

return restTemplate.exchange(
"/accounts/sendMoney/{sourceAccountId}/{targetAccountId}/{amount}",
"/accounts/send/{sourceAccountId}/{targetAccountId}/{amount}",
HttpMethod.POST,
request,
Object.class,
Expand Down

0 comments on commit 8bde954

Please sign in to comment.