Skip to content
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

Warning messages for unknown build time properties #23943

Merged
merged 1 commit into from
Feb 24, 2022
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,9 @@ final class ReadOperation {
final Set<String> processedNames = new HashSet<>();

final Map<Class<?>, Object> objectsByClass = new HashMap<>();
final Map<String, String> specifiedRunTimeDefaultValues = new TreeMap<>();
final Map<String, String> buildTimeRunTimeVisibleValues = new TreeMap<>();
final Map<String, String> allBuildTimeValues = new TreeMap<>();
final Map<String, String> buildTimeRunTimeVisibleValues = new TreeMap<>();
final Map<String, String> specifiedRunTimeDefaultValues = new TreeMap<>();

final Map<ConverterType, Converter<?>> convByType = new HashMap<>();

Expand Down Expand Up @@ -362,10 +362,10 @@ ReadResult run() {
nameBuilder.setLength(0);
}

Set<String> registeredRoots = allRoots.stream().map(RootDefinition::getPrefix).collect(toSet());
// sweep-up
SmallRyeConfig runtimeDefaultsConfig = getConfigForRuntimeDefaults();
final Set<String> allProperties = getAllProperties(registeredRoots);
Set<String> registeredRoots = allRoots.stream().map(RootDefinition::getPrefix).collect(toSet());
Set<String> allProperties = getAllProperties(registeredRoots);
Set<String> unknownBuildProperties = new HashSet<>();
for (String propertyName : allProperties) {
if (propertyName.equals(ConfigSource.CONFIG_ORDINAL)) {
continue;
Expand Down Expand Up @@ -449,6 +449,7 @@ ReadResult run() {
if (configValue.getValue() != null) {
specifiedRunTimeDefaultValues.put(configValue.getNameProfiled(), configValue.getValue());
}
continue;
}
// also check for the bootstrap properties since those need to be added to specifiedRunTimeDefaultValues as well
ni.goToStart();
Expand All @@ -459,7 +460,11 @@ ReadResult run() {
if (configValue.getValue() != null) {
specifiedRunTimeDefaultValues.put(configValue.getNameProfiled(), configValue.getValue());
}
continue;
}

// If we reach here it means we were not able to match the property (and it shares roots namespace)
unknownBuildProperties.add(propertyName);
} else {
// it's not managed by us; record it
ConfigValue configValue = withoutExpansion(() -> runtimeDefaultsConfig.getConfigValue(propertyName));
Expand All @@ -478,6 +483,7 @@ ReadResult run() {
for (ConfigClassWithPrefix mapping : buildTimeMappings) {
Set<String> mappedProperties = ConfigMappings.mappedProperties(mapping, allProperties);
for (String property : mappedProperties) {
unknownBuildProperties.remove(property);
ConfigValue value = config.getConfigValue(property);
if (value != null && value.getRawValue() != null) {
allBuildTimeValues.put(property, value.getRawValue());
Expand All @@ -489,6 +495,7 @@ ReadResult run() {
for (ConfigClassWithPrefix mapping : buildTimeRunTimeMappings) {
Set<String> mappedProperties = ConfigMappings.mappedProperties(mapping, allProperties);
for (String property : mappedProperties) {
unknownBuildProperties.remove(property);
ConfigValue value = config.getConfigValue(property);
if (value != null && value.getRawValue() != null) {
allBuildTimeValues.put(property, value.getRawValue());
Expand All @@ -501,6 +508,7 @@ ReadResult run() {
for (ConfigClassWithPrefix mapping : runTimeMappings) {
Set<String> mappedProperties = ConfigMappings.mappedProperties(mapping, allProperties);
for (String property : mappedProperties) {
unknownBuildProperties.remove(property);
ConfigValue value = config.getConfigValue(property);
if (value != null && value.getRawValue() != null) {
specifiedRunTimeDefaultValues.put(property, value.getRawValue());
Expand All @@ -521,6 +529,7 @@ ReadResult run() {
.setBuildTimeMappings(buildTimeMappings)
.setBuildTimeRunTimeMappings(buildTimeRunTimeMappings)
.setRunTimeMappings(runTimeMappings)
.setUnknownBuildProperties(unknownBuildProperties)
.createReadResult();
}

Expand Down Expand Up @@ -940,6 +949,8 @@ public static final class ReadResult {
final List<ConfigClassWithPrefix> runTimeMappings;
final Map<Class<?>, ConfigClassWithPrefix> allMappings;

final Set<String> unknownBuildProperties;

public ReadResult(final Builder builder) {
this.objectsByClass = builder.getObjectsByClass();

Expand All @@ -961,6 +972,8 @@ public ReadResult(final Builder builder) {
this.buildTimeRunTimeMappings = builder.getBuildTimeRunTimeMappings();
this.runTimeMappings = builder.getRunTimeMappings();
this.allMappings = mappingsToMap(builder);

this.unknownBuildProperties = builder.getUnknownBuildProperties();
}

private static Map<Class<?>, RootDefinition> rootsToMap(Builder builder) {
Expand Down Expand Up @@ -1045,6 +1058,10 @@ public Map<Class<?>, ConfigClassWithPrefix> getAllMappings() {
return allMappings;
}

public Set<String> getUnknownBuildProperties() {
return unknownBuildProperties;
}

public Object requireObjectForClass(Class<?> clazz) {
Object obj = objectsByClass.get(clazz);
if (obj == null) {
Expand All @@ -1067,6 +1084,7 @@ static class Builder {
private List<ConfigClassWithPrefix> buildTimeMappings;
private List<ConfigClassWithPrefix> buildTimeRunTimeMappings;
private List<ConfigClassWithPrefix> runTimeMappings;
private Set<String> unknownBuildProperties;

Map<Class<?>, Object> getObjectsByClass() {
return objectsByClass;
Expand Down Expand Up @@ -1185,6 +1203,15 @@ Builder setRunTimeMappings(final List<ConfigClassWithPrefix> runTimeMappings) {
return this;
}

Set<String> getUnknownBuildProperties() {
return unknownBuildProperties;
}

Builder setUnknownBuildProperties(final Set<String> unknownBuildProperties) {
this.unknownBuildProperties = unknownBuildProperties;
return this;
}

ReadResult createReadResult() {
return new ReadResult(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.StaticInitSafe;
import io.quarkus.runtime.configuration.ConfigDiagnostic;
import io.quarkus.runtime.configuration.ConfigRecorder;
import io.quarkus.runtime.configuration.ConfigUtils;
import io.quarkus.runtime.configuration.ProfileManager;
Expand Down Expand Up @@ -140,6 +141,9 @@ void generateConfigClass(
List<RunTimeConfigBuilderBuildItem> runTimeConfigBuilders)
throws IOException {

reportUnknownBuildProperties(launchModeBuildItem.getLaunchMode(),
configItem.getReadResult().getUnknownBuildProperties());

if (liveReloadBuildItem.isLiveReload()) {
return;
}
Expand Down Expand Up @@ -192,7 +196,17 @@ void generateConfigClass(
.run();
}

private List<String> getAdditionalBootstrapConfigSourceProviders(
private static void reportUnknownBuildProperties(LaunchMode launchMode, Set<String> unknownBuildProperties) {
// So it only reports during the build, because it is very likely that the property is available in runtime
// and, it will be caught by the RuntimeConfig and log double warnings
if (!launchMode.isDevOrTest()) {
radcortez marked this conversation as resolved.
Show resolved Hide resolved
for (String unknownProperty : unknownBuildProperties) {
ConfigDiagnostic.unknown(unknownProperty);
}
}
}

private static List<String> getAdditionalBootstrapConfigSourceProviders(
List<AdditionalBootstrapConfigSourceProviderBuildItem> additionalBootstrapConfigSourceProviders) {
if (additionalBootstrapConfigSourceProviders.isEmpty()) {
return Collections.emptyList();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.quarkus.extest;

import static java.util.Arrays.asList;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.List;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.LogRecord;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.ProdBuildResults;
import io.quarkus.test.ProdModeTestResults;
import io.quarkus.test.QuarkusProdModeTest;

public class UnknownBuildConfigTest {
@RegisterExtension
static final QuarkusProdModeTest TEST = new QuarkusProdModeTest()
.setLogRecordPredicate(record -> record.getLevel().intValue() >= Level.WARNING.intValue())
.setExpectExit(true);

@ProdBuildResults
private ProdModeTestResults prodModeTestResults;

@Test
void unknownBuildConfig() {
List<LogRecord> logRecords = prodModeTestResults.getRetainedBuildLogRecords();

Optional<LogRecord> unknownBuildKey = logRecords.stream()
.filter(logRecord -> asList(logRecord.getParameters()).contains("quarkus.build.unknown.prop"))
.findFirst();
assertTrue(unknownBuildKey.isPresent());
assertTrue(unknownBuildKey.get().getMessage().startsWith("Unrecognized configuration key"));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.quarkus.extest;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.Set;
Expand Down Expand Up @@ -28,6 +29,7 @@ public class UnknownConfigTest {
Set<String> properties = logRecords.stream().flatMap(
logRecord -> Stream.of(logRecord.getParameters())).map(Object::toString).collect(Collectors.toSet());
assertTrue(properties.contains("quarkus.unknown.prop"));
assertFalse(properties.contains("quarkus.build.unknown.prop"));
});

@Inject
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.quarkus.extest.runtime.config.unknown;

import static java.util.Collections.emptyList;

import java.util.List;
import java.util.Map;

import org.eclipse.microprofile.config.spi.ConfigSource;

import io.smallrye.config.ConfigSourceContext;
import io.smallrye.config.ConfigSourceFactory;
import io.smallrye.config.ConfigValue;
import io.smallrye.config.PropertiesConfigSource;

public class UnknownBuildPropertyConfigSourceFactory implements ConfigSourceFactory {
@Override
public Iterable<ConfigSource> getConfigSources(final ConfigSourceContext context) {
ConfigValue value = context.getValue("skip.build.sources");
if (value.getValue() == null || value.getValue().equals("false")) {
return List.of(new PropertiesConfigSource(Map.of("quarkus.build.unknown.prop", "value"), "", 100));
} else {
return emptyList();
}
}
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
io.quarkus.extest.runtime.config.rename.RenameConfigSourceFactory
io.quarkus.extest.runtime.config.unknown.UnknownBuildPropertyConfigSourceFactory