added example configuration parameter to show how to "cleanly" inject configuration parameters into the application
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
package io.reflectoring.buckpal.application.service;
|
||||||
|
|
||||||
|
import io.reflectoring.buckpal.domain.Money;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration properties for money transfer use cases.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class MoneyTransferProperties {
|
||||||
|
|
||||||
|
private Money maximumTransferThreshold = Money.of(1_000_000L);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,9 +1,5 @@
|
|||||||
package io.reflectoring.buckpal.application.service;
|
package io.reflectoring.buckpal.application.service;
|
||||||
|
|
||||||
import javax.transaction.Transactional;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
import io.reflectoring.buckpal.application.port.in.SendMoneyUseCase;
|
import io.reflectoring.buckpal.application.port.in.SendMoneyUseCase;
|
||||||
import io.reflectoring.buckpal.application.port.out.AccountLock;
|
import io.reflectoring.buckpal.application.port.out.AccountLock;
|
||||||
import io.reflectoring.buckpal.application.port.out.LoadAccountPort;
|
import io.reflectoring.buckpal.application.port.out.LoadAccountPort;
|
||||||
@@ -12,6 +8,9 @@ import io.reflectoring.buckpal.domain.Account;
|
|||||||
import io.reflectoring.buckpal.testdata.UseCase;
|
import io.reflectoring.buckpal.testdata.UseCase;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@UseCase
|
@UseCase
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -20,9 +19,15 @@ public class SendMoneyService implements SendMoneyUseCase {
|
|||||||
private final LoadAccountPort loadAccountPort;
|
private final LoadAccountPort loadAccountPort;
|
||||||
private final AccountLock accountLock;
|
private final AccountLock accountLock;
|
||||||
private final UpdateAccountStatePort updateAccountStatePort;
|
private final UpdateAccountStatePort updateAccountStatePort;
|
||||||
|
private final MoneyTransferProperties moneyTransferProperties;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendMoney(SendMoneyCommand command) {
|
public boolean sendMoney(SendMoneyCommand command) {
|
||||||
|
|
||||||
|
if(command.getMoney().isGreaterThan(moneyTransferProperties.getMaximumTransferThreshold())){
|
||||||
|
throw new ThresholdExceededException(moneyTransferProperties.getMaximumTransferThreshold(), command.getMoney());
|
||||||
|
}
|
||||||
|
|
||||||
LocalDateTime baselineDate = LocalDateTime.now().minusDays(10);
|
LocalDateTime baselineDate = LocalDateTime.now().minusDays(10);
|
||||||
|
|
||||||
Account sourceAccount = loadAccountPort.loadAccount(
|
Account sourceAccount = loadAccountPort.loadAccount(
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package io.reflectoring.buckpal.application.service;
|
||||||
|
|
||||||
|
import io.reflectoring.buckpal.domain.Money;
|
||||||
|
|
||||||
|
public class ThresholdExceededException extends RuntimeException {
|
||||||
|
|
||||||
|
public ThresholdExceededException(Money threshold, Money actual) {
|
||||||
|
super(String.format("Maximum threshold for transferring money exceeded: tried to transfer %s but threshold is %s!", actual, threshold));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -29,6 +29,10 @@ public class Money {
|
|||||||
return this.amount.compareTo(money.amount) >= 0;
|
return this.amount.compareTo(money.amount) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isGreaterThan(Money money){
|
||||||
|
return this.amount.compareTo(money.amount) >= 1;
|
||||||
|
}
|
||||||
|
|
||||||
public static Money of(long value) {
|
public static Money of(long value) {
|
||||||
return new Money(BigInteger.valueOf(value));
|
return new Money(BigInteger.valueOf(value));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class SendMoneyServiceTest {
|
|||||||
Mockito.mock(UpdateAccountStatePort.class);
|
Mockito.mock(UpdateAccountStatePort.class);
|
||||||
|
|
||||||
private final SendMoneyService sendMoneyService =
|
private final SendMoneyService sendMoneyService =
|
||||||
new SendMoneyService(loadAccountPort, accountLock, updateAccountStatePort);
|
new SendMoneyService(loadAccountPort, accountLock, updateAccountStatePort, moneyTransferProperties());
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void givenWithdrawalFails_thenOnlySourceAccountIsLockedAndReleased() {
|
void givenWithdrawalFails_thenOnlySourceAccountIsLockedAndReleased() {
|
||||||
@@ -138,4 +138,8 @@ class SendMoneyServiceTest {
|
|||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
private MoneyTransferProperties moneyTransferProperties(){
|
||||||
|
return new MoneyTransferProperties(Money.of(Long.MAX_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ plugins {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
|
compileOnly 'org.projectlombok:lombok'
|
||||||
|
annotationProcessor 'org.projectlombok:lombok'
|
||||||
|
|
||||||
implementation project(':common')
|
implementation project(':common')
|
||||||
implementation project(':buckpal-application')
|
implementation project(':buckpal-application')
|
||||||
implementation project(':adapters:buckpal-persistence')
|
implementation project(':adapters:buckpal-persistence')
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package io.reflectoring.buckpal;
|
||||||
|
|
||||||
|
import io.reflectoring.buckpal.application.service.MoneyTransferProperties;
|
||||||
|
import io.reflectoring.buckpal.domain.Money;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableConfigurationProperties(BuckPalConfigurationProperties.class)
|
||||||
|
public class BuckPalConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a use-case-specific {@link MoneyTransferProperties} object to the application context. The properties
|
||||||
|
* are read from the Spring-Boot-specific {@link BuckPalConfigurationProperties} object.
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public MoneyTransferProperties moneyTransferProperties(BuckPalConfigurationProperties buckPalConfigurationProperties){
|
||||||
|
return new MoneyTransferProperties(Money.of(buckPalConfigurationProperties.getTransferThreshold()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package io.reflectoring.buckpal;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ConfigurationProperties(prefix = "buckpal")
|
||||||
|
public class BuckPalConfigurationProperties {
|
||||||
|
|
||||||
|
private long transferThreshold = Long.MAX_VALUE;
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user