Skip to content

Commit 0f1c844

Browse files
committed
Adopt SmallRye Config
Closes #695 Signed-off-by: nscuro <nscuro@protonmail.com> # Conflicts: # pom.xml
1 parent 2250f38 commit 0f1c844

File tree

17 files changed

+690
-131
lines changed

17 files changed

+690
-131
lines changed

alpine-common/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
<groupId>org.apache.commons</groupId>
3636
<artifactId>commons-lang3</artifactId>
3737
</dependency>
38+
<dependency>
39+
<groupId>io.smallrye.config</groupId>
40+
<artifactId>smallrye-config-core</artifactId>
41+
</dependency>
3842
<dependency>
3943
<groupId>com.fasterxml.jackson.core</groupId>
4044
<artifactId>jackson-annotations</artifactId>

alpine-common/src/main/java/alpine/Config.java

Lines changed: 125 additions & 116 deletions
Large diffs are not rendered by default.
Lines changed: 154 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,56 @@
11
package alpine;
22

3+
import io.smallrye.config.ConfigMapping;
4+
import io.smallrye.config.SmallRyeConfigBuilder;
5+
import io.smallrye.config.SmallRyeConfigBuilderCustomizer;
6+
import io.smallrye.config.WithDefault;
7+
import org.eclipse.microprofile.config.ConfigValue;
38
import org.junit.jupiter.api.AfterAll;
4-
import org.junit.jupiter.api.AfterEach;
59
import org.junit.jupiter.api.Test;
610
import org.junitpioneer.jupiter.RestoreEnvironmentVariables;
711
import org.junitpioneer.jupiter.RestoreSystemProperties;
812
import org.junitpioneer.jupiter.SetEnvironmentVariable;
13+
import org.junitpioneer.jupiter.SetSystemProperty;
914

1015
import java.net.URL;
16+
import java.nio.file.Files;
17+
import java.nio.file.Path;
18+
import java.nio.file.StandardCopyOption;
1119
import java.util.Map;
20+
import java.util.Optional;
1221

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

1524
public class ConfigTest {
1625

17-
@AfterEach
18-
public void tearDown() {
19-
Config.reset();
26+
@AfterAll
27+
public static void tearDown() {
28+
Config.reload(); // Ensure we're not affecting other tests
2029
}
2130

22-
@AfterAll
23-
public static void tearDownClass() {
24-
Config.getInstance().init(); // Ensure we're not affecting other tests
31+
@Test
32+
@RestoreEnvironmentVariables
33+
@SetEnvironmentVariable(key = "ALPINE_NO_PROXY", value = "foo, bar, baz")
34+
void testGetPropertyAsList() {
35+
Config.reload();
36+
37+
assertThat(Config.getInstance().getPropertyAsList(Config.AlpineKey.NO_PROXY)).containsExactly("foo", "bar", "baz");
38+
}
39+
40+
@Test
41+
void testGetProperty() {
42+
Config.reload();
43+
44+
// Property with default value.
45+
assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_URL)).isEqualTo("jdbc:h2:mem:alpine");
46+
47+
// Property without default value.
48+
assertThat(Config.getInstance().getProperty(Config.AlpineKey.SECRET_KEY_PATH)).isNull();
2549
}
2650

2751
@Test
2852
public void testGetPassThroughPropertiesEmpty() {
29-
Config.getInstance().init();
53+
Config.reload();
3054

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

50-
System.setProperty("alpine.application.properties", propertiesUrl.getPath());
75+
final Path tmpPropertiesFile = Files.createTempFile(null, ".properties");
76+
Files.copy(propertiesUrl.openStream(), tmpPropertiesFile, StandardCopyOption.REPLACE_EXISTING);
77+
78+
System.setProperty("alpine.application.properties", tmpPropertiesFile.toUri().toString());
5179

52-
Config.getInstance().init();
80+
Config.reload();
5381

5482
assertThat(Config.getInstance().getPassThroughProperties("datanucleus"))
5583
.containsExactlyInAnyOrderEntriesOf(Map.of(
5684
"datanucleus.foo", "fromEnv3", // ENV takes precedence over properties
5785
"datanucleus.foo.bar", "fromEnv4", // ENV takes precedence over properties
5886
"datanucleus.from.env", "fromEnv7",
59-
"datanucleus.from.props", "fromProps7"
87+
"datanucleus.from.props", "fromProps7",
88+
"datanucleus.from.env.lowercase", "fromEnv8",
89+
"datanucleus.from.env.mixedcase", "fromEnv9",
90+
"datanucleus.expression.from.props", "fromEnv3",
91+
"datanucleus.expression.from.env", "fromEnv7"
6092
));
6193
}
6294

95+
@ConfigMapping(prefix = "alpine")
96+
public interface TestConfig {
97+
98+
DatabaseConfig database();
99+
100+
interface DatabaseConfig {
101+
102+
Optional<String> url();
103+
104+
@WithDefault("testUser")
105+
String username();
106+
107+
Map<String, String> pool();
108+
109+
}
110+
111+
}
112+
113+
public static class ConfigBuilderCustomizer implements SmallRyeConfigBuilderCustomizer {
114+
115+
@Override
116+
public void configBuilder(final SmallRyeConfigBuilder configBuilder) {
117+
configBuilder
118+
.withMapping(TestConfig.class)
119+
.withValidateUnknown(false);
120+
}
121+
122+
}
123+
124+
@Test
125+
@RestoreEnvironmentVariables
126+
@SetEnvironmentVariable(key = "ALPINE_DATABASE_URL", value = "jdbc:h2:mem:alpine")
127+
@SetEnvironmentVariable(key = "ALPINE_DATABASE_POOL_MAX_SIZE", value = "666")
128+
void testGetMapping() {
129+
Config.reload();
130+
131+
final var testConfig = Config.getInstance().getMapping(TestConfig.class);
132+
assertThat(testConfig).isNotNull();
133+
assertThat(testConfig.database().url()).contains("jdbc:h2:mem:alpine");
134+
assertThat(testConfig.database().username()).isEqualTo("testUser");
135+
assertThat(testConfig.database().pool())
136+
.containsExactlyInAnyOrderEntriesOf(Map.of("max.size", "666"));
137+
}
138+
139+
@Test
140+
@RestoreEnvironmentVariables
141+
@SetEnvironmentVariable(key = "ALPINE_CONFIG_PROFILE", value = "dev")
142+
@SetEnvironmentVariable(key = "ALPINE_DATABASE_URL", value = "defaultUrl")
143+
@SetEnvironmentVariable(key = "_DEV_ALPINE_DATABASE_URL", value = "devUrl")
144+
@SetEnvironmentVariable(key = "ALPINE_DATABASE_USERNAME", value = "defaultUser")
145+
void testProfiles() {
146+
Config.reload();
147+
148+
assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_URL)).isEqualTo("devUrl");
149+
assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_USERNAME)).isEqualTo("defaultUser");
150+
}
151+
152+
@Test
153+
@RestoreEnvironmentVariables
154+
@SetEnvironmentVariable(key = "ALPINE_DATABASE_URL", value = "defaultUrl")
155+
@SetEnvironmentVariable(key = "_PROD_ALPINE_DATABASE_URL", value = "prodUrl")
156+
@SetEnvironmentVariable(key = "ALPINE_DATABASE_USERNAME", value = "defaultUser")
157+
void testDefaultProfile() {
158+
Config.reload();
159+
160+
assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_URL)).isEqualTo("prodUrl");
161+
assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_USERNAME)).isEqualTo("defaultUser");
162+
}
163+
164+
@Test
165+
@RestoreEnvironmentVariables
166+
@RestoreSystemProperties
167+
@SetEnvironmentVariable(key = "ALPINE_DATABASE_USERNAME", value = "envUsername")
168+
@SetSystemProperty(key = "alpine.database.password", value = "propertyPassword")
169+
void testGetValue() throws Exception {
170+
final URL propertiesUrl = ConfigTest.class.getResource("/Config_testGetValue.properties");
171+
assertThat(propertiesUrl).isNotNull();
172+
173+
final Path tmpPropertiesFile = Files.createTempFile(null, ".properties");
174+
Files.copy(propertiesUrl.openStream(), tmpPropertiesFile, StandardCopyOption.REPLACE_EXISTING);
175+
176+
System.setProperty("alpine.application.properties", tmpPropertiesFile.toUri().toString());
177+
178+
Config.reload();
179+
180+
ConfigValue configValue = Config.getInstance().getDelegate().getConfigValue(Config.AlpineKey.DATABASE_URL.getPropertyName());
181+
assertThat(configValue.getValue()).isEqualTo("jdbc:h2:mem:alpine");
182+
assertThat(configValue.getSourceName()).matches(
183+
"PropertiesConfigSource\\[source=file:.+\\.properties]");
184+
185+
configValue = Config.getInstance().getDelegate().getConfigValue(Config.AlpineKey.DATABASE_USERNAME.getPropertyName());
186+
assertThat(configValue.getValue()).isEqualTo("envUsername");
187+
assertThat(configValue.getSourceName()).isEqualTo("EnvConfigSource");
188+
189+
configValue = Config.getInstance().getDelegate().getConfigValue(Config.AlpineKey.DATABASE_PASSWORD.getPropertyName());
190+
assertThat(configValue.getValue()).isEqualTo("propertyPassword");
191+
assertThat(configValue.getSourceName()).isEqualTo("SysPropConfigSource");
192+
}
193+
194+
@Test
195+
@RestoreEnvironmentVariables
196+
@SetEnvironmentVariable(key = "ALPINE_DATABASE_USERNAME", value = "dbUsername")
197+
@SetEnvironmentVariable(key = "ALPINE_DATABASE_PASSWORD", value = "${alpine.database.username}-123")
198+
void testExpression() {
199+
Config.reload();
200+
201+
assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_USERNAME)).isEqualTo("dbUsername");
202+
assertThat(Config.getInstance().getProperty(Config.AlpineKey.DATABASE_PASSWORD)).isEqualTo("dbUsername-123");
203+
}
204+
63205
}

alpine-common/src/test/java/alpine/common/util/ThreadUtilTest.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,52 @@
1818
*/
1919
package alpine.common.util;
2020

21+
import alpine.Config;
22+
import org.junit.jupiter.api.AfterAll;
23+
import org.junit.jupiter.api.AfterEach;
2124
import org.junit.jupiter.api.Assertions;
25+
import org.junit.jupiter.api.BeforeAll;
2226
import org.junit.jupiter.api.Test;
2327
import org.junitpioneer.jupiter.RestoreEnvironmentVariables;
2428
import org.junitpioneer.jupiter.SetEnvironmentVariable;
2529

30+
import java.lang.reflect.Method;
31+
2632
class ThreadUtilTest {
2733

34+
private static Method configReloadMethod;
35+
36+
@BeforeAll
37+
public static void setUp() throws Exception {
38+
configReloadMethod = Config.class.getDeclaredMethod("reload");
39+
configReloadMethod.setAccessible(true);
40+
}
41+
42+
@AfterEach
43+
public void tearDown() throws Exception {
44+
configReloadMethod.invoke(Config.getInstance());
45+
}
46+
47+
@AfterAll
48+
public static void tearDownClass() throws Exception {
49+
configReloadMethod.invoke(Config.getInstance()); // Ensure we're not affecting other tests.
50+
}
51+
2852
@Test
2953
@RestoreEnvironmentVariables
3054
@SetEnvironmentVariable(key = "ALPINE_WORKER_THREADS", value = "10")
31-
void determineNumberOfWorkerThreadsStaticTest() {
55+
void determineNumberOfWorkerThreadsStaticTest() throws Exception {
56+
configReloadMethod.invoke(Config.getInstance());
57+
3258
Assertions.assertEquals(10, ThreadUtil.determineNumberOfWorkerThreads());
3359
}
3460

3561
@Test
3662
@RestoreEnvironmentVariables
3763
@SetEnvironmentVariable(key = "ALPINE_WORKER_THREADS", value = "0")
38-
void determineNumberOfWorkerThreadsDynamicTest() {
64+
void determineNumberOfWorkerThreadsDynamicTest() throws Exception {
65+
configReloadMethod.invoke(Config.getInstance());
66+
3967
Assertions.assertTrue(ThreadUtil.determineNumberOfWorkerThreads() > 0);
4068
}
4169

alpine-common/src/test/resources/Config_testGetPassThroughProperties.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ alpine.data.nucleus.foo=fromProps5
66
datanucleus.foo=fromProps6
77
alpine.datanucleus.from.props=fromProps7
88
ALPINE.DATANUCLEUS.FROM.PROPS.UPPERCASE=fromProps8
9-
Alpine.DataNucleus.From.Props.MixedCase=fromProps9
9+
Alpine.DataNucleus.From.Props.MixedCase=fromProps9
10+
alpine.datanucleus.expression.from.props=${alpine.datanucleus.foo}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
alpine.database.url=jdbc:h2:mem:alpine
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
alpine.ConfigTest$ConfigBuilderCustomizer

alpine-test/pom.xml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<groupId>us.springett</groupId>
7+
<artifactId>alpine-parent</artifactId>
8+
<version>3.2.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>alpine-test</artifactId>
13+
<packaging>jar</packaging>
14+
<version>3.2.0-SNAPSHOT</version>
15+
16+
<name>alpine-test</name>
17+
<description>
18+
An opinionated scaffolding library that jumpstarts Java projects with an API-first design,
19+
secure defaults, and minimal dependencies.
20+
</description>
21+
<url>https://github.com/stevespringett/Alpine</url>
22+
<inceptionYear>2016</inceptionYear>
23+
24+
<properties>
25+
<lib.junit4.version>4.13.2</lib.junit4.version>
26+
</properties>
27+
28+
<dependencies>
29+
<dependency>
30+
<groupId>us.springett</groupId>
31+
<artifactId>alpine-common</artifactId>
32+
<version>${project.parent.version}</version>
33+
<scope>provided</scope>
34+
</dependency>
35+
36+
<dependency>
37+
<groupId>junit</groupId>
38+
<artifactId>junit</artifactId>
39+
<version>${lib.junit4.version}</version>
40+
</dependency>
41+
42+
<dependency>
43+
<groupId>org.junit.jupiter</groupId>
44+
<artifactId>junit-jupiter</artifactId>
45+
<scope>test</scope>
46+
</dependency>
47+
<dependency>
48+
<groupId>org.junit.vintage</groupId>
49+
<artifactId>junit-vintage-engine</artifactId>
50+
<version>${lib.junit-jupiter.version}</version>
51+
<scope>test</scope>
52+
</dependency>
53+
</dependencies>
54+
55+
</project>

0 commit comments

Comments
 (0)