From e82850920f9087af754394f15f3d1e93d903e53e Mon Sep 17 00:00:00 2001 From: Tom Hombergs Date: Tue, 17 Sep 2019 21:08:52 +0200 Subject: [PATCH] added example configuration parameter to show how to "cleanly" inject configuration parameters into the application --- .../service/MoneyTransferProperties.java | 18 +++++++++++++++ .../application/service/SendMoneyService.java | 13 +++++++---- .../service/ThresholdExceededException.java | 11 ++++++++++ .../io/reflectoring/buckpal/domain/Money.java | 4 ++++ .../service/SendMoneyServiceTest.java | 8 +++++-- buckpal-configuration/build.gradle | 3 +++ .../buckpal/BuckPalConfiguration.java | 22 +++++++++++++++++++ .../BuckPalConfigurationProperties.java | 12 ++++++++++ 8 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 buckpal-application/src/main/java/io/reflectoring/buckpal/application/service/MoneyTransferProperties.java create mode 100644 buckpal-application/src/main/java/io/reflectoring/buckpal/application/service/ThresholdExceededException.java create mode 100644 buckpal-configuration/src/main/java/io/reflectoring/buckpal/BuckPalConfiguration.java create mode 100644 buckpal-configuration/src/main/java/io/reflectoring/buckpal/BuckPalConfigurationProperties.java diff --git a/buckpal-application/src/main/java/io/reflectoring/buckpal/application/service/MoneyTransferProperties.java b/buckpal-application/src/main/java/io/reflectoring/buckpal/application/service/MoneyTransferProperties.java new file mode 100644 index 0000000..23c7a93 --- /dev/null +++ b/buckpal-application/src/main/java/io/reflectoring/buckpal/application/service/MoneyTransferProperties.java @@ -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); + +} diff --git a/buckpal-application/src/main/java/io/reflectoring/buckpal/application/service/SendMoneyService.java b/buckpal-application/src/main/java/io/reflectoring/buckpal/application/service/SendMoneyService.java index e55787c..871a3e2 100644 --- a/buckpal-application/src/main/java/io/reflectoring/buckpal/application/service/SendMoneyService.java +++ b/buckpal-application/src/main/java/io/reflectoring/buckpal/application/service/SendMoneyService.java @@ -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( diff --git a/buckpal-application/src/main/java/io/reflectoring/buckpal/application/service/ThresholdExceededException.java b/buckpal-application/src/main/java/io/reflectoring/buckpal/application/service/ThresholdExceededException.java new file mode 100644 index 0000000..5e31681 --- /dev/null +++ b/buckpal-application/src/main/java/io/reflectoring/buckpal/application/service/ThresholdExceededException.java @@ -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)); + } + +} diff --git a/buckpal-application/src/main/java/io/reflectoring/buckpal/domain/Money.java b/buckpal-application/src/main/java/io/reflectoring/buckpal/domain/Money.java index 10a2a76..9a33749 100644 --- a/buckpal-application/src/main/java/io/reflectoring/buckpal/domain/Money.java +++ b/buckpal-application/src/main/java/io/reflectoring/buckpal/domain/Money.java @@ -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)); } diff --git a/buckpal-application/src/test/java/io/reflectoring/buckpal/application/service/SendMoneyServiceTest.java b/buckpal-application/src/test/java/io/reflectoring/buckpal/application/service/SendMoneyServiceTest.java index c094cae..ea29de5 100644 --- a/buckpal-application/src/test/java/io/reflectoring/buckpal/application/service/SendMoneyServiceTest.java +++ b/buckpal-application/src/test/java/io/reflectoring/buckpal/application/service/SendMoneyServiceTest.java @@ -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; } -} \ No newline at end of file + private MoneyTransferProperties moneyTransferProperties(){ + return new MoneyTransferProperties(Money.of(Long.MAX_VALUE)); + } + +} diff --git a/buckpal-configuration/build.gradle b/buckpal-configuration/build.gradle index c66d5c1..c8599bd 100644 --- a/buckpal-configuration/build.gradle +++ b/buckpal-configuration/build.gradle @@ -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') diff --git a/buckpal-configuration/src/main/java/io/reflectoring/buckpal/BuckPalConfiguration.java b/buckpal-configuration/src/main/java/io/reflectoring/buckpal/BuckPalConfiguration.java new file mode 100644 index 0000000..eb1c6c3 --- /dev/null +++ b/buckpal-configuration/src/main/java/io/reflectoring/buckpal/BuckPalConfiguration.java @@ -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())); + } + +} diff --git a/buckpal-configuration/src/main/java/io/reflectoring/buckpal/BuckPalConfigurationProperties.java b/buckpal-configuration/src/main/java/io/reflectoring/buckpal/BuckPalConfigurationProperties.java new file mode 100644 index 0000000..6da5b42 --- /dev/null +++ b/buckpal-configuration/src/main/java/io/reflectoring/buckpal/BuckPalConfigurationProperties.java @@ -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; + +}