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;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import io.reflectoring.buckpal.application.port.in.SendMoneyUseCase;
|
||||
import io.reflectoring.buckpal.application.port.out.AccountLock;
|
||||
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 lombok.RequiredArgsConstructor;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@UseCase
|
||||
@Transactional
|
||||
@@ -20,9 +19,15 @@ public class SendMoneyService implements SendMoneyUseCase {
|
||||
private final LoadAccountPort loadAccountPort;
|
||||
private final AccountLock accountLock;
|
||||
private final UpdateAccountStatePort updateAccountStatePort;
|
||||
private final MoneyTransferProperties moneyTransferProperties;
|
||||
|
||||
@Override
|
||||
public boolean sendMoney(SendMoneyCommand command) {
|
||||
|
||||
if(command.getMoney().isGreaterThan(moneyTransferProperties.getMaximumTransferThreshold())){
|
||||
throw new ThresholdExceededException(moneyTransferProperties.getMaximumTransferThreshold(), command.getMoney());
|
||||
}
|
||||
|
||||
LocalDateTime baselineDate = LocalDateTime.now().minusDays(10);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public boolean isGreaterThan(Money money){
|
||||
return this.amount.compareTo(money.amount) >= 1;
|
||||
}
|
||||
|
||||
public static Money of(long value) {
|
||||
return new Money(BigInteger.valueOf(value));
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class SendMoneyServiceTest {
|
||||
Mockito.mock(UpdateAccountStatePort.class);
|
||||
|
||||
private final SendMoneyService sendMoneyService =
|
||||
new SendMoneyService(loadAccountPort, accountLock, updateAccountStatePort);
|
||||
new SendMoneyService(loadAccountPort, accountLock, updateAccountStatePort, moneyTransferProperties());
|
||||
|
||||
@Test
|
||||
void givenWithdrawalFails_thenOnlySourceAccountIsLockedAndReleased() {
|
||||
@@ -138,4 +138,8 @@ class SendMoneyServiceTest {
|
||||
return account;
|
||||
}
|
||||
|
||||
private MoneyTransferProperties moneyTransferProperties(){
|
||||
return new MoneyTransferProperties(Money.of(Long.MAX_VALUE));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,9 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
|
||||
compileOnly 'org.projectlombok:lombok'
|
||||
annotationProcessor 'org.projectlombok:lombok'
|
||||
|
||||
implementation project(':common')
|
||||
implementation project(':buckpal-application')
|
||||
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