diff --git a/bom/pom.xml b/bom/pom.xml index 75b65cd..1185832 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -19,6 +19,11 @@ spring-boot-conditions ${project.version} + + ${project.groupId} + spring-boot-properties + ${project.version} + diff --git a/pom.xml b/pom.xml index 2cf6c90..d4703fb 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,7 @@ spring-boot-conditions + spring-boot-properties bom @@ -77,6 +78,13 @@ org.jetbrains.kotlin kotlin-maven-plugin + + + spring + no-arg + all-open + + org.apache.maven.plugins diff --git a/spring-boot-conditions/pom.xml b/spring-boot-conditions/pom.xml index cd62b0f..d63f414 100644 --- a/spring-boot-conditions/pom.xml +++ b/spring-boot-conditions/pom.xml @@ -28,5 +28,16 @@ slf4j-api provided + + + org.springframework.boot + spring-boot-test + test + + + org.slf4j + slf4j-simple + test + diff --git a/spring-boot-conditions/src/test/java/.gitkeep b/spring-boot-conditions/src/test/java/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/spring-boot-conditions/src/test/kotlin/.gitkeep b/spring-boot-conditions/src/test/kotlin/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/spring-boot-conditions/src/test/kotlin/ConditionalOnMissingQualifiedBeanTest.kt b/spring-boot-conditions/src/test/kotlin/ConditionalOnMissingQualifiedBeanTest.kt new file mode 100644 index 0000000..49a8eee --- /dev/null +++ b/spring-boot-conditions/src/test/kotlin/ConditionalOnMissingQualifiedBeanTest.kt @@ -0,0 +1,39 @@ +package io.toolisticon.spring.condition + +import com.sun.tools.javac.util.AbstractDiagnosticFormatter +import io.toolisticon.spring.condition.fixture.MyComponent +import io.toolisticon.spring.condition.fixture.MyTestConfiguration +import io.toolisticon.spring.condition.fixture.SimpleConfiguration +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.springframework.boot.context.annotation.UserConfigurations +import org.springframework.boot.test.context.runner.ApplicationContextRunner + +class ConditionalOnMissingQualifiedBeanTest { + + private val contextRunner = ApplicationContextRunner() + + @Test + fun `should load qualified default bean`() { + contextRunner + .withConfiguration(UserConfigurations.of(MyTestConfiguration::class.java)) + .run { + assertThat(it.getBean(MyComponent::class.java)).isNotNull + val component: MyComponent = it.getBean(MyComponent::class.java) + assertThat(component.qualifier).isEqualTo("qualifier1") + } + } + + @Test + fun `should load user qualified bean`() { + contextRunner + .withConfiguration(UserConfigurations.of(SimpleConfiguration::class.java)) + .withConfiguration(UserConfigurations.of(MyTestConfiguration::class.java)) + .run { + assertThat(it.getBean(MyComponent::class.java)).isNotNull + val component: MyComponent = it.getBean(MyComponent::class.java) + assertThat(component.qualifier).isEqualTo("qualifier2") + } + } + +} diff --git a/spring-boot-conditions/src/test/kotlin/fixture/MyComponent.kt b/spring-boot-conditions/src/test/kotlin/fixture/MyComponent.kt new file mode 100644 index 0000000..e696395 --- /dev/null +++ b/spring-boot-conditions/src/test/kotlin/fixture/MyComponent.kt @@ -0,0 +1,4 @@ +package io.toolisticon.spring.condition.fixture + +class MyComponent(val qualifier: String) { +} diff --git a/spring-boot-conditions/src/test/kotlin/fixture/MyTestConfiguration.kt b/spring-boot-conditions/src/test/kotlin/fixture/MyTestConfiguration.kt new file mode 100644 index 0000000..736f827 --- /dev/null +++ b/spring-boot-conditions/src/test/kotlin/fixture/MyTestConfiguration.kt @@ -0,0 +1,15 @@ +package io.toolisticon.spring.condition.fixture + +import io.toolisticon.spring.condition.ConditionalOnMissingQualifiedBean +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +@Configuration +class MyTestConfiguration { + + @ConditionalOnMissingQualifiedBean(beanClass = MyComponent::class, qualifier = "qualifier") + @Bean + @Qualifier("qualifier") + fun component1(): MyComponent = MyComponent("qualifier1") +} diff --git a/spring-boot-conditions/src/test/kotlin/fixture/SimpleConfiguration.kt b/spring-boot-conditions/src/test/kotlin/fixture/SimpleConfiguration.kt new file mode 100644 index 0000000..12a378c --- /dev/null +++ b/spring-boot-conditions/src/test/kotlin/fixture/SimpleConfiguration.kt @@ -0,0 +1,14 @@ +package io.toolisticon.spring.condition.fixture + +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +@Configuration +class SimpleConfiguration { + + @Bean + @Qualifier(value = "qualifier") + fun component2(): MyComponent = MyComponent("qualifier2") + +} diff --git a/spring-boot-properties/pom.xml b/spring-boot-properties/pom.xml new file mode 100644 index 0000000..3070421 --- /dev/null +++ b/spring-boot-properties/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + + + io.toolisticon.spring + spring-boot-support + 1.0.1-SNAPSHOT + + + spring-boot-properties + Spring-Boot Properties + Set of useful Spring Boot properties helpers + + + + org.springframework + spring-context + provided + + + org.springframework.boot + spring-boot-autoconfigure + provided + + + org.slf4j + slf4j-api + provided + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.slf4j + slf4j-simple + test + + + + diff --git a/spring-boot-properties/src/main/kotlin/YamlPropertySourceFactory.kt b/spring-boot-properties/src/main/kotlin/YamlPropertySourceFactory.kt new file mode 100644 index 0000000..d2c6fad --- /dev/null +++ b/spring-boot-properties/src/main/kotlin/YamlPropertySourceFactory.kt @@ -0,0 +1,30 @@ +package io.toolisticon.spring.properties + +import org.springframework.beans.factory.config.YamlPropertiesFactoryBean +import org.springframework.core.env.PropertiesPropertySource +import org.springframework.core.env.PropertySource +import org.springframework.core.io.support.EncodedResource +import org.springframework.core.io.support.PropertySourceFactory +import org.springframework.lang.NonNull +import java.util.* + +/** + * Property source factory to read properties from YAML files. + * Inspired by [spring-yaml-propertysource](https://www.baeldung.com/spring-yaml-propertysource). + */ +class YamlPropertySourceFactory : PropertySourceFactory { + + @NonNull + override fun createPropertySource(name: String?, encodedResource: EncodedResource): PropertySource<*> { + + val factory = YamlPropertiesFactoryBean() + + factory.setResources(encodedResource.resource) + val properties = factory.getObject() + + return PropertiesPropertySource( + Objects.requireNonNull(name ?: encodedResource.resource.filename), + Objects.requireNonNull(properties) + ) + } +} diff --git a/spring-boot-properties/src/test/kotlin/YamlPropertySourceFactoryTest.kt b/spring-boot-properties/src/test/kotlin/YamlPropertySourceFactoryTest.kt new file mode 100644 index 0000000..3119eea --- /dev/null +++ b/spring-boot-properties/src/test/kotlin/YamlPropertySourceFactoryTest.kt @@ -0,0 +1,48 @@ +package io.toolisticon.spring.properties + +import io.toolisticon.spring.properties.fixture.MyProperties +import io.toolisticon.spring.properties.fixture.MyTestConfiguration +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.springframework.boot.context.annotation.UserConfigurations +import org.springframework.boot.test.context.runner.ApplicationContextRunner + +class YamlPropertySourceFactoryTest { + + private val contextRunner = ApplicationContextRunner() + .withConfiguration(UserConfigurations.of(MyTestConfiguration::class.java)) + + @Test + fun `properties are loaded from defaults`() { + contextRunner + .run { + + assertThat(it.getBean(MyProperties::class.java)).isNotNull + val props: MyProperties = it.getBean(MyProperties::class.java) + + assertThat(props.foo).isEqualTo("bar") + assertThat(props.zee).isEqualTo(12) + assertThat(props.baz).isTrue() + } + } + + @Test + fun `properties are loaded from defaults and overridden`() { + contextRunner + .withPropertyValues( + "test.foo=nobar", + "test.zee=42" + ) + .run { + assertThat(it.getBean(MyProperties::class.java)).isNotNull + val props: MyProperties = it.getBean(MyProperties::class.java) + + assertThat(props.foo).isEqualTo("nobar") + assertThat(props.zee).isEqualTo(42) + assertThat(props.baz).isTrue() + } + } + +} + + diff --git a/spring-boot-properties/src/test/kotlin/fixture/MyProperties.kt b/spring-boot-properties/src/test/kotlin/fixture/MyProperties.kt new file mode 100644 index 0000000..8e9a8ea --- /dev/null +++ b/spring-boot-properties/src/test/kotlin/fixture/MyProperties.kt @@ -0,0 +1,10 @@ +package io.toolisticon.spring.properties.fixture + +import org.springframework.boot.context.properties.ConfigurationProperties + +@ConfigurationProperties(prefix = "test") +data class MyProperties( + val foo: String, + val zee: Int, + val baz: Boolean +) diff --git a/spring-boot-properties/src/test/kotlin/fixture/MyTestConfiguration.kt b/spring-boot-properties/src/test/kotlin/fixture/MyTestConfiguration.kt new file mode 100644 index 0000000..1227c79 --- /dev/null +++ b/spring-boot-properties/src/test/kotlin/fixture/MyTestConfiguration.kt @@ -0,0 +1,17 @@ +package io.toolisticon.spring.properties.fixture + +import io.toolisticon.spring.properties.YamlPropertySourceFactory +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.PropertySource + +@PropertySource( + name = "defaultTestingProperties", + value = ["classpath:/application-testing.yaml"], + factory = YamlPropertySourceFactory::class +) +@EnableConfigurationProperties(MyProperties::class) +@Configuration +@ComponentScan +class MyTestConfiguration diff --git a/spring-boot-properties/src/test/resources/application-testing.yaml b/spring-boot-properties/src/test/resources/application-testing.yaml new file mode 100644 index 0000000..3eb1706 --- /dev/null +++ b/spring-boot-properties/src/test/resources/application-testing.yaml @@ -0,0 +1,4 @@ +test: + foo: "bar" + zee: 12 + baz: true