Skip to content

Commit cd8f952

Browse files
committed
Allow Environment variables to populate property Maps in build time Config
1 parent 4585831 commit cd8f952

File tree

7 files changed

+23
-108
lines changed

7 files changed

+23
-108
lines changed

core/deployment/src/main/java/io/quarkus/deployment/configuration/BuildTimeConfigurationReader.java

+15-14
Original file line numberDiff line numberDiff line change
@@ -877,33 +877,34 @@ private Converter<?> getConverter(SmallRyeConfig config, Field field, ConverterT
877877

878878
/**
879879
* We collect all properties from eligible ConfigSources, because Config#getPropertyNames exclude the active
880-
* profiled properties, meaning that the property is written in the default config source without the profile
881-
* prefix. This may cause issues if we run with a different profile and fallback to defaults.
880+
* profiled properties (the property name omits the active profile prefix). If we record properties as is, we
881+
* can have an issue when running in a different profile from the one recorded. This list includes all available
882+
* properties in all profiles (active or not), so it is safe to fall back to different default on another
883+
* profile.
882884
* <br>
883-
* We also filter the properties coming from the System with the registered roots, because we don't want to
885+
* We also filter the properties coming from System or Env with the registered roots, because we don't want to
884886
* record properties set by the compiling JVM (or other properties that are only related to the build).
885-
* <br>
886-
* Properties coming from the Environment are ignored.
887887
*/
888888
private Set<String> getAllProperties(final Set<String> registeredRoots) {
889889
Set<String> properties = new HashSet<>();
890+
for (String property : config.getPropertyNames()) {
891+
properties.add(property);
892+
}
893+
890894
for (ConfigSource configSource : config.getConfigSources()) {
891-
// This is a BuildTimeSysPropConfigSource
892-
if (configSource instanceof SysPropConfigSource) {
893-
for (String propertyName : configSource.getProperties().keySet()) {
894-
NameIterator ni = new NameIterator(propertyName);
895+
if (configSource instanceof SysPropConfigSource || configSource instanceof EnvConfigSource) {
896+
for (String property : configSource.getPropertyNames()) {
897+
NameIterator ni = new NameIterator(property);
895898
if (ni.hasNext() && PropertiesUtil.isPropertyInRoot(registeredRoots, ni)) {
896-
properties.add(propertyName);
899+
properties.add(property);
900+
} else {
901+
properties.remove(property);
897902
}
898903
}
899904
} else {
900-
// The BuildTimeEnvConfigSource returns an empty Set
901905
properties.addAll(configSource.getPropertyNames());
902906
}
903907
}
904-
for (String propertyName : config.getPropertyNames()) {
905-
properties.add(propertyName);
906-
}
907908
return properties;
908909
}
909910

core/runtime/src/main/java/io/quarkus/runtime/configuration/ConfigUtils.java

+2-85
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
package io.quarkus.runtime.configuration;
22

3-
import static io.smallrye.config.PropertiesConfigSourceProvider.classPathSources;
43
import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_LOCATIONS;
54
import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_PROFILE;
65
import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_PROFILE_PARENT;
7-
import static io.smallrye.config.SmallRyeConfigBuilder.META_INF_MICROPROFILE_CONFIG_PROPERTIES;
86

9-
import java.io.IOException;
107
import java.lang.reflect.InvocationTargetException;
11-
import java.net.URL;
128
import java.util.ArrayList;
139
import java.util.Collection;
14-
import java.util.Collections;
1510
import java.util.Comparator;
1611
import java.util.HashMap;
1712
import java.util.LinkedHashSet;
@@ -36,15 +31,12 @@
3631
import io.smallrye.config.ConfigSourceInterceptorContext;
3732
import io.smallrye.config.ConfigSourceInterceptorFactory;
3833
import io.smallrye.config.DotEnvConfigSourceProvider;
39-
import io.smallrye.config.EnvConfigSource;
4034
import io.smallrye.config.FallbackConfigSourceInterceptor;
4135
import io.smallrye.config.NameIterator;
4236
import io.smallrye.config.Priorities;
4337
import io.smallrye.config.RelocateConfigSourceInterceptor;
4438
import io.smallrye.config.SmallRyeConfig;
4539
import io.smallrye.config.SmallRyeConfigBuilder;
46-
import io.smallrye.config.SysPropConfigSource;
47-
import io.smallrye.config.common.utils.ConfigSourceUtil;
4840

4941
/**
5042
*
@@ -100,24 +92,17 @@ public static SmallRyeConfigBuilder configBuilder(final boolean runTime, final b
10092

10193
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
10294
builder.forClassLoader(classLoader);
95+
builder.addDefaultSources();
10396
builder.withSources(new ApplicationPropertiesConfigSourceLoader.InFileSystem());
10497
builder.withSources(new ApplicationPropertiesConfigSourceLoader.InClassPath());
98+
builder.withSources(new DotEnvConfigSourceProvider());
10599
if (launchMode.isDevOrTest() && (runTime || bootstrap)) {
106100
builder.withSources(new RuntimeOverrideConfigSource(classLoader));
107101
}
108102
if (runTime || bootstrap) {
109-
builder.addDefaultSources();
110103
// Validator only for runtime. We cannot use the current validator for build time (chicken / egg problem)
111104
builder.addDiscoveredValidator();
112105
builder.withDefaultValue(UUID_KEY, UUID.randomUUID().toString());
113-
builder.withSources(new DotEnvConfigSourceProvider());
114-
} else {
115-
List<ConfigSource> sources = new ArrayList<>();
116-
sources.addAll(classPathSources(META_INF_MICROPROFILE_CONFIG_PROPERTIES, classLoader));
117-
sources.addAll(new BuildTimeDotEnvConfigSourceProvider().getConfigSources(classLoader));
118-
sources.add(new BuildTimeEnvConfigSource());
119-
sources.add(new BuildTimeSysPropConfigSource());
120-
builder.withSources(sources);
121106
}
122107
if (addDiscovered) {
123108
builder.addDiscoveredSources();
@@ -336,77 +321,9 @@ public static <T> Optional<T> getFirstOptionalValue(List<String> propertyNames,
336321
return Optional.empty();
337322
}
338323

339-
/**
340-
* We override the EnvConfigSource, because we don't want the nothing back from getPropertiesNames at build time.
341-
* The mapping is one way and there is no way to map them back.
342-
*/
343-
static class BuildTimeEnvConfigSource extends EnvConfigSource {
344-
BuildTimeEnvConfigSource() {
345-
super();
346-
}
347-
348-
BuildTimeEnvConfigSource(final Map<String, String> propertyMap, final int ordinal) {
349-
super(propertyMap, ordinal);
350-
}
351-
352-
@Override
353-
public Set<String> getPropertyNames() {
354-
return Collections.emptySet();
355-
}
356-
357-
@Override
358-
public String getName() {
359-
return "System environment";
360-
}
361-
}
362-
363-
/**
364-
* Same as BuildTimeEnvConfigSource.
365-
*/
366-
static class BuildTimeDotEnvConfigSourceProvider extends DotEnvConfigSourceProvider {
367-
public BuildTimeDotEnvConfigSourceProvider() {
368-
super();
369-
}
370-
371-
public BuildTimeDotEnvConfigSourceProvider(final String location) {
372-
super(location);
373-
}
374-
375-
@Override
376-
protected ConfigSource loadConfigSource(final URL url, final int ordinal) throws IOException {
377-
return new BuildTimeEnvConfigSource(ConfigSourceUtil.urlToMap(url), ordinal) {
378-
@Override
379-
public String getName() {
380-
return super.getName() + "[source=" + url + "]";
381-
}
382-
};
383-
}
384-
}
385-
386-
/**
387-
* We only want to include properties in the quarkus namespace.
388-
*
389-
* We removed the filter on the quarkus namespace due to the any prefix support for ConfigRoot. Filtering is now
390-
* done in io.quarkus.deployment.configuration.BuildTimeConfigurationReader.ReadOperation#getAllProperties.
391-
*/
392-
static class BuildTimeSysPropConfigSource extends SysPropConfigSource {
393-
public String getName() {
394-
return "System properties";
395-
}
396-
397-
@Override
398-
public Set<String> getPropertyNames() {
399-
return Collections.emptySet();
400-
}
401-
}
402-
403324
private static class ConfigBuilderComparator implements Comparator<ConfigBuilder> {
404-
405325
private static final ConfigBuilderComparator INSTANCE = new ConfigBuilderComparator();
406326

407-
private ConfigBuilderComparator() {
408-
}
409-
410327
@Override
411328
public int compare(ConfigBuilder o1, ConfigBuilder o2) {
412329
return Integer.compare(o1.priority(), o2.priority());

core/runtime/src/test/java/io/quarkus/runtime/configuration/DotEnvTestCase.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import org.junit.jupiter.api.Test;
1919

20+
import io.smallrye.config.DotEnvConfigSourceProvider;
2021
import io.smallrye.config.SmallRyeConfig;
2122
import io.smallrye.config.SmallRyeConfigBuilder;
2223

@@ -40,9 +41,7 @@ private SmallRyeConfig buildConfig(Map<String, String> configMap) throws IOExcep
4041
}
4142
}
4243
}
43-
builder.withSources(
44-
new ConfigUtils.BuildTimeDotEnvConfigSourceProvider(dotEnv.toUri().toString())
45-
.getConfigSources(Thread.currentThread().getContextClassLoader()));
44+
builder.withSources(new DotEnvConfigSourceProvider(dotEnv.toUri().toString()));
4645
final SmallRyeConfig config = builder.build();
4746
Files.delete(dotEnv);
4847
return config;
@@ -65,5 +64,4 @@ public void testProperties() throws IOException {
6564
assertEquals("foo.bar", config.getValue("foo.bar", String.class));
6665
assertTrue(config.getOptionalValue("foo.baz", String.class).isPresent());
6766
}
68-
6967
}

extensions/resteasy-classic/rest-client/deployment/src/test/java/io/quarkus/restclient/configuration/RestClientBuildTimeConfigSource.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ private static boolean isBuildTime() {
5959
// We can only call this when the SmallRyeConfig is already initialized, or else we may get into a loop
6060
Config config = ConfigProvider.getConfig();
6161
for (ConfigSource configSource : config.getConfigSources()) {
62-
if (configSource.getClass().getSimpleName().equals("BuildTimeEnvConfigSource")) {
62+
if (configSource.getName().equals("PropertiesConfigSource[source=Build system]")) {
6363
return true;
6464
}
6565
}

extensions/resteasy-classic/rest-client/deployment/src/test/java/io/quarkus/restclient/configuration/RestClientOverrideRuntimeConfigTest.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ public class RestClientOverrideRuntimeConfigTest {
3939
@Test
4040
void overrideConfig() {
4141
// Build time property recording
42-
Optional<ConfigSource> specifiedDefaultValues = config
43-
.getConfigSource("RunTime Defaults");
42+
Optional<ConfigSource> specifiedDefaultValues = config.getConfigSource("RunTime Defaults");
4443
assertTrue(specifiedDefaultValues.isPresent());
4544
assertTrue(specifiedDefaultValues.get().getPropertyNames()
4645
.contains("io.quarkus.restclient.configuration.EchoClient/mp-rest/url"));

integration-tests/jpa-postgresql/src/test/java/io/quarkus/it/jpa/postgresql/OverrideJdbcUrlBuildTimeConfigSource.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public String getValue(final String propertyName) {
2525

2626
boolean isBuildTime = false;
2727
for (ConfigSource configSource : ConfigProvider.getConfig().getConfigSources()) {
28-
if (configSource.getClass().getSimpleName().equals("BuildTimeEnvConfigSource")) {
28+
if (configSource.getName().equals("PropertiesConfigSource[source=Build system]")) {
2929
isBuildTime = true;
3030
break;
3131
}

integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/OverrideBuildTimeConfigSource.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public String getValue(final String propertyName) {
2929

3030
boolean isBuildTime = false;
3131
for (ConfigSource configSource : ConfigProvider.getConfig().getConfigSources()) {
32-
if (configSource.getClass().getSimpleName().equals("BuildTimeEnvConfigSource")) {
32+
if (configSource.getName().equals("PropertiesConfigSource[source=Build system]")) {
3333
isBuildTime = true;
3434
break;
3535
}

0 commit comments

Comments
 (0)