diff --git a/spring-boot/configuration/.gitignore b/spring-boot/configuration/.gitignore new file mode 100644 index 0000000..d6819a4 --- /dev/null +++ b/spring-boot/configuration/.gitignore @@ -0,0 +1,26 @@ +.gradle +/build/ +!gradle/wrapper/gradle-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ diff --git a/spring-boot/configuration/build.gradle b/spring-boot/configuration/build.gradle new file mode 100644 index 0000000..5ada682 --- /dev/null +++ b/spring-boot/configuration/build.gradle @@ -0,0 +1,31 @@ +plugins { + id 'org.springframework.boot' version '2.1.3.RELEASE' + id 'java' +} + +apply plugin: 'io.spring.dependency-management' + +group = 'io.reflectoring' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '11' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter' + implementation 'org.springframework.boot:spring-boot-starter-mail' + implementation 'org.springframework.boot:spring-boot-starter-validation' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' + testImplementation('org.junit.jupiter:junit-jupiter:5.4.0') + testImplementation('org.springframework.boot:spring-boot-starter-test'){ + exclude group: 'org.junit', module: 'junit' + } +} + +test { + useJUnitPlatform() +} diff --git a/spring-boot/configuration/gradlew b/spring-boot/configuration/gradlew new file mode 100644 index 0000000..af6708f --- /dev/null +++ b/spring-boot/configuration/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/spring-boot/configuration/gradlew.bat b/spring-boot/configuration/gradlew.bat new file mode 100644 index 0000000..6d57edc --- /dev/null +++ b/spring-boot/configuration/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/spring-boot/configuration/settings.gradle b/spring-boot/configuration/settings.gradle new file mode 100644 index 0000000..df58ca7 --- /dev/null +++ b/spring-boot/configuration/settings.gradle @@ -0,0 +1,6 @@ +pluginManagement { + repositories { + gradlePluginPortal() + } +} +rootProject.name = 'configuration' diff --git a/spring-boot/configuration/src/main/java/io/reflectoring/configuration/ConfigurationApplication.java b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/ConfigurationApplication.java new file mode 100644 index 0000000..895c720 --- /dev/null +++ b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/ConfigurationApplication.java @@ -0,0 +1,13 @@ +package io.reflectoring.configuration; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ConfigurationApplication { + + public static void main(String[] args) { + SpringApplication.run(ConfigurationApplication.class, args); + } + +} diff --git a/spring-boot/configuration/src/main/java/io/reflectoring/configuration/mail/MailModuleConfiguration.java b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/mail/MailModuleConfiguration.java new file mode 100644 index 0000000..2918bbc --- /dev/null +++ b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/mail/MailModuleConfiguration.java @@ -0,0 +1,18 @@ +package io.reflectoring.configuration.mail; + +import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties(MailModuleProperties.class) +class MailModuleConfiguration { + + @Bean + @ConfigurationPropertiesBinding + public WeightConverter weightConverter() { + return new WeightConverter(); + } + +} diff --git a/spring-boot/configuration/src/main/java/io/reflectoring/configuration/mail/MailModuleProperties.java b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/mail/MailModuleProperties.java new file mode 100644 index 0000000..ce78c31 --- /dev/null +++ b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/mail/MailModuleProperties.java @@ -0,0 +1,84 @@ +package io.reflectoring.configuration.mail; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +import java.time.Duration; +import java.util.List; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; +import org.springframework.util.unit.DataSize; +import org.springframework.validation.annotation.Validated; + +@ConfigurationProperties(prefix = "myapp.mail", ignoreInvalidFields = true, ignoreUnknownFields = false) +@Validated +class MailModuleProperties { + + @NotNull + private Boolean enabled = Boolean.TRUE; + + @NotEmpty + private String defaultSubject; + + @NotNull + private Duration pauseBetweenMails; + + @NotNull + private DataSize maxAttachmentSize; + + @NotNull + private Weight maxAttachmentWeight; + + @NotEmpty + private List smtpServers; + + @DeprecatedConfigurationProperty(reason = "not needed anymore", replacement = "none") + public String getDefaultSubject() { + return defaultSubject; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public void setDefaultSubject(String defaultSubject) { + this.defaultSubject = defaultSubject; + } + + public Duration getPauseBetweenMails() { + return pauseBetweenMails; + } + + public void setPauseBetweenMails(Duration pauseBetweenMails) { + this.pauseBetweenMails = pauseBetweenMails; + } + + public DataSize getMaxAttachmentSize() { + return maxAttachmentSize; + } + + public void setMaxAttachmentSize(DataSize maxAttachmentSize) { + this.maxAttachmentSize = maxAttachmentSize; + } + + public List getSmtpServers() { + return smtpServers; + } + + public void setSmtpServers(List smtpServers) { + this.smtpServers = smtpServers; + } + + public Weight getMaxAttachmentWeight() { + return maxAttachmentWeight; + } + + public void setMaxAttachmentWeight(Weight maxAttachmentWeight) { + this.maxAttachmentWeight = maxAttachmentWeight; + } +} diff --git a/spring-boot/configuration/src/main/java/io/reflectoring/configuration/mail/Weight.java b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/mail/Weight.java new file mode 100644 index 0000000..21dc2e5 --- /dev/null +++ b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/mail/Weight.java @@ -0,0 +1,39 @@ +package io.reflectoring.configuration.mail; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Weight { + + private static final Pattern PATTERN = Pattern.compile("^([0-9]+)(g|kg|t)$"); + + private long grams; + + private Weight(long grams){ + this.grams = grams; + } + + public static Weight fromString(String string) { + Matcher matcher = PATTERN.matcher(string); + if (matcher.matches()) { + Long amount = Long.valueOf(matcher.group(1)); + String unit = matcher.group(2); + + switch (unit) { + case "g": + return new Weight(amount); + case "kg": + return new Weight(amount * 1_000); + case "t": + return new Weight(amount * 1_000 * 1_000); + default: + throw new IllegalArgumentException(String.format("invalid weight unit %s", unit)); + } + } + throw new IllegalArgumentException(String.format("invalid weight string %s", string)); + } + + public long getGrams() { + return grams; + } +} diff --git a/spring-boot/configuration/src/main/java/io/reflectoring/configuration/mail/WeightConverter.java b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/mail/WeightConverter.java new file mode 100644 index 0000000..9dd2d81 --- /dev/null +++ b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/mail/WeightConverter.java @@ -0,0 +1,12 @@ +package io.reflectoring.configuration.mail; + +import org.springframework.core.convert.converter.Converter; + +class WeightConverter implements Converter { + + @Override + public Weight convert(String source) { + return Weight.fromString(source); + } + +} diff --git a/spring-boot/configuration/src/main/java/io/reflectoring/configuration/unknownandinvalidfield/UnkownAndInvalidFieldProperties.java b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/unknownandinvalidfield/UnkownAndInvalidFieldProperties.java new file mode 100644 index 0000000..27807c1 --- /dev/null +++ b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/unknownandinvalidfield/UnkownAndInvalidFieldProperties.java @@ -0,0 +1,22 @@ +package io.reflectoring.configuration.unknownandinvalidfield; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties( + prefix = "myapp.unknown-and-invalid-field-module", + ignoreUnknownFields = false, + ignoreInvalidFields = true) +class UnkownAndInvalidFieldProperties { + + private Boolean enabled; + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } +} diff --git a/spring-boot/configuration/src/main/java/io/reflectoring/configuration/unknownfield/UnkownFieldProperties.java b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/unknownfield/UnkownFieldProperties.java new file mode 100644 index 0000000..84b5f52 --- /dev/null +++ b/spring-boot/configuration/src/main/java/io/reflectoring/configuration/unknownfield/UnkownFieldProperties.java @@ -0,0 +1,29 @@ +package io.reflectoring.configuration.unknownfield; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +import java.time.Duration; +import java.util.List; + +import io.reflectoring.configuration.mail.Weight; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; +import org.springframework.stereotype.Component; +import org.springframework.util.unit.DataSize; +import org.springframework.validation.annotation.Validated; + +@Component +@ConfigurationProperties(prefix = "myapp.unknownfield", ignoreUnknownFields = false) +class UnkownFieldProperties { + + private Boolean enabled = Boolean.TRUE; + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } +} diff --git a/spring-boot/configuration/src/main/resources/application.properties b/spring-boot/configuration/src/main/resources/application.properties new file mode 100644 index 0000000..a0d841e --- /dev/null +++ b/spring-boot/configuration/src/main/resources/application.properties @@ -0,0 +1,8 @@ +myapp.mail.enabled=true +myapp.mail.defaultSubject=hello +myapp.mail.pauseBetweenMails=5s +myapp.mail.maxAttachmentSize=1MB +myapp.mail.smtpServers[0]=server1 +myapp.mail.smtpServers[1]=server2 +myapp.mail.maxAttachmentWeight=5kg +myapp.mail.foo=foo \ No newline at end of file diff --git a/spring-boot/configuration/src/test/java/io/reflectoring/configuration/ConfigurationApplicationTests.java b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/ConfigurationApplicationTests.java new file mode 100644 index 0000000..ffd3fba --- /dev/null +++ b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/ConfigurationApplicationTests.java @@ -0,0 +1,16 @@ +package io.reflectoring.configuration; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@SpringBootTest +class ConfigurationApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/spring-boot/configuration/src/test/java/io/reflectoring/configuration/mail/MailModuleTestWithAllProperties.java b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/mail/MailModuleTestWithAllProperties.java new file mode 100644 index 0000000..b886086 --- /dev/null +++ b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/mail/MailModuleTestWithAllProperties.java @@ -0,0 +1,38 @@ +package io.reflectoring.configuration.mail; + +import java.time.Duration; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.util.unit.DataSize; +import static org.assertj.core.api.Assertions.*; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(properties = { + "myapp.mail.enabled=asd", + "myapp.mail.defaultSubject=hello", + "myapp.mail.pauseBetweenMails=5s", + "myapp.mail.maxAttachmentSize=1MB", + "myapp.mail.smtpServers[0]=server1", + "myapp.mail.smtpServers[1]=server2", + "myapp.mail.maxAttachmentWeight=5kg" +}) +class MailModuleTestWithAllProperties { + + @Autowired(required = false) + private MailModuleProperties mailModuleProperties; + + @Test + void propertiesAreLoaded() { + assertThat(mailModuleProperties).isNotNull(); + assertThat(mailModuleProperties.getDefaultSubject()).isEqualTo("hello"); + assertThat(mailModuleProperties.getEnabled()).isTrue(); + assertThat(mailModuleProperties.getPauseBetweenMails()).isEqualByComparingTo(Duration.ofSeconds(5)); + assertThat(mailModuleProperties.getMaxAttachmentSize()).isEqualByComparingTo(DataSize.ofMegabytes(1)); + assertThat(mailModuleProperties.getSmtpServers()).hasSize(2); + assertThat(mailModuleProperties.getMaxAttachmentWeight().getGrams()).isEqualTo(5000L); + } +} \ No newline at end of file diff --git a/spring-boot/configuration/src/test/java/io/reflectoring/configuration/mail/MailModuleTestWithInvalidProperties.java b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/mail/MailModuleTestWithInvalidProperties.java new file mode 100644 index 0000000..c5a2148 --- /dev/null +++ b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/mail/MailModuleTestWithInvalidProperties.java @@ -0,0 +1,25 @@ +package io.reflectoring.configuration.mail; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import static org.assertj.core.api.Assertions.*; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(properties = { + "myapp.mail.defaultSubject=" +}) +@Disabled("this test will fail due to invalid properties") +class MailModuleTestWithInvalidProperties { + + @Autowired(required = false) + private MailModuleProperties mailModuleProperties; + + @Test + void propertiesAreLoaded() { + assertThat(mailModuleProperties).isNotNull(); + } +} \ No newline at end of file diff --git a/spring-boot/configuration/src/test/java/io/reflectoring/configuration/mail/MailModuleTestWithUnknownField.java b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/mail/MailModuleTestWithUnknownField.java new file mode 100644 index 0000000..b70b374 --- /dev/null +++ b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/mail/MailModuleTestWithUnknownField.java @@ -0,0 +1,22 @@ +package io.reflectoring.configuration.mail; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import static org.assertj.core.api.Assertions.*; + +@ExtendWith(SpringExtension.class) +@SpringBootTest +class MailModuleTestWithUnknownField { + + @Autowired(required = false) + private MailModuleProperties mailModuleProperties; + + @Test + void propertiesAreLoaded() { + assertThat(mailModuleProperties).isNotNull(); + } +} \ No newline at end of file diff --git a/spring-boot/configuration/src/test/java/io/reflectoring/configuration/unknownandinvalidfield/UnknownAndInvalidFieldModule.java b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/unknownandinvalidfield/UnknownAndInvalidFieldModule.java new file mode 100644 index 0000000..1722407 --- /dev/null +++ b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/unknownandinvalidfield/UnknownAndInvalidFieldModule.java @@ -0,0 +1,9 @@ +package io.reflectoring.configuration.unknownandinvalidfield; + +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; + +@SpringBootConfiguration +@EnableConfigurationProperties(UnkownAndInvalidFieldProperties.class) +class UnknownAndInvalidFieldModule { +} diff --git a/spring-boot/configuration/src/test/java/io/reflectoring/configuration/unknownandinvalidfield/UnkownFieldPropertiesTest.java b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/unknownandinvalidfield/UnkownFieldPropertiesTest.java new file mode 100644 index 0000000..bc100a4 --- /dev/null +++ b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/unknownandinvalidfield/UnkownFieldPropertiesTest.java @@ -0,0 +1,28 @@ +package io.reflectoring.configuration.unknownandinvalidfield; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import static org.assertj.core.api.Assertions.*; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(properties = { + "myapp.unknown-and-invalid-field-module.unknown-property=foo" +}) +class UnkownFieldPropertiesTest { + + @Autowired(required = false) + private UnkownAndInvalidFieldProperties properties; + + @Test + @Disabled("disabled due to unexpected behavior") + void loadsApplicationContext() { + // This test passes. + // However, I would expect this test to fail application context startup due to the unknown property. + // If we set ignoreInvalidFields to true, it works as expected. + assertThat(properties).isNotNull(); + } +} \ No newline at end of file diff --git a/spring-boot/configuration/src/test/java/io/reflectoring/configuration/unknownfield/UnknownFieldModule.java b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/unknownfield/UnknownFieldModule.java new file mode 100644 index 0000000..e3c54b0 --- /dev/null +++ b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/unknownfield/UnknownFieldModule.java @@ -0,0 +1,10 @@ +package io.reflectoring.configuration.unknownfield; + +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@SpringBootConfiguration +@EnableConfigurationProperties(UnkownFieldProperties.class) +class UnknownFieldModule { +} diff --git a/spring-boot/configuration/src/test/java/io/reflectoring/configuration/unknownfield/UnkownFieldPropertiesTest.java b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/unknownfield/UnkownFieldPropertiesTest.java new file mode 100644 index 0000000..d4e3929 --- /dev/null +++ b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/unknownfield/UnkownFieldPropertiesTest.java @@ -0,0 +1,25 @@ +package io.reflectoring.configuration.unknownfield; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import static org.assertj.core.api.Assertions.*; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(properties = { + "myapp.unknownfield.unknown-property=foo" +}) +@Disabled("this test is expected to fail due an unknown property") +class UnkownFieldPropertiesTest { + + @Autowired(required = false) + private UnkownFieldProperties properties; + + @Test + void propertiesAreLoaded() { + assertThat(properties).isNotNull(); + } +} \ No newline at end of file