From b2743cbf22dc4dcdc493f11d6b8c6978c573271e Mon Sep 17 00:00:00 2001 From: Roberto Cortez Date: Tue, 5 Sep 2023 00:07:32 +0100 Subject: [PATCH] Improve matching of config properties to a root (cherry picked from commit e90f074225dd59823a23794ec07e4b6ee900cf31) --- .../RunTimeConfigurationGenerator.java | 28 ++++++---- .../runtime/configuration/PropertiesUtil.java | 54 +++++++++++++++++-- 2 files changed, 69 insertions(+), 13 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/configuration/RunTimeConfigurationGenerator.java b/core/deployment/src/main/java/io/quarkus/deployment/configuration/RunTimeConfigurationGenerator.java index a14c1d0c61470..ea46e31c3a26a 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/configuration/RunTimeConfigurationGenerator.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/configuration/RunTimeConfigurationGenerator.java @@ -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", @@ -668,16 +671,10 @@ public void run() { private void configSweepLoop(MethodDescriptor parserBody, MethodCreator method, ResultHandle config, Set 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()) { @@ -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; @@ -711,6 +706,21 @@ private void configSweepLoop(MethodDescriptor parserBody, MethodCreator method, } } + private ResultHandle filterProperties(MethodCreator method, ResultHandle config, Set 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 getRegisteredRoots(ConfigPhase configPhase) { Set registeredRoots = new HashSet<>(); for (RootDefinition root : roots) { diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/PropertiesUtil.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/PropertiesUtil.java index a1683b240edf4..4a87c6b0f191a 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/PropertiesUtil.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/configuration/PropertiesUtil.java @@ -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; @@ -51,11 +53,55 @@ public static boolean isPropertyInRoot(Set roots, NameIterator propertyN return false; } - public static boolean isPropertyQuarkusCompoundName(NameIterator propertyName) { - if (propertyName.hasNext()) { - return propertyName.getNextSegment().startsWith("quarkus."); + public static Iterable filterPropertiesInRoots(final Iterable properties, final Set roots) { + if (roots.isEmpty()) { + return properties; } - return false; + + // Will match everything, so no point in filtering + if (roots.contains("")) { + return properties; + } + + List 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."); } /**