Skip to content

Commit

Permalink
Update SmallRye Config to 3.6.1
Browse files Browse the repository at this point in the history
  • Loading branch information
radcortez committed Mar 9, 2024
1 parent fc5df7c commit fbba2cc
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 74 deletions.
2 changes: 1 addition & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
<microprofile-lra.version>2.0</microprofile-lra.version>
<microprofile-openapi.version>3.1.1</microprofile-openapi.version>
<smallrye-common.version>2.3.0</smallrye-common.version>
<smallrye-config.version>3.6.0</smallrye-config.version>
<smallrye-config.version>3.6.1-SNAPSHOT</smallrye-config.version>
<smallrye-health.version>4.1.0</smallrye-health.version>
<smallrye-metrics.version>4.0.0</smallrye-metrics.version>
<smallrye-open-api.version>3.10.0</smallrye-open-api.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import static io.quarkus.deployment.util.ReflectUtil.toError;
import static io.quarkus.deployment.util.ReflectUtil.typeOfParameter;
import static io.quarkus.deployment.util.ReflectUtil.unwrapInvocationTargetException;
import static io.quarkus.runtime.configuration.PropertiesUtil.filterPropertiesInRoots;
import static io.smallrye.config.ConfigMappings.ConfigClassWithPrefix.configClassWithPrefix;
import static io.smallrye.config.Expressions.withoutExpansion;
import static java.util.stream.Collectors.toSet;
Expand Down Expand Up @@ -81,7 +82,8 @@
import io.smallrye.config.SmallRyeConfig;
import io.smallrye.config.SmallRyeConfigBuilder;
import io.smallrye.config.SysPropConfigSource;
import io.smallrye.config.common.utils.StringUtil;
import io.smallrye.config.common.AbstractConfigSource;
import io.smallrye.config.common.MapBackedConfigSource;

/**
* A configuration reader.
Expand Down Expand Up @@ -519,7 +521,6 @@ ReadResult run() {
buildTimeRunTimeValues.putAll(ConfigMappings.getDefaults(buildTimeRunTimeMapping));
}

SmallRyeConfig runtimeDefaultsConfig = getConfigForRuntimeDefaults();
Set<String> registeredRoots = allRoots.stream().map(RootDefinition::getName).collect(toSet());
registeredRoots.add("quarkus");
Set<String> allProperties = getAllProperties(registeredRoots);
Expand Down Expand Up @@ -599,7 +600,7 @@ ReadResult run() {
knownProperty = knownProperty || matched != null;
if (matched != null) {
// it's a run-time default (record for later)
ConfigValue configValue = withoutExpansion(() -> runtimeDefaultsConfig.getConfigValue(propertyName));
ConfigValue configValue = withoutExpansion(() -> config.getConfigValue(propertyName));
if (configValue.getValue() != null) {
runTimeValues.put(configValue.getNameProfiled(), configValue.getValue());
}
Expand All @@ -610,7 +611,7 @@ ReadResult run() {
}
} else {
// it's not managed by us; record it
ConfigValue configValue = withoutExpansion(() -> runtimeDefaultsConfig.getConfigValue(propertyName));
ConfigValue configValue = withoutExpansion(() -> config.getConfigValue(propertyName));
if (configValue.getValue() != null) {
runTimeValues.put(configValue.getNameProfiled(), configValue.getValue());
}
Expand Down Expand Up @@ -668,6 +669,15 @@ ReadResult run() {
}
}

Set<String> relocatesOrFallbacks = new HashSet<>();
for (String unknownBuildProperty : unknownBuildProperties) {
ConfigValue configValue = config.getConfigValue(unknownBuildProperty);
if (!unknownBuildProperties.contains(configValue.getName())) {
relocatesOrFallbacks.add(unknownBuildProperty);
}
}
unknownBuildProperties.removeAll(relocatesOrFallbacks);

return new ReadResult.Builder().setObjectsByClass(objectsByClass)
.setAllBuildTimeValues(allBuildTimeValues)
.setBuildTimeRunTimeValues(filterActiveProfileProperties(buildTimeRunTimeValues))
Expand Down Expand Up @@ -1026,66 +1036,66 @@ private Converter<?> getConverter(SmallRyeConfig config, Field field, ConverterT
* want to record properties set by the compiling JVM (or other properties that are only related to the build).
*/
private Set<String> getAllProperties(final Set<String> registeredRoots) {
Set<String> properties = new HashSet<>();

// Get all properties, including the ones generated by interceptors, but these do not include profiles
for (String property : config.getPropertyNames()) {
properties.add(property);
}

Set<String> propertiesToRemove = new HashSet<>();
Set<String> propertiesToAdd = new HashSet<>();

// Get properties per source to collect profiled properties and exclude properties that are build related
Set<String> sourcesProperties = new HashSet<>();
for (ConfigSource configSource : config.getConfigSources()) {
// only consider properties from Quarkus roots
if (configSource instanceof SysPropConfigSource || configSource instanceof EnvConfigSource
|| "PropertiesConfigSource[source=Build system]".equals(configSource.getName())) {
for (String property : configSource.getPropertyNames()) {
NameIterator ni = new NameIterator(property);
if (ni.hasNext() && PropertiesUtil.isPropertyInRoot(registeredRoots, ni)) {
propertiesToAdd.add(property);
} else {
propertiesToRemove.add(property);
if (configSource instanceof EnvConfigSource) {
propertiesToRemove.add(StringUtil.toLowerCaseAndDotted(property));
String unprofiledProperty = property;
if (property.startsWith("%")) {
int profileDot = property.indexOf('.');
if (profileDot != -1) {
unprofiledProperty = property.substring(profileDot + 1);
}
}
if (filterPropertiesInRoots(List.of(unprofiledProperty), registeredRoots).iterator().hasNext()) {
sourcesProperties.add(property);
}
}
} else {
propertiesToAdd.addAll(configSource.getPropertyNames());
sourcesProperties.addAll(configSource.getPropertyNames());
}
}

// A property may exist in an excluded source and an include source. We don't have a way to know, so we
// just remove the excluded ones and add the ones to be included, so the property is back there again
properties.removeAll(propertiesToRemove);
properties.addAll(propertiesToAdd);

return properties;
}
Set<String> properties = new HashSet<>();

/**
* Use this Config instance to record the runtime default values. We cannot use the main Config
* instance because it may record values coming from the EnvSource in build time. Environment variable values
* may be completely different between build and runtime, so it doesn't make sense to record these.
* <br>
* We do exclude the properties coming from the EnvSource, but a call to getValue may still provide a result
* coming from the EnvSource, so we need to exclude it from the sources when recording values for runtime.
* <br>
* We also do not want to completely exclude the EnvSource, because it may provide values for the build. This
* is only specific when recording the defaults.
*
* @return a new SmallRye instance without the EnvSources.
*/
private SmallRyeConfig getConfigForRuntimeDefaults() {
// We build a new Config to also apply the interceptor chain, this includes the active profile. A property
// may only exist in its profiled name format, but it requires recording in the unprofiled name
SmallRyeConfigBuilder builder = ConfigUtils.emptyConfigBuilder();
for (ConfigSource configSource : config.getConfigSources()) {
if (configSource instanceof EnvConfigSource) {
continue;
}
builder.withSources(configSource);
builder.getSources().clear();
builder.getSourceProviders().clear();
builder.setAddDefaultSources(false)
.addDiscoveredCustomizers()
.withSources(new AbstractConfigSource("SourceProperties", 100) {
@Override
public Set<String> getPropertyNames() {
return sourcesProperties;
}

@Override
public String getValue(final String propertyName) {
return null;
}
});

// We also need an empty profile Config to record the properties that are not on the active profile
SmallRyeConfig config = builder.build();
for (String property : config.getPropertyNames()) {
properties.add(property);
}
return builder.build();

builder.withSources(new MapBackedConfigSource("Reset Profile",
Map.of("quarkus.profile", "",
"quarkus.test.profile", "")) {
});
config = builder.build();
properties = new HashSet<>();
for (String property : config.getPropertyNames()) {
properties.add(property);
}

return properties;
}

private Map<String, String> filterActiveProfileProperties(final Map<String, String> properties) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.jboss.logging.Logger;

import io.quarkus.runtime.ImageMode;
import io.smallrye.config.ConfigValue;
import io.smallrye.config.SmallRyeConfig;
import io.smallrye.config.common.utils.StringUtil;

Expand Down Expand Up @@ -90,8 +91,9 @@ public static void unknown(NameIterator name) {
* @param properties the set of possible unused properties
*/
public static void unknownProperties(Set<String> properties) {
SmallRyeConfig config = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class);
Set<String> usedProperties = new HashSet<>();
for (String property : ConfigProvider.getConfig().getPropertyNames()) {
for (String property : config.getPropertyNames()) {
if (properties.contains(property)) {
continue;
}
Expand All @@ -114,7 +116,10 @@ public static void unknownProperties(Set<String> properties) {
}
}
if (!found) {
unknown(property);
ConfigValue configValue = config.getConfigValue(property);
if (property.equals(configValue.getName())) {
unknown(property);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ quarkus.arc.unremovable-types=foo
quarkus.arc.unremovable-types[0]=foo

### Do not record env values in build time
bt.do.not.record=properties
bt.ok.to.record=properties
%test.bt.profile.record=properties

### mappings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ quarkus.arc.unremovable-types=foo
quarkus.arc.unremovable-types[0]=foo

### Do not record env values in build time
bt.do.not.record=properties
bt.ok.to.record=properties
%test.bt.profile.record=properties

### mappings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ void rename() {
// In Build time source
assertNotNull(buildTimeRunTimeDefaults.getValue("quarkus.rename.prop"));
assertNotNull(buildTimeRunTimeDefaults.getValue("quarkus.rename.only-in-new"));
assertNotNull(buildTimeRunTimeDefaults.getValue("quarkus.rename-old.only-in-old"));
assertNotNull(buildTimeRunTimeDefaults.getValue("quarkus.rename.only-in-old"));
assertNotNull(buildTimeRunTimeDefaults.getValue("quarkus.rename.in-both"));
// When in both only the one that has priority (remamed) is recorded
assertNull(buildTimeRunTimeDefaults.getValue("quarkus.rename-old.in-both"));
Expand All @@ -68,7 +68,7 @@ void rename() {
assertNotNull(config.getRawValue("quarkus.rename-old.prop"));
assertNull(buildTimeRunTimeDefaults.getValue("quarkus.rename-old.only-in-new"));
assertNotNull(config.getRawValue("quarkus.rename-old.only-in-new"));
assertNull(buildTimeRunTimeDefaults.getValue("quarkus.rename.only-in-old"));
assertNotNull(config.getRawValue("quarkus.rename.only-in-old"));
assertNull(buildTimeRunTimeDefaults.getValue("quarkus.rename-old.only-in-old"));
assertNotNull(config.getRawValue("quarkus.rename-old.only-in-old"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ public class ConfiguredBeanTest {
.addClasses(ConfiguredBean.class)
// Don't change this to types, because of classloader class cast exception.
.addAsServiceProvider("org.eclipse.microprofile.config.spi.ConfigSource",
"io.quarkus.extest.runtime.config.OverrideBuildTimeConfigSource")
"io.quarkus.extest.runtime.config.OverrideBuildTimeConfigSource\n" +
"io.quarkus.extest.runtime.config.RecordQuarkusSystemPropertiesConfigSource")
.addAsResource("application.properties"));

@Inject
Expand Down Expand Up @@ -363,6 +364,11 @@ public void testProfileDefaultValuesSource() {
assertEquals("5678", defaultValues.getValue("%dev.my.prop"));
assertEquals("1234", defaultValues.getValue("%test.my.prop"));
assertEquals("1234", config.getValue("my.prop", String.class));
assertNull(defaultValues.getValue("should.not.be.recorded"));
assertNull(defaultValues.getValue("SHOULD_NOT_BE_RECORDED"));
assertEquals("value", defaultValues.getValue("quarkus.mapping.rt.record"));
assertEquals("prod", defaultValues.getValue("%prod.quarkus.mapping.rt.record"));
assertEquals("dev", defaultValues.getValue("%dev.quarkus.mapping.rt.record"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ public class RuntimeDefaultsTest {
void doNotRecordEnvRuntimeDefaults() {
Optional<ConfigSource> defaultValues = config.getConfigSource("DefaultValuesConfigSource");
assertTrue(defaultValues.isPresent());
assertEquals("rtStringOptValue", defaultValues.get().getValue("quarkus.rt.rt-string-opt"));
assertEquals("properties", defaultValues.get().getValue("bt.do.not.record"));
// It's ok to record env properties for a Quarkus root
assertEquals("changed", defaultValues.get().getValue("quarkus.rt.rt-string-opt"));
// It's ok to record env properties for a property available in another source
assertEquals("env-source", defaultValues.get().getValue("bt.ok.to.record"));
// Do not record any of the other properties
assertNull(defaultValues.get().getValue(("do.not.record")));
assertNull(defaultValues.get().getValue(("DO_NOT_RECORD")));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,8 @@ void unknownBuildConfig() {
.orElse(new Object[0]))
.collect(toSet());

assertEquals(7, unrecognized.size());
assertEquals(2, unrecognized.size());
assertTrue(unrecognized.contains("quarkus.unknown.prop"));
assertTrue(unrecognized.contains("quarkus.build.unknown.prop"));
assertTrue(unrecognized.contains("quarkus.rename-old.prop"));
assertTrue(unrecognized.contains("quarkus.rename-old.only-in-new"));
assertTrue(unrecognized.contains("quarkus.rename-old.only-in-old"));
assertTrue(unrecognized.contains("quarkus.rename-old.in-both"));
assertTrue(unrecognized.contains("quarkus.rename-old.with-default"));
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package io.quarkus.extest.runtime.config;

import java.util.HashMap;
import java.util.Map;

import io.smallrye.config.EnvConfigSource;

public class EnvBuildTimeConfigSource extends EnvConfigSource {
public EnvBuildTimeConfigSource() {
super(new HashMap<>() {
{
put("QUARKUS_RT_RT_STRING_OPT", "changed");
put("BT_DO_NOT_RECORD", "env-source");
}
}, Integer.MAX_VALUE);
super(Map.of("QUARKUS_RT_RT_STRING_OPT", "changed",
"BT_OK_TO_RECORD", "env-source",
"DO_NOT_RECORD", "record"), Integer.MAX_VALUE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.quarkus.extest.runtime.config;

import java.util.Map;

import io.quarkus.runtime.annotations.StaticInitSafe;
import io.smallrye.config.EnvConfigSource;

@StaticInitSafe
public class RecordQuarkusSystemPropertiesConfigSource extends EnvConfigSource {
public RecordQuarkusSystemPropertiesConfigSource() {
super(Map.of(
"SHOULD_NOT_BE_RECORDED", "value",
"should.not.be.recorded", "value",
"quarkus.mapping.rt.record", "value",
"%dev.quarkus.mapping.rt.record", "dev",
"_PROD_QUARKUS_MAPPING_RT_RECORD", "prod"), 0);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.quarkus.extest.runtime.config;

import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
Expand All @@ -17,6 +19,9 @@ public interface TestMappingRunTime {
*/
Group group();

/** Record values from env test **/
Optional<String> record();

interface Group {
/**
* A Group value.
Expand Down

0 comments on commit fbba2cc

Please sign in to comment.