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

Improve matching of config properties to a root #35726

Merged
merged 1 commit into from
Sep 12, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ public final class RunTimeConfigurationGenerator {

static final MethodDescriptor PU_IS_PROPERTY_IN_ROOT = MethodDescriptor.ofMethod(PropertiesUtil.class,
"isPropertyInRoot", boolean.class, Set.class, NameIterator.class);
static final MethodDescriptor PU_FILTER_PROPERTIES_IN_ROOTS = MethodDescriptor.ofMethod(PropertiesUtil.class,
"filterPropertiesInRoots", Iterable.class, Iterable.class, Set.class);

static final MethodDescriptor PU_IS_PROPERTY_QUARKUS_COMPOUND_NAME = MethodDescriptor.ofMethod(PropertiesUtil.class,
"isPropertyQuarkusCompoundName", boolean.class, NameIterator.class);
static final MethodDescriptor PU_FILTER_UNKNOWN = MethodDescriptor.ofMethod(PropertiesUtil.class, "filterUnknown",
Expand Down Expand Up @@ -668,16 +671,10 @@ public void run() {

private void configSweepLoop(MethodDescriptor parserBody, MethodCreator method, ResultHandle config,
Set<String> registeredRoots, Type type) {
ResultHandle rootSet;
ResultHandle nameSet;
ResultHandle iterator;

rootSet = method.newInstance(HS_NEW);
for (String registeredRoot : registeredRoots) {
method.invokeVirtualMethod(HS_ADD, rootSet, method.load(registeredRoot));
}

nameSet = method.invokeVirtualMethod(SRC_GET_PROPERTY_NAMES, config);
nameSet = filterProperties(method, config, registeredRoots);
iterator = method.invokeInterfaceMethod(ITRA_ITERATOR, nameSet);

try (BytecodeCreator sweepLoop = method.createScope()) {
Expand All @@ -701,8 +698,6 @@ private void configSweepLoop(MethodDescriptor parserBody, MethodCreator method,
// if (! keyIter.hasNext()) continue sweepLoop;
hasNext.ifNonZero(hasNext.invokeVirtualMethod(NI_HAS_NEXT, keyIter)).falseBranch().continueScope(sweepLoop);
// if (! keyIter.nextSegmentEquals("quarkus")) continue sweepLoop;
hasNext.ifNonZero(hasNext.invokeStaticMethod(PU_IS_PROPERTY_IN_ROOT, rootSet, keyIter)).falseBranch()
.continueScope(sweepLoop);
// parse(config, keyIter);
hasNext.invokeStaticMethod(parserBody, config, keyIter);
// continue sweepLoop;
Expand All @@ -711,6 +706,21 @@ private void configSweepLoop(MethodDescriptor parserBody, MethodCreator method,
}
}

private ResultHandle filterProperties(MethodCreator method, ResultHandle config, Set<String> registeredRoots) {
// Roots
ResultHandle rootSet;
rootSet = method.newInstance(HS_NEW);
for (String registeredRoot : registeredRoots) {
method.invokeVirtualMethod(HS_ADD, rootSet, method.load(registeredRoot));
}

// PropertyNames
ResultHandle properties = method.invokeVirtualMethod(SRC_GET_PROPERTY_NAMES, config);

// Filtered Properties
return method.invokeStaticMethod(PU_FILTER_PROPERTIES_IN_ROOTS, properties, rootSet);
}

private Set<String> getRegisteredRoots(ConfigPhase configPhase) {
Set<String> registeredRoots = new HashSet<>();
for (RootDefinition root : roots) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.quarkus.runtime.configuration;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import io.smallrye.config.KeyMap;
Expand Down Expand Up @@ -51,11 +53,55 @@ public static boolean isPropertyInRoot(Set<String> roots, NameIterator propertyN
return false;
}

public static boolean isPropertyQuarkusCompoundName(NameIterator propertyName) {
if (propertyName.hasNext()) {
return propertyName.getNextSegment().startsWith("quarkus.");
public static Iterable<String> filterPropertiesInRoots(final Iterable<String> properties, final Set<String> roots) {
if (roots.isEmpty()) {
return properties;
}
return false;

// Will match everything, so no point in filtering
if (roots.contains("")) {
return properties;
}

List<String> matchedProperties = new ArrayList<>();
for (String property : properties) {
// This is a Quarkus compound name, usually by setting something like `quarkus.foo.bar` in the YAML source
// TODO - We let it through to match it later again to place it in the right unknown reporting (static or runtime). We can improve this too.
if (property.startsWith("\"quarkus.")) {
matchedProperties.add(property);
continue;
}

for (String root : roots) {
// if property is less than the root no way to match
if (property.length() < root.length()) {
continue;
}

// if it is the same, then it can still map with parent name
if (property.equals(root)) {
matchedProperties.add(property);
break;
} else if (property.length() == root.length()) {
continue;
}

// foo.bar
// foo.bar."baz"
// foo.bar[0]
char c = property.charAt(root.length());
if ((c == '.') || c == '[') {
if (property.startsWith(root)) {
matchedProperties.add(property);
}
}
}
}
return matchedProperties;
}

public static boolean isPropertyQuarkusCompoundName(NameIterator propertyName) {
return propertyName.getName().startsWith("\"quarkus.");
}

/**
Expand Down