diff --git a/aws/aws-rds-hello-world/src/main/java/io/reflectoring/awshelloworld/HelloWorldController.java b/aws/aws-rds-hello-world/src/main/java/io/reflectoring/awshelloworld/HelloWorldController.java index 304dec2..ccaef3c 100644 --- a/aws/aws-rds-hello-world/src/main/java/io/reflectoring/awshelloworld/HelloWorldController.java +++ b/aws/aws-rds-hello-world/src/main/java/io/reflectoring/awshelloworld/HelloWorldController.java @@ -4,16 +4,16 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController -public class HelloWorldController { +class HelloWorldController { private final UserRepository userRepository; - public HelloWorldController(UserRepository userRepository) { + HelloWorldController(UserRepository userRepository) { this.userRepository = userRepository; } @GetMapping("/hello") - public String helloWorld(){ + String helloWorld(){ Iterable users = userRepository.findAll(); diff --git a/aws/cloudformation/rds-in-private-subnet/database.yml b/aws/cloudformation/rds-in-private-subnet/database.yml index f7784a8..c68f6fe 100644 --- a/aws/cloudformation/rds-in-private-subnet/database.yml +++ b/aws/cloudformation/rds-in-private-subnet/database.yml @@ -25,6 +25,7 @@ Resources: SecretStringTemplate: !Join ['', ['{"username": "', !Ref 'DBUsername' ,'"}']] GenerateStringKey: "password" PasswordLength: 32 + ExcludeCharacters: '"@/\' DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup @@ -75,6 +76,11 @@ Outputs: Value: !GetAtt 'PostgresInstance.Endpoint.Port' Export: Name: !Join [ ':', [ !Ref 'AWS::StackName', 'EndpointPort' ] ] + DBName: + Description: The name of the database that is created within the PostgreSQL instance. + Value: !Ref DBName + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'DBName' ] ] Secret: Description: Reference to the secret containing the password to the database. Value: !Ref 'Secret' diff --git a/aws/cloudformation/rds-in-private-subnet/rds-in-private-subnet.drawio b/aws/cloudformation/rds-in-private-subnet/rds-in-private-subnet.drawio index b896d1b..e2d0bd4 100644 --- a/aws/cloudformation/rds-in-private-subnet/rds-in-private-subnet.drawio +++ b/aws/cloudformation/rds-in-private-subnet/rds-in-private-subnet.drawio @@ -1 +1 @@ -7VpZb9s4EP41fqyhW/JjfKUBWqyx3t22TwYtMTIRWXRp+sqv36FEXaR8pHESGIhhIJohRQ5nvm84pNOxB8v9PUOrxXca4aRjGdG+Yw87lmXargt/hOaQa3zfyRUxI5HsVCmm5BlLpSG1GxLhdaMjpzThZNVUhjRNccgbOsQY3TW7PdKkOesKxVhTTEOU6NofJOILqTW9XtXwFZN4IacOLD9vWKKis1zJeoEiuqup7FHHHjBKef603A9wIpxX+CV/b3yktTSM4ZRf8sICh9b++cH/MXyeP3nO9+j3bP6lMG6Lko1c8X+TgTSYHwovrChJeeZJtw9feGlgdFxoGQipa7mKQpX9psLUJTFGU6HKflNhqsObyvymamBNoUmN4Q1lfqNmIHztPt3whKR4UGLOAGXMUEQgFgOaUAa6lKbgvf6CLxOQTHjcLQjH0xUKhVd3wBfQPdKUS9SbViFLx4t3ADUr8bzcx4JgXbRbO92Y0c0qm/IBcN/aOtuuQvE6Z/QJFyZ1LNtygsB0xEQkSRRTt5hxAtC/S0gsRuVUTIKklOBHLkYE+0kaf8ukoW1Im2tT3N31/X4A+gitFziS7tHhKhEsZsX7mkrC9x7TJebsAF2KVk+iVeaSQIq7ipieI3WLGiet4j0kk0FcDl3xBR4kZV5AH1tjz2QzT0go2LOZp5h/Mun2mbTG4YYRfphVnacZraS5l3EM9KPe2B551yNaOc+1iWa7TaKZls40M2hhmumZGULehGymr7FtNJiCYorZlgAUVK61pDgtVu6dNwi8ug/NowFSEaWEoxxKCeQ1AhIoAXFbAmK3BcQyup71RgFxtXh0LC8RS57DQywe7lYrSIeIEyBX0caKxm8URboW3IfSELOiBUwrh9NC3Jo/GnQoQvkNzXEyoWuS2WIP55RzujxLxhCCBrY0sk9LJrG7qFrpLIGFzebFOrQ8MHYD13aOJ7orAMZyFMD4QTcI9O2yp0PGfyu4BOfh8iCcnW2bHlqKMKTz9SrziIqSe8TxDh1uDCRErm8WS/PbseG9KTbKRFHDhu9+LDZ6R1L7P2j9dFk81b3RtsZifs2Pwsd+MDLq/BsSBgPlIU8pEx5Q4zI03AFsQC07yGP2eQdEnStw0HqVu+OR7IUd7RUPw2u6YSHO650+iG2VDw7X1wGbYypgayna/ZaNy3+rkt3Sa3YNYDiKceFZAQca0xQlo0pbDwtOoztx0SCCm9DwSaiSeSYXMc5ggxgv+kkuw5tjkpQJQytNHLfvCZhC2ZlGJbIgFuzwsy78EgJU2VIc7uuNw0NdmmBGwI8CWqeLxRwkp/woKQvrijE/n/aFT08Cpl7KGDL6DCewo26bdzFtkJDDTcTpqgJfr4k9KJuaI+SLlC/Vr06Uccr6Vw5kGwo6cydoA2UALZf4Csx6n5i9ALNnoeh+HBQt41pYVI4CtvnOWGwr424Ki3vCfxZzw3MNiSBVQBTCoSZcL3W6F8K193FwtY1eE64GnCPtP0OsU/wGUCDWMbpG7WNehF+IvSj3y27yIu34Cpx2wh2z8kx/eMgtuC6Z9Lr31JnoJo861ssPOeVPJdX1WvHji32l87FalfptRyC/13X10tR1Xl+a7pPNeIb/2n51Dr9+8/m/z/h+88XUwDBhZAsnxc/r5M/r5I+9TtaY1cK/o2Rzex98ndzKNut86v17KO4gHlIoPlJxv3xTCZhFax0z1si3s9/mTl4vvSranuM0o+07ZRDrudXS4x2cqFNeFetbP/O3FoJ/Vny2HNuP0+N9ak1TqTUtp7yrfnGtqWzs2Vi92kcZ98XF5uXHKRCrf+7Iu1f/ImOP/gc= \ No newline at end of file +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 \ No newline at end of file diff --git a/aws/cloudformation/rds-in-private-subnet/rds-in-private-subnet.svg b/aws/cloudformation/rds-in-private-subnet/rds-in-private-subnet.svg deleted file mode 100644 index d49a192..0000000 --- a/aws/cloudformation/rds-in-private-subnet/rds-in-private-subnet.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -
VPC
VPC
Public subnet
Public subnet
ECS Service
Application
Load
Balancer
Application...
Internet 
Gateway
Internet...
ECS Task
ECS Task
Internet
Internet
Private subnet
Private subnet
RDS Instance
RDS Instance
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/aws/cloudformation/rds-in-private-subnet/service.yml b/aws/cloudformation/rds-in-private-subnet/service.yml index 4393811..fc40462 100644 --- a/aws/cloudformation/rds-in-private-subnet/service.yml +++ b/aws/cloudformation/rds-in-private-subnet/service.yml @@ -9,12 +9,6 @@ Parameters: DatabaseStackName: Type: String Description: The name of the database stack with the database this service should connect to. - DBName: - Type: String - Description: The database name. - DBUsername: - Type: String - Description: The database username. ServiceName: Type: String Description: A human-readable name for the service. @@ -117,9 +111,13 @@ Resources: - ':' - Fn::ImportValue: !Join [':', [!Ref 'DatabaseStackName', 'EndpointPort']] - '/' - - !Ref 'DBName' + - Fn::ImportValue: !Join [':', [!Ref 'DatabaseStackName', 'DBName']] - Name: SPRING_DATASOURCE_USERNAME - Value: !Ref 'DBUsername' + Value: !Join + - '' + - - '{{resolve:secretsmanager:' + - Fn::ImportValue: !Join [':', [!Ref 'DatabaseStackName', 'Secret']] + - ':SecretString:username}}' - Name: SPRING_DATASOURCE_PASSWORD Value: !Join - '' diff --git a/spring-boot/configuration/build.gradle b/spring-boot/configuration/build.gradle index 54562d1..1d7d91a 100644 --- a/spring-boot/configuration/build.gradle +++ b/spring-boot/configuration/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'org.springframework.boot' version '2.1.3.RELEASE' + id 'org.springframework.boot' version '2.3.0.RELEASE' id 'java' } @@ -7,7 +7,7 @@ apply plugin: 'io.spring.dependency-management' group = 'io.reflectoring' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '11' +sourceCompatibility = '13' repositories { mavenCentral() @@ -23,6 +23,7 @@ dependencies { testImplementation('org.junit.jupiter:junit-jupiter:5.4.0') testImplementation('org.springframework.boot:spring-boot-starter-test'){ exclude group: 'junit', module: 'junit' + exclude group: 'org.junit.vintage' } } diff --git a/spring-boot/configuration/gradle/wrapper/gradle-wrapper.properties b/spring-boot/configuration/gradle/wrapper/gradle-wrapper.properties index 44e7c4d..21e622d 100644 --- a/spring-boot/configuration/gradle/wrapper/gradle-wrapper.properties +++ b/spring-boot/configuration/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/spring-boot/configuration/gradlew b/spring-boot/configuration/gradlew old mode 100644 new mode 100755 diff --git a/spring-boot/configuration/src/main/java/io/reflectoring/Application.java b/spring-boot/configuration/src/main/java/io/reflectoring/Application.java new file mode 100644 index 0000000..0c90412 --- /dev/null +++ b/spring-boot/configuration/src/main/java/io/reflectoring/Application.java @@ -0,0 +1,14 @@ +package io.reflectoring; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/spring-boot/configuration/src/main/resources/application.properties b/spring-boot/configuration/src/main/resources/application.properties index bc88f39..0dc5de8 100644 --- a/spring-boot/configuration/src/main/resources/application.properties +++ b/spring-boot/configuration/src/main/resources/application.properties @@ -1,5 +1,4 @@ myapp.mail.enabled=true -myapp myapp.mail.pauseBetweenMails=5s myapp.mail.maxAttachmentSize=1MB myapp.mail.smtpServers[0]=server1 diff --git a/spring-boot/configuration/src/main/java/io/reflectoring/configuration/ConfigurationApplication.java b/spring-boot/configuration/src/test/java/io/reflectoring/configuration/ConfigurationApplication.java similarity index 100% rename from spring-boot/configuration/src/main/java/io/reflectoring/configuration/ConfigurationApplication.java rename to spring-boot/configuration/src/test/java/io/reflectoring/configuration/ConfigurationApplication.java 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 index 731d8f6..f9b6c65 100644 --- 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 @@ -1,37 +1,36 @@ package io.reflectoring.configuration.mail; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.util.unit.DataSize; + 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.*; +import static org.assertj.core.api.Assertions.assertThat; @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" + "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; + @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); - } + @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/validation/PropertiesInvalidInputTest.java b/spring-boot/configuration/src/test/java/io/reflectoring/validation/PropertiesInvalidInputTest.java index e725d5d..a3b1be1 100644 --- a/spring-boot/configuration/src/test/java/io/reflectoring/validation/PropertiesInvalidInputTest.java +++ b/spring-boot/configuration/src/test/java/io/reflectoring/validation/PropertiesInvalidInputTest.java @@ -70,8 +70,7 @@ class PropertiesInvalidInputTest { assertThatThrownBy(application::run) .isInstanceOf(ConfigurationPropertiesBindException.class) .hasRootCauseInstanceOf(BindValidationException.class) - .hasStackTraceContaining("Field error in object 'app.properties' on field 'report.intervalInDays'") - .hasStackTraceContaining("[must be less than or equal to 30]"); + .hasStackTraceContaining("rejected value [31]"); } @@ -83,8 +82,7 @@ class PropertiesInvalidInputTest { assertThatThrownBy(application::run) .isInstanceOf(ConfigurationPropertiesBindException.class) .hasRootCauseInstanceOf(BindValidationException.class) - .hasStackTraceContaining("Field error in object 'app.properties' on field 'report.intervalInDays'") - .hasStackTraceContaining("[must be greater than or equal to 7]"); + .hasStackTraceContaining("rejected value [6]"); } @@ -96,8 +94,7 @@ class PropertiesInvalidInputTest { assertThatThrownBy(application::run) .isInstanceOf(ConfigurationPropertiesBindException.class) .hasRootCauseInstanceOf(BindValidationException.class) - .hasStackTraceContaining("Field error in object 'app.properties' on field 'report.emailAddress'") - .hasStackTraceContaining("[must be a well-formed email address]"); + .hasStackTraceContaining("rejected value [manager.analysisapp.com]"); } diff --git a/spring-boot/configuration/src/main/java/io/reflectoring/validation/ValidationApplication.java b/spring-boot/configuration/src/test/java/io/reflectoring/validation/ValidationApplication.java similarity index 100% rename from spring-boot/configuration/src/main/java/io/reflectoring/validation/ValidationApplication.java rename to spring-boot/configuration/src/test/java/io/reflectoring/validation/ValidationApplication.java