Skip to content

Adopt SmallRye Config #696

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions alpine-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
Expand Down
241 changes: 125 additions & 116 deletions alpine-common/src/main/java/alpine/Config.java

Large diffs are not rendered by default.

166 changes: 154 additions & 12 deletions alpine-common/src/test/java/alpine/ConfigTest.java
Original file line number Diff line number Diff line change
@@ -1,32 +1,56 @@
package alpine;

import io.smallrye.config.ConfigMapping;
import io.smallrye.config.SmallRyeConfigBuilder;
import io.smallrye.config.SmallRyeConfigBuilderCustomizer;
import io.smallrye.config.WithDefault;
import org.eclipse.microprofile.config.ConfigValue;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junitpioneer.jupiter.RestoreEnvironmentVariables;
import org.junitpioneer.jupiter.RestoreSystemProperties;
import org.junitpioneer.jupiter.SetEnvironmentVariable;
import org.junitpioneer.jupiter.SetSystemProperty;

import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.Map;
import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;

public class ConfigTest {

@AfterEach
public void tearDown() {
Config.reset();
@AfterAll
public static void tearDown() {
Config.reload(); // Ensure we're not affecting other tests
}

@AfterAll
public static void tearDownClass() {
Config.getInstance().init(); // Ensure we're not affecting other tests
@Test
@RestoreEnvironmentVariables
@SetEnvironmentVariable(key = "ALPINE_NO_PROXY", value = "foo, bar, baz")
void testGetPropertyAsList() {
Config.reload();

assertThat(Config.getInstance().getPropertyAsList(Config.AlpineKey.NO_PROXY)).containsExactly("foo", "bar", "baz");
}

@Test
void testGetProperty() {
Config.reload();

// Property with default value.
assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_URL)).isEqualTo("jdbc:h2:mem:alpine");

// Property without default value.
assertThat(Config.getInstance().getProperty(Config.AlpineKey.SECRET_KEY_PATH)).isNull();
}

@Test
public void testGetPassThroughPropertiesEmpty() {
Config.getInstance().init();
Config.reload();

assertThat(Config.getInstance().getPassThroughProperties("datanucleus")).isEmpty();
}
Expand All @@ -43,21 +67,139 @@ public void testGetPassThroughPropertiesEmpty() {
@SetEnvironmentVariable(key = "ALPINE_DATANUCLEUS_FROM_ENV", value = "fromEnv7")
@SetEnvironmentVariable(key = "alpine_datanucleus_from_env_lowercase", value = "fromEnv8")
@SetEnvironmentVariable(key = "Alpine_DataNucleus_From_Env_MixedCase", value = "fromEnv9")
public void testGetPassThroughProperties() {
@SetEnvironmentVariable(key = "ALPINE_DATANUCLEUS_EXPRESSION_FROM_ENV", value = "${alpine.datanucleus.from.env}")
public void testGetPassThroughProperties() throws Exception {
final URL propertiesUrl = ConfigTest.class.getResource("/Config_testGetPassThroughProperties.properties");
assertThat(propertiesUrl).isNotNull();

System.setProperty("alpine.application.properties", propertiesUrl.getPath());
final Path tmpPropertiesFile = Files.createTempFile(null, ".properties");
Files.copy(propertiesUrl.openStream(), tmpPropertiesFile, StandardCopyOption.REPLACE_EXISTING);

System.setProperty("alpine.application.properties", tmpPropertiesFile.toUri().toString());

Config.getInstance().init();
Config.reload();

assertThat(Config.getInstance().getPassThroughProperties("datanucleus"))
.containsExactlyInAnyOrderEntriesOf(Map.of(
"datanucleus.foo", "fromEnv3", // ENV takes precedence over properties
"datanucleus.foo.bar", "fromEnv4", // ENV takes precedence over properties
"datanucleus.from.env", "fromEnv7",
"datanucleus.from.props", "fromProps7"
"datanucleus.from.props", "fromProps7",
"datanucleus.from.env.lowercase", "fromEnv8",
"datanucleus.from.env.mixedcase", "fromEnv9",
"datanucleus.expression.from.props", "fromEnv3",
"datanucleus.expression.from.env", "fromEnv7"
));
}

@ConfigMapping(prefix = "alpine")
public interface TestConfig {

DatabaseConfig database();

interface DatabaseConfig {

Optional<String> url();

@WithDefault("testUser")
String username();

Map<String, String> pool();

}

}

public static class ConfigBuilderCustomizer implements SmallRyeConfigBuilderCustomizer {

@Override
public void configBuilder(final SmallRyeConfigBuilder configBuilder) {
configBuilder
.withMapping(TestConfig.class)
.withValidateUnknown(false);
}

}

@Test
@RestoreEnvironmentVariables
@SetEnvironmentVariable(key = "ALPINE_DATABASE_URL", value = "jdbc:h2:mem:alpine")
@SetEnvironmentVariable(key = "ALPINE_DATABASE_POOL_MAX_SIZE", value = "666")
void testGetMapping() {
Config.reload();

final var testConfig = Config.getInstance().getMapping(TestConfig.class);
assertThat(testConfig).isNotNull();
assertThat(testConfig.database().url()).contains("jdbc:h2:mem:alpine");
assertThat(testConfig.database().username()).isEqualTo("testUser");
assertThat(testConfig.database().pool())
.containsExactlyInAnyOrderEntriesOf(Map.of("max.size", "666"));
}

@Test
@RestoreEnvironmentVariables
@SetEnvironmentVariable(key = "ALPINE_CONFIG_PROFILE", value = "dev")
@SetEnvironmentVariable(key = "ALPINE_DATABASE_URL", value = "defaultUrl")
@SetEnvironmentVariable(key = "_DEV_ALPINE_DATABASE_URL", value = "devUrl")
@SetEnvironmentVariable(key = "ALPINE_DATABASE_USERNAME", value = "defaultUser")
void testProfiles() {
Config.reload();

assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_URL)).isEqualTo("devUrl");
assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_USERNAME)).isEqualTo("defaultUser");
}

@Test
@RestoreEnvironmentVariables
@SetEnvironmentVariable(key = "ALPINE_DATABASE_URL", value = "defaultUrl")
@SetEnvironmentVariable(key = "_PROD_ALPINE_DATABASE_URL", value = "prodUrl")
@SetEnvironmentVariable(key = "ALPINE_DATABASE_USERNAME", value = "defaultUser")
void testDefaultProfile() {
Config.reload();

assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_URL)).isEqualTo("prodUrl");
assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_USERNAME)).isEqualTo("defaultUser");
}

@Test
@RestoreEnvironmentVariables
@RestoreSystemProperties
@SetEnvironmentVariable(key = "ALPINE_DATABASE_USERNAME", value = "envUsername")
@SetSystemProperty(key = "alpine.database.password", value = "propertyPassword")
void testGetValue() throws Exception {
final URL propertiesUrl = ConfigTest.class.getResource("/Config_testGetValue.properties");
assertThat(propertiesUrl).isNotNull();

final Path tmpPropertiesFile = Files.createTempFile(null, ".properties");
Files.copy(propertiesUrl.openStream(), tmpPropertiesFile, StandardCopyOption.REPLACE_EXISTING);

System.setProperty("alpine.application.properties", tmpPropertiesFile.toUri().toString());

Config.reload();

ConfigValue configValue = Config.getInstance().getDelegate().getConfigValue(Config.AlpineKey.DATABASE_URL.getPropertyName());
assertThat(configValue.getValue()).isEqualTo("jdbc:h2:mem:alpine");
assertThat(configValue.getSourceName()).matches(
"PropertiesConfigSource\\[source=file:.+\\.properties]");

configValue = Config.getInstance().getDelegate().getConfigValue(Config.AlpineKey.DATABASE_USERNAME.getPropertyName());
assertThat(configValue.getValue()).isEqualTo("envUsername");
assertThat(configValue.getSourceName()).isEqualTo("EnvConfigSource");

configValue = Config.getInstance().getDelegate().getConfigValue(Config.AlpineKey.DATABASE_PASSWORD.getPropertyName());
assertThat(configValue.getValue()).isEqualTo("propertyPassword");
assertThat(configValue.getSourceName()).isEqualTo("SysPropConfigSource");
}

@Test
@RestoreEnvironmentVariables
@SetEnvironmentVariable(key = "ALPINE_DATABASE_USERNAME", value = "dbUsername")
@SetEnvironmentVariable(key = "ALPINE_DATABASE_PASSWORD", value = "${alpine.database.username}-123")
void testExpression() {
Config.reload();

assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_USERNAME)).isEqualTo("dbUsername");
assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_PASSWORD)).isEqualTo("dbUsername-123");
}

}
32 changes: 30 additions & 2 deletions alpine-common/src/test/java/alpine/common/util/ThreadUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,52 @@
*/
package alpine.common.util;

import alpine.Config;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junitpioneer.jupiter.RestoreEnvironmentVariables;
import org.junitpioneer.jupiter.SetEnvironmentVariable;

import java.lang.reflect.Method;

class ThreadUtilTest {

private static Method configReloadMethod;

@BeforeAll
public static void setUp() throws Exception {
configReloadMethod = Config.class.getDeclaredMethod("reload");
configReloadMethod.setAccessible(true);
}

@AfterEach
public void tearDown() throws Exception {
configReloadMethod.invoke(Config.getInstance());
}

@AfterAll
public static void tearDownClass() throws Exception {
configReloadMethod.invoke(Config.getInstance()); // Ensure we're not affecting other tests.
}

@Test
@RestoreEnvironmentVariables
@SetEnvironmentVariable(key = "ALPINE_WORKER_THREADS", value = "10")
void determineNumberOfWorkerThreadsStaticTest() {
void determineNumberOfWorkerThreadsStaticTest() throws Exception {
configReloadMethod.invoke(Config.getInstance());

Assertions.assertEquals(10, ThreadUtil.determineNumberOfWorkerThreads());
}

@Test
@RestoreEnvironmentVariables
@SetEnvironmentVariable(key = "ALPINE_WORKER_THREADS", value = "0")
void determineNumberOfWorkerThreadsDynamicTest() {
void determineNumberOfWorkerThreadsDynamicTest() throws Exception {
configReloadMethod.invoke(Config.getInstance());

Assertions.assertTrue(ThreadUtil.determineNumberOfWorkerThreads() > 0);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ alpine.data.nucleus.foo=fromProps5
datanucleus.foo=fromProps6
alpine.datanucleus.from.props=fromProps7
ALPINE.DATANUCLEUS.FROM.PROPS.UPPERCASE=fromProps8
Alpine.DataNucleus.From.Props.MixedCase=fromProps9
Alpine.DataNucleus.From.Props.MixedCase=fromProps9
alpine.datanucleus.expression.from.props=${alpine.datanucleus.foo}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
alpine.database.url=jdbc:h2:mem:alpine
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
alpine.ConfigTest$ConfigBuilderCustomizer
55 changes: 55 additions & 0 deletions alpine-test/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>us.springett</groupId>
<artifactId>alpine-parent</artifactId>
<version>3.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>alpine-test</artifactId>
<packaging>jar</packaging>
<version>3.2.0-SNAPSHOT</version>

<name>alpine-test</name>
<description>
An opinionated scaffolding library that jumpstarts Java projects with an API-first design,
secure defaults, and minimal dependencies.
</description>
<url>https://github.com/stevespringett/Alpine</url>
<inceptionYear>2016</inceptionYear>

<properties>
<lib.junit4.version>4.13.2</lib.junit4.version>
</properties>

<dependencies>
<dependency>
<groupId>us.springett</groupId>
<artifactId>alpine-common</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${lib.junit4.version}</version>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${lib.junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Loading