From 793fdc1fe7958d271ab9d9adadad087d045285e5 Mon Sep 17 00:00:00 2001 From: Roberto Cortez Date: Fri, 11 Aug 2023 12:44:52 +0100 Subject: [PATCH] Use SmallRyeConfigBuilder Customizer to generate Quarkus configuration --- bom/application/pom.xml | 2 +- .../quarkus/deployment/ExtensionLoader.java | 9 - .../builditem/ConfigMappingBuildItem.java | 5 + .../BuildTimeConfigurationReader.java | 1 - .../configuration/ConfigMappingUtils.java | 25 +- .../RunTimeConfigurationGenerator.java | 271 ++----------- .../steps/ConfigGenerationBuildStep.java | 380 +++++++++--------- .../java/io/quarkus/runtime/ConfigConfig.java | 2 - .../configuration/AbstractConfigBuilder.java | 94 +++++ .../ConfigSourceFactoryProvider.java | 7 - .../runtime/configuration/ConfigUtils.java | 171 +------- .../configuration/DefaultsConfigSource.java | 42 -- .../configuration/MappingsConfigBuilder.java | 18 - .../runtime/configuration/PropertiesUtil.java | 4 + .../QuarkusConfigBuilderCustomizer.java | 104 +++++ .../configuration/QuarkusConfigFactory.java | 9 +- .../RuntimeConfigBuilderCustomizer.java | 23 ++ .../configuration/RuntimeConfigSource.java | 27 -- .../RuntimeConfigSourceFactory.java | 25 -- .../RuntimeConfigSourceProvider.java | 27 -- .../RuntimeOverrideConfigSource.java | 5 + .../StaticInitConfigBuilderCustomizer.java | 19 + .../AvailableConfigSourcesTest.java | 2 +- .../RestClientOverrideRuntimeConfigTest.java | 2 +- .../RestClientRunTimeConfigSource.java | 2 +- .../config/ConfigBuilderCustomizer.java | 13 + ...rye.config.SmallRyeConfigBuilderCustomizer | 1 + .../src/main/resources/config.properties | 2 - .../src/main/resources/fallback.properties | 2 - .../main/resources/test-profile.properties | 2 - .../BuildTimeCustomConfigBuilder.java | 15 + ...rye.config.SmallRyeConfigBuilderCustomizer | 1 + .../io/quarkus/config/ConfigBuilderTest.java | 7 + .../RecordedBuildProfileInRuntimeTest.java | 2 +- .../io/quarkus/extest/ConfigMappingTest.java | 2 +- .../io/quarkus/extest/ConfiguredBeanTest.java | 10 +- .../quarkus/extest/RuntimeDefaultsTest.java | 5 +- .../quarkus/extest/StaticInitSourcesTest.java | 8 +- .../config/EnvBuildTimeConfigSource.java | 3 +- ...ticInitNotSafeConfigBuilderCustomizer.java | 11 + ...StaticInitSafeConfigBuilderCustomizer.java | 17 + .../test/common/TestResourceManager.java | 7 +- 42 files changed, 605 insertions(+), 779 deletions(-) create mode 100644 core/runtime/src/main/java/io/quarkus/runtime/configuration/AbstractConfigBuilder.java delete mode 100644 core/runtime/src/main/java/io/quarkus/runtime/configuration/ConfigSourceFactoryProvider.java delete mode 100644 core/runtime/src/main/java/io/quarkus/runtime/configuration/DefaultsConfigSource.java delete mode 100644 core/runtime/src/main/java/io/quarkus/runtime/configuration/MappingsConfigBuilder.java create mode 100644 core/runtime/src/main/java/io/quarkus/runtime/configuration/QuarkusConfigBuilderCustomizer.java create mode 100644 core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigBuilderCustomizer.java delete mode 100644 core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigSource.java delete mode 100644 core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigSourceFactory.java delete mode 100644 core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigSourceProvider.java create mode 100644 core/runtime/src/main/java/io/quarkus/runtime/configuration/StaticInitConfigBuilderCustomizer.java create mode 100644 integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/ConfigBuilderCustomizer.java create mode 100644 integration-tests/smallrye-config/src/main/resources/META-INF/services/io.smallrye.config.SmallRyeConfigBuilderCustomizer create mode 100644 integration-tests/test-extension/extension/deployment/src/main/java/io/quarkus/extest/deployment/BuildTimeCustomConfigBuilder.java create mode 100644 integration-tests/test-extension/extension/deployment/src/main/resources/META-INF/services/io.smallrye.config.SmallRyeConfigBuilderCustomizer create mode 100644 integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/StaticInitNotSafeConfigBuilderCustomizer.java create mode 100644 integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/StaticInitSafeConfigBuilderCustomizer.java diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 83a4d773d47546..c952ca8629700b 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -51,7 +51,7 @@ 2.0 3.1.1 2.1.2 - 3.3.4 + 3.4.0 4.0.4 4.0.0 3.5.2 diff --git a/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java b/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java index b51b14c0481d2e..d4076b42abab70 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java @@ -47,7 +47,6 @@ import org.eclipse.microprofile.config.Config; import org.eclipse.microprofile.config.ConfigProvider; -import org.eclipse.microprofile.config.spi.ConfigProviderResolver; import org.jboss.logging.Logger; import org.wildfly.common.function.Functions; @@ -136,16 +135,8 @@ public static Consumer loadStepsFrom(ClassLoader classLoader, final BuildTimeConfigurationReader reader = new BuildTimeConfigurationReader(classLoader); final SmallRyeConfig src = reader.initConfiguration(launchMode, buildSystemProps, appModel.getPlatformProperties()); - // install globally QuarkusConfigFactory.setConfig(src); - final ConfigProviderResolver cpr = ConfigProviderResolver.instance(); - try { - cpr.releaseConfig(cpr.getConfig()); - } catch (IllegalStateException ignored) { - // just means no config was installed, which is fine - } - final BuildTimeConfigurationReader.ReadResult readResult = reader.readConfiguration(src); final BooleanSupplierFactoryBuildItem bsf = new BooleanSupplierFactoryBuildItem(readResult, launchMode, devModeType); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/ConfigMappingBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/ConfigMappingBuildItem.java index 78639aaccc7188..45274f49eb20a3 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/ConfigMappingBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/ConfigMappingBuildItem.java @@ -4,6 +4,7 @@ import io.quarkus.builder.item.MultiBuildItem; import io.quarkus.runtime.annotations.StaticInitSafe; +import io.smallrye.config.ConfigMappings.ConfigClassWithPrefix; public final class ConfigMappingBuildItem extends MultiBuildItem { private final Class configClass; @@ -26,6 +27,10 @@ public boolean isStaticInitSafe() { return configClass.isAnnotationPresent(StaticInitSafe.class); } + public ConfigClassWithPrefix toConfigClassWithPrefix() { + return new ConfigClassWithPrefix(configClass, prefix); + } + @Override public boolean equals(final Object o) { if (this == o) { diff --git a/core/deployment/src/main/java/io/quarkus/deployment/configuration/BuildTimeConfigurationReader.java b/core/deployment/src/main/java/io/quarkus/deployment/configuration/BuildTimeConfigurationReader.java index 326fd9c0b924aa..135683c96111c8 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/configuration/BuildTimeConfigurationReader.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/configuration/BuildTimeConfigurationReader.java @@ -470,7 +470,6 @@ final class ReadOperation { final SmallRyeConfig config; final ConfigTrackingInterceptor buildConfigTracker; final Set processedNames = new HashSet<>(); - final Map, Object> objectsByClass = new HashMap<>(); final Map allBuildTimeValues = new TreeMap<>(); final Map buildTimeRunTimeValues = new TreeMap<>(); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/configuration/ConfigMappingUtils.java b/core/deployment/src/main/java/io/quarkus/deployment/configuration/ConfigMappingUtils.java index 65a31c9132ad31..3617c0a0a1b319 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/configuration/ConfigMappingUtils.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/configuration/ConfigMappingUtils.java @@ -1,5 +1,6 @@ package io.quarkus.deployment.configuration; +import static io.smallrye.config.ConfigMappings.ConfigClassWithPrefix.configClassWithPrefix; import static org.jboss.jandex.AnnotationTarget.Kind.CLASS; import java.util.ArrayList; @@ -32,6 +33,7 @@ import io.smallrye.config.ConfigMappingInterface.Property; import io.smallrye.config.ConfigMappingLoader; import io.smallrye.config.ConfigMappingMetadata; +import io.smallrye.config.ConfigMappings.ConfigClassWithPrefix; public class ConfigMappingUtils { @@ -58,33 +60,42 @@ public static void processConfigClasses( Class configClass = toClass(target.asClass().name()); String prefix = Optional.ofNullable(annotationPrefix).map(AnnotationValue::asString).orElse(""); Kind configClassKind = getConfigClassType(instance); - processConfigClass(configClass, configClassKind, prefix, true, combinedIndex, generatedClasses, reflectiveClasses, - configClasses); + processConfigClass(configClassWithPrefix(configClass, prefix), configClassKind, true, combinedIndex, + generatedClasses, reflectiveClasses, configClasses); } } + public static void processConfigMapping( + CombinedIndexBuildItem combinedIndex, + BuildProducer generatedClasses, + BuildProducer reflectiveClasses, + BuildProducer configClasses) { + processConfigClasses(combinedIndex, generatedClasses, reflectiveClasses, configClasses, CONFIG_MAPPING_NAME); + } + public static void processExtensionConfigMapping( - Class configClass, - String prefix, + ConfigClassWithPrefix configClass, CombinedIndexBuildItem combinedIndex, BuildProducer generatedClasses, BuildProducer reflectiveClasses, BuildProducer configClasses) { - processConfigClass(configClass, Kind.MAPPING, prefix, false, combinedIndex, generatedClasses, reflectiveClasses, + processConfigClass(configClass, Kind.MAPPING, false, combinedIndex, generatedClasses, reflectiveClasses, configClasses); } private static void processConfigClass( - Class configClass, + ConfigClassWithPrefix configClassWithPrefix, Kind configClassKind, - String prefix, boolean isApplicationClass, CombinedIndexBuildItem combinedIndex, BuildProducer generatedClasses, BuildProducer reflectiveClasses, BuildProducer configClasses) { + Class configClass = configClassWithPrefix.getKlass(); + String prefix = configClassWithPrefix.getPrefix(); + List configMappingsMetadata = ConfigMappingLoader.getConfigMappingsMetadata(configClass); Set generatedClassesNames = new HashSet<>(); configMappingsMetadata.forEach(mappingMetadata -> { 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 ea46e31c3a26ac..ed60fa5b259847 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 @@ -6,8 +6,6 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -26,7 +24,6 @@ import org.eclipse.microprofile.config.spi.ConfigBuilder; import org.eclipse.microprofile.config.spi.ConfigProviderResolver; import org.eclipse.microprofile.config.spi.ConfigSource; -import org.eclipse.microprofile.config.spi.ConfigSourceProvider; import org.eclipse.microprofile.config.spi.Converter; import org.objectweb.asm.Opcodes; import org.wildfly.common.Assert; @@ -61,18 +58,16 @@ import io.quarkus.gizmo.TryBlock; import io.quarkus.runtime.LaunchMode; import io.quarkus.runtime.annotations.ConfigPhase; +import io.quarkus.runtime.configuration.AbstractConfigBuilder; import io.quarkus.runtime.configuration.AbstractRawDefaultConfigSource; import io.quarkus.runtime.configuration.ConfigDiagnostic; -import io.quarkus.runtime.configuration.ConfigSourceFactoryProvider; import io.quarkus.runtime.configuration.ConfigUtils; import io.quarkus.runtime.configuration.ConfigurationException; import io.quarkus.runtime.configuration.HyphenateEnumConverter; import io.quarkus.runtime.configuration.NameIterator; import io.quarkus.runtime.configuration.PropertiesUtil; import io.quarkus.runtime.configuration.QuarkusConfigFactory; -import io.quarkus.runtime.configuration.RuntimeConfigSource; -import io.quarkus.runtime.configuration.RuntimeConfigSourceFactory; -import io.quarkus.runtime.configuration.RuntimeConfigSourceProvider; +import io.quarkus.runtime.configuration.RuntimeOverrideConfigSource; import io.smallrye.config.ConfigMappings; import io.smallrye.config.ConfigMappings.ConfigClassWithPrefix; import io.smallrye.config.Converters; @@ -86,6 +81,8 @@ public final class RunTimeConfigurationGenerator { public static final String CONFIG_CLASS_NAME = "io.quarkus.runtime.generated.Config"; + public static final String CONFIG_BUILDER_STATIC_NAME = "io.quarkus.runtime.generated.StaticInitConfigBuilder"; + public static final String CONFIG_BUILDER_RUNTIME_NAME = "io.quarkus.runtime.generated.RunTimeConfigBuilder"; static final String RTDVCS_CLASS_NAME = "io.quarkus.runtime.generated.RunTimeDefaultValuesConfigSource"; public static final MethodDescriptor C_CREATE_RUN_TIME_CONFIG = MethodDescriptor.ofMethod(CONFIG_CLASS_NAME, @@ -145,28 +142,6 @@ public final class RunTimeConfigurationGenerator { IntFunction.class); static final MethodDescriptor CU_SORTED_SET_FACTORY = MethodDescriptor.ofMethod(ConfigUtils.class, "sortedSetFactory", IntFunction.class); - static final MethodDescriptor CU_CONFIG_BUILDER = MethodDescriptor.ofMethod(ConfigUtils.class, "configBuilder", - SmallRyeConfigBuilder.class, boolean.class, LaunchMode.class); - static final MethodDescriptor CU_CONFIG_BUILDER_WITH_ADD_DISCOVERED = MethodDescriptor.ofMethod(ConfigUtils.class, - "configBuilder", - SmallRyeConfigBuilder.class, boolean.class, boolean.class, LaunchMode.class); - static final MethodDescriptor CU_CONFIG_BUILDER_LIST = MethodDescriptor.ofMethod(ConfigUtils.class, "configBuilder", - SmallRyeConfigBuilder.class, SmallRyeConfigBuilder.class, List.class); - static final MethodDescriptor CU_ADD_SOURCE_PROVIDER = MethodDescriptor.ofMethod(ConfigUtils.class, "addSourceProvider", - void.class, SmallRyeConfigBuilder.class, ConfigSourceProvider.class); - static final MethodDescriptor CU_ADD_SOURCE_PROVIDERS = MethodDescriptor.ofMethod(ConfigUtils.class, "addSourceProviders", - void.class, SmallRyeConfigBuilder.class, Collection.class); - static final MethodDescriptor CU_ADD_SOURCE_FACTORY_PROVIDER = MethodDescriptor.ofMethod(ConfigUtils.class, - "addSourceFactoryProvider", - void.class, SmallRyeConfigBuilder.class, ConfigSourceFactoryProvider.class); - - static final MethodDescriptor RCS_NEW = MethodDescriptor.ofConstructor(RuntimeConfigSource.class, String.class); - static final MethodDescriptor RCSP_NEW = MethodDescriptor.ofConstructor(RuntimeConfigSourceProvider.class, String.class); - static final MethodDescriptor RCSF_NEW = MethodDescriptor.ofConstructor(RuntimeConfigSourceFactory.class, String.class); - - static final MethodDescriptor AL_NEW = MethodDescriptor.ofConstructor(ArrayList.class); - static final MethodDescriptor AL_ADD = MethodDescriptor.ofMethod(ArrayList.class, "add", boolean.class, Object.class); - static final MethodDescriptor ITRA_ITERATOR = MethodDescriptor.ofMethod(Iterable.class, "iterator", Iterator.class); static final MethodDescriptor ITR_HAS_NEXT = MethodDescriptor.ofMethod(Iterator.class, "hasNext", boolean.class); @@ -218,15 +193,17 @@ public final class RunTimeConfigurationGenerator { static final MethodDescriptor SRC_GET_VALUE = MethodDescriptor.ofMethod(SmallRyeConfig.class, "getValue", Object.class, String.class, Converter.class); + static final MethodDescriptor SRCB_NEW = MethodDescriptor.ofConstructor(SmallRyeConfigBuilder.class); + static final MethodDescriptor SRCB_WITH_CONVERTER = MethodDescriptor.ofMethod(SmallRyeConfigBuilder.class, "withConverter", ConfigBuilder.class, Class.class, int.class, Converter.class); static final MethodDescriptor SRCB_WITH_SOURCES = MethodDescriptor.ofMethod(SmallRyeConfigBuilder.class, "withSources", ConfigBuilder.class, ConfigSource[].class); + static final MethodDescriptor SRCB_WITH_CUSTOMIZER = MethodDescriptor.ofMethod(AbstractConfigBuilder.class, + "withCustomizer", void.class, SmallRyeConfigBuilder.class, String.class); static final MethodDescriptor SRCB_BUILD = MethodDescriptor.ofMethod(SmallRyeConfigBuilder.class, "build", SmallRyeConfig.class); - 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); @@ -272,16 +249,6 @@ public static final class GenerateOperation implements AutoCloseable { final ResultHandle clinitConfig; final Map> convertersToRegister = new HashMap<>(); final List> additionalTypes; - final Set staticConfigSources; - final Set staticConfigSourceProviders; - final Set staticConfigSourceFactories; - final Set staticConfigBuilders; - final Set runtimeConfigSources; - final Set runtimeConfigSourceProviders; - final Set runtimeConfigSourceFactories; - final Set staticConfigMappings; - final Set runtimeConfigMappings; - final Set runtimeConfigBuilders; /** * Regular converters organized by type. Each converter is stored in a separate field. Some are used * only at build time, some only at run time, and some at both times. @@ -312,16 +279,6 @@ public static final class GenerateOperation implements AutoCloseable { classOutput = Assert.checkNotNullParam("classOutput", builder.getClassOutput()); roots = Assert.checkNotNullParam("builder.roots", builder.getBuildTimeReadResult().getAllRoots()); additionalTypes = Assert.checkNotNullParam("additionalTypes", builder.getAdditionalTypes()); - staticConfigSources = builder.getStaticConfigSources(); - staticConfigSourceProviders = builder.getStaticConfigSourceProviders(); - staticConfigSourceFactories = builder.getStaticConfigSourceFactories(); - staticConfigBuilders = builder.getStaticConfigBuilders(); - runtimeConfigSources = builder.getRuntimeConfigSources(); - runtimeConfigSourceProviders = builder.getRuntimeConfigSourceProviders(); - runtimeConfigSourceFactories = builder.getRuntimeConfigSourceFactories(); - staticConfigMappings = builder.getStaticConfigMappings(); - runtimeConfigMappings = builder.getRuntimeConfigMappings(); - runtimeConfigBuilders = builder.getRuntimeConfigBuilders(); cc = ClassCreator.builder().classOutput(classOutput).className(CONFIG_CLASS_NAME).setFinal(true).build(); generateEmptyParsers(); generateUnknownFilter(); @@ -356,34 +313,12 @@ public static final class GenerateOperation implements AutoCloseable { clinit.writeStaticField(C_RUN_TIME_DEFAULTS_CONFIG_SOURCE, clinit.newInstance(RTDVCS_NEW)); // the build time config, which is for user use only (not used by us other than for loading converters) - final ResultHandle buildTimeBuilder = clinit.invokeStaticMethod(CU_CONFIG_BUILDER_WITH_ADD_DISCOVERED, - clinit.load(true), clinit.load(false), clinit.load(launchMode)); - - // add safe static sources - for (String runtimeConfigSource : staticConfigSources) { - clinit.invokeStaticMethod(CU_ADD_SOURCE_PROVIDER, buildTimeBuilder, - clinit.newInstance(RCS_NEW, clinit.load(runtimeConfigSource))); - } - // add safe static source providers - for (String runtimeConfigSourceProvider : staticConfigSourceProviders) { - clinit.invokeStaticMethod(CU_ADD_SOURCE_PROVIDER, buildTimeBuilder, - clinit.newInstance(RCSP_NEW, clinit.load(runtimeConfigSourceProvider))); - } - // add safe static source factories - for (String discoveredConfigSourceFactory : staticConfigSourceFactories) { - clinit.invokeStaticMethod(CU_ADD_SOURCE_FACTORY_PROVIDER, buildTimeBuilder, - clinit.newInstance(RCSF_NEW, clinit.load(discoveredConfigSourceFactory))); - } + final ResultHandle buildTimeBuilder = clinit.newInstance(SRCB_NEW); - // additional config builders - ResultHandle configBuilders = clinit.newInstance(AL_NEW); - for (String configBuilder : staticConfigBuilders) { - clinit.invokeVirtualMethod(AL_ADD, configBuilders, clinit.load(configBuilder)); - } - clinit.invokeStaticMethod(CU_CONFIG_BUILDER_LIST, buildTimeBuilder, configBuilders); + // static config builder + clinit.invokeStaticMethod(SRCB_WITH_CUSTOMIZER, buildTimeBuilder, clinit.load(CONFIG_BUILDER_STATIC_NAME)); - clinitConfig = clinit.checkCast(clinit.invokeVirtualMethod(SRCB_BUILD, buildTimeBuilder), - SmallRyeConfig.class); + clinitConfig = clinit.checkCast(clinit.invokeVirtualMethod(SRCB_BUILD, buildTimeBuilder), SmallRyeConfig.class); // block for converter setup converterSetup = clinit.createScope(); @@ -403,29 +338,9 @@ public void run() { installConfiguration(clinitConfig, clinit); if (liveReloadPossible) { // the build time config, which is for user use only (not used by us other than for loading converters) - final ResultHandle buildTimeBuilder = reinit.invokeStaticMethod(CU_CONFIG_BUILDER, reinit.load(true), - reinit.load(launchMode)); - // add safe static sources - for (String runtimeConfigSource : staticConfigSources) { - reinit.invokeStaticMethod(CU_ADD_SOURCE_PROVIDER, buildTimeBuilder, - reinit.newInstance(RCS_NEW, reinit.load(runtimeConfigSource))); - } - // add safe static source providers - for (String runtimeConfigSourceProvider : staticConfigSourceProviders) { - reinit.invokeStaticMethod(CU_ADD_SOURCE_PROVIDER, buildTimeBuilder, - reinit.newInstance(RCSP_NEW, reinit.load(runtimeConfigSourceProvider))); - } - // add safe static source factories - for (String discoveredConfigSourceFactory : staticConfigSourceFactories) { - reinit.invokeStaticMethod(CU_ADD_SOURCE_FACTORY_PROVIDER, buildTimeBuilder, - reinit.newInstance(RCSF_NEW, reinit.load(discoveredConfigSourceFactory))); - } - // additional config builders - ResultHandle configBuilders = reinit.newInstance(AL_NEW); - for (String configBuilder : staticConfigBuilders) { - reinit.invokeVirtualMethod(AL_ADD, configBuilders, reinit.load(configBuilder)); - } - reinit.invokeStaticMethod(CU_CONFIG_BUILDER_LIST, buildTimeBuilder, configBuilders); + final ResultHandle buildTimeBuilder = reinit.newInstance(SRCB_NEW); + // static config builder + reinit.invokeStaticMethod(SRCB_WITH_CUSTOMIZER, buildTimeBuilder, reinit.load(CONFIG_BUILDER_STATIC_NAME)); ResultHandle clinitConfig = reinit.checkCast(reinit.invokeVirtualMethod(SRCB_BUILD, buildTimeBuilder), SmallRyeConfig.class); @@ -457,16 +372,7 @@ public void run() { new StringBuilder("rtParseKey"), false, Type.RUNTIME); // create the run time config - final ResultHandle runTimeBuilder = readConfig.invokeStaticMethod( - CU_CONFIG_BUILDER_WITH_ADD_DISCOVERED, readConfig.load(true), - readConfig.load(false), - readConfig.load(launchMode)); - - // add in our custom sources - final ResultHandle runtimeConfigSourcesArray = readConfig.newArray(ConfigSource[].class, 1); - // run time config default values - readConfig.writeArrayValue(runtimeConfigSourcesArray, 0, - readConfig.readStaticField(C_RUN_TIME_DEFAULTS_CONFIG_SOURCE)); + final ResultHandle runTimeBuilder = readConfig.newInstance(SRCB_NEW); // add in known converters for (Class additionalType : additionalTypes) { @@ -493,33 +399,21 @@ public void run() { } } - // put sources in the builder - readConfig.invokeVirtualMethod(SRCB_WITH_SOURCES, runTimeBuilder, runtimeConfigSourcesArray); + // runtime config builder + readConfig.invokeStaticMethod(SRCB_WITH_CUSTOMIZER, runTimeBuilder, readConfig.load(CONFIG_BUILDER_RUNTIME_NAME)); - // add discovered sources - for (String runtimeConfigSource : runtimeConfigSources) { - readConfig.invokeStaticMethod(CU_ADD_SOURCE_PROVIDER, runTimeBuilder, - readConfig.newInstance(RCS_NEW, readConfig.load(runtimeConfigSource))); - } - - // add discovered source providers - for (String runtimeConfigSourceProvider : runtimeConfigSourceProviders) { - readConfig.invokeStaticMethod(CU_ADD_SOURCE_PROVIDER, runTimeBuilder, - readConfig.newInstance(RCSP_NEW, readConfig.load(runtimeConfigSourceProvider))); - } - - // add discovered source factories - for (String discoveredConfigSourceFactory : runtimeConfigSourceFactories) { - readConfig.invokeStaticMethod(CU_ADD_SOURCE_FACTORY_PROVIDER, runTimeBuilder, - readConfig.newInstance(RCSF_NEW, readConfig.load(discoveredConfigSourceFactory))); - } - - // additional config builders - ResultHandle configBuilders = readConfig.newInstance(AL_NEW); - for (String configBuilder : runtimeConfigBuilders) { - readConfig.invokeVirtualMethod(AL_ADD, configBuilders, readConfig.load(configBuilder)); + // add in our custom sources + final ResultHandle runtimeConfigSourcesArray = readConfig.newArray(ConfigSource[].class, 1); + // run time config default values for roots + readConfig.writeArrayValue(runtimeConfigSourcesArray, 0, + readConfig.readStaticField(C_RUN_TIME_DEFAULTS_CONFIG_SOURCE)); + if (launchMode.isDevOrTest()) { + MethodDescriptor registerRuntimeOverrideConfigSource = MethodDescriptor.ofMethod( + RuntimeOverrideConfigSource.class, "registerRuntimeOverrideConfigSource", void.class, + SmallRyeConfigBuilder.class); + readConfig.invokeStaticMethod(registerRuntimeOverrideConfigSource, runTimeBuilder); } - readConfig.invokeStaticMethod(CU_CONFIG_BUILDER_LIST, runTimeBuilder, configBuilders); + readConfig.invokeVirtualMethod(SRCB_WITH_SOURCES, runTimeBuilder, runtimeConfigSourcesArray); final ResultHandle runTimeConfig = readConfig.invokeVirtualMethod(SRCB_BUILD, runTimeBuilder); installConfiguration(runTimeConfig, readConfig); @@ -1512,13 +1406,13 @@ private void reportUnknown(final MethodCreator mc) { private void generateUnknownFilter() { Set mappedProperties = new HashSet<>(); - for (ConfigClassWithPrefix buildTimeMapping : buildTimeConfigResult.buildTimeMappings) { + for (ConfigClassWithPrefix buildTimeMapping : buildTimeConfigResult.getBuildTimeMappings()) { mappedProperties.addAll(ConfigMappings.getProperties(buildTimeMapping).keySet()); } - for (ConfigClassWithPrefix staticConfigMapping : staticConfigMappings) { + for (ConfigClassWithPrefix staticConfigMapping : buildTimeConfigResult.getBuildTimeRunTimeMappings()) { mappedProperties.addAll(ConfigMappings.getProperties(staticConfigMapping).keySet()); } - for (ConfigClassWithPrefix runtimeConfigMapping : runtimeConfigMappings) { + for (ConfigClassWithPrefix runtimeConfigMapping : buildTimeConfigResult.getRunTimeMappings()) { mappedProperties.addAll(ConfigMappings.getProperties(runtimeConfigMapping).keySet()); } @@ -1572,17 +1466,6 @@ public static final class Builder { private ClassOutput classOutput; private BuildTimeConfigurationReader.ReadResult buildTimeReadResult; private List> additionalTypes; - private Set staticConfigSources; - private Set staticConfigSourceProviders; - private Set staticConfigSourceFactories; - private Set staticConfigBuilders; - private Set runtimeConfigSources; - private Set runtimeConfigSourceProviders; - private Set runtimeConfigSourceFactories; - private Set runtimeConfigBuilders; - - private Set staticConfigMappings; - private Set runtimeConfigMappings; Builder() { } @@ -1628,96 +1511,6 @@ public Builder setLaunchMode(LaunchMode launchMode) { return this; } - Set getStaticConfigSources() { - return staticConfigSources; - } - - public Builder setStaticConfigSources(final Set staticConfigSources) { - this.staticConfigSources = staticConfigSources; - return this; - } - - Set getStaticConfigSourceProviders() { - return staticConfigSourceProviders; - } - - public Builder setStaticConfigSourceProviders(final Set staticConfigSourceProviders) { - this.staticConfigSourceProviders = staticConfigSourceProviders; - return this; - } - - Set getStaticConfigSourceFactories() { - return staticConfigSourceFactories; - } - - public Builder setStaticConfigSourceFactories(final Set staticConfigSourceFactories) { - this.staticConfigSourceFactories = staticConfigSourceFactories; - return this; - } - - Set getStaticConfigBuilders() { - return staticConfigBuilders; - } - - public Builder setStaticConfigBuilders(final Set staticConfigBuilders) { - this.staticConfigBuilders = staticConfigBuilders; - return this; - } - - Set getRuntimeConfigSources() { - return runtimeConfigSources; - } - - public Builder setRuntimeConfigSources(final Set runtimeConfigSources) { - this.runtimeConfigSources = runtimeConfigSources; - return this; - } - - Set getRuntimeConfigSourceProviders() { - return runtimeConfigSourceProviders; - } - - public Builder setRuntimeConfigSourceProviders(final Set runtimeConfigSourceProviders) { - this.runtimeConfigSourceProviders = runtimeConfigSourceProviders; - return this; - } - - Set getRuntimeConfigSourceFactories() { - return runtimeConfigSourceFactories; - } - - public Builder setRuntimeConfigSourceFactories(final Set runtimeConfigSourceFactories) { - this.runtimeConfigSourceFactories = runtimeConfigSourceFactories; - return this; - } - - Set getStaticConfigMappings() { - return staticConfigMappings; - } - - public Builder setStaticConfigMappings(final Set staticConfigMappings) { - this.staticConfigMappings = staticConfigMappings; - return this; - } - - Set getRuntimeConfigMappings() { - return runtimeConfigMappings; - } - - public Builder setRuntimeConfigMappings(final Set runtimeConfigMappings) { - this.runtimeConfigMappings = runtimeConfigMappings; - return this; - } - - Set getRuntimeConfigBuilders() { - return runtimeConfigBuilders; - } - - public Builder setRuntimeConfigBuilders(final Set runtimeConfigBuilders) { - this.runtimeConfigBuilders = runtimeConfigBuilders; - return this; - } - public GenerateOperation build() { return new GenerateOperation(this); } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigGenerationBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigGenerationBuildStep.java index 743582f056a7d6..dcb8e5fdcbba1f 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigGenerationBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigGenerationBuildStep.java @@ -1,11 +1,11 @@ package io.quarkus.deployment.steps; -import static io.quarkus.deployment.configuration.ConfigMappingUtils.CONFIG_MAPPING_NAME; -import static io.quarkus.deployment.configuration.ConfigMappingUtils.processConfigClasses; +import static io.quarkus.deployment.configuration.ConfigMappingUtils.processConfigMapping; import static io.quarkus.deployment.configuration.ConfigMappingUtils.processExtensionConfigMapping; +import static io.quarkus.deployment.configuration.RunTimeConfigurationGenerator.CONFIG_BUILDER_RUNTIME_NAME; +import static io.quarkus.deployment.configuration.RunTimeConfigurationGenerator.CONFIG_BUILDER_STATIC_NAME; import static io.quarkus.deployment.steps.ConfigBuildSteps.SERVICES_PREFIX; import static io.quarkus.deployment.util.ServiceUtil.classNamesNamedIn; -import static io.smallrye.config.ConfigMappings.ConfigClassWithPrefix.configClassWithPrefix; import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_LOCATIONS; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; @@ -32,8 +32,10 @@ import org.eclipse.microprofile.config.ConfigValue; import org.eclipse.microprofile.config.spi.ConfigSource; import org.eclipse.microprofile.config.spi.ConfigSourceProvider; +import org.eclipse.microprofile.config.spi.Converter; import org.objectweb.asm.Opcodes; +import io.quarkus.bootstrap.classloading.QuarkusClassLoader; import io.quarkus.deployment.GeneratedClassGizmoAdaptor; import io.quarkus.deployment.IsNormal; import io.quarkus.deployment.annotations.BuildProducer; @@ -71,18 +73,25 @@ import io.quarkus.gizmo.ResultHandle; import io.quarkus.runtime.LaunchMode; import io.quarkus.runtime.annotations.StaticInitSafe; +import io.quarkus.runtime.configuration.AbstractConfigBuilder; import io.quarkus.runtime.configuration.ConfigBuilder; import io.quarkus.runtime.configuration.ConfigDiagnostic; import io.quarkus.runtime.configuration.ConfigRecorder; -import io.quarkus.runtime.configuration.DefaultsConfigSource; import io.quarkus.runtime.configuration.DisableableConfigSource; -import io.quarkus.runtime.configuration.MappingsConfigBuilder; import io.quarkus.runtime.configuration.QuarkusConfigValue; +import io.quarkus.runtime.configuration.RuntimeConfigBuilderCustomizer; import io.quarkus.runtime.configuration.RuntimeOverrideConfigSource; +import io.quarkus.runtime.configuration.StaticInitConfigBuilderCustomizer; import io.smallrye.config.ConfigMappings.ConfigClassWithPrefix; import io.smallrye.config.ConfigSourceFactory; +import io.smallrye.config.ConfigSourceInterceptor; +import io.smallrye.config.ConfigSourceInterceptorFactory; +import io.smallrye.config.DefaultValuesConfigSource; +import io.smallrye.config.SecretKeysHandler; +import io.smallrye.config.SecretKeysHandlerFactory; import io.smallrye.config.SmallRyeConfig; import io.smallrye.config.SmallRyeConfigBuilder; +import io.smallrye.config.SmallRyeConfigBuilderCustomizer; public class ConfigGenerationBuildStep { private static final MethodDescriptor CONFIG_BUILDER = MethodDescriptor.ofMethod( @@ -100,11 +109,7 @@ void buildTimeRunTimeConfig( BuildProducer staticInitConfigBuilder, BuildProducer runTimeConfigBuilder) { - String className = "io.quarkus.runtime.generated.BuildTimeRunTimeFixedConfigSource"; - generateDefaultsConfigSource(generatedClass, reflectiveClass, configItem.getReadResult().getBuildTimeRunTimeValues(), - className, "BuildTime RunTime Fixed", Integer.MAX_VALUE); - - String builderClassName = className + "Builder"; + String builderClassName = "io.quarkus.runtime.generated.BuildTimeRunTimeFixedConfigSourceBuilder"; try (ClassCreator classCreator = ClassCreator.builder() .classOutput(new GeneratedClassGizmoAdaptor(generatedClass, true)) .className(builderClassName) @@ -117,10 +122,20 @@ void buildTimeRunTimeConfig( MethodCreator clinit = classCreator.getMethodCreator("", void.class); clinit.setModifiers(Opcodes.ACC_STATIC); - ResultHandle buildTimeRunTimeConfigSource = clinit.newInstance(MethodDescriptor.ofConstructor(className)); + + ResultHandle map = clinit.newInstance(MethodDescriptor.ofConstructor(HashMap.class)); + MethodDescriptor put = MethodDescriptor.ofMethod(Map.class, "put", Object.class, Object.class, Object.class); + for (Map.Entry entry : configItem.getReadResult().getBuildTimeRunTimeValues().entrySet()) { + clinit.invokeInterfaceMethod(put, map, clinit.load(entry.getKey()), clinit.load(entry.getValue())); + } + + ResultHandle defaultValuesSource = clinit.newInstance( + MethodDescriptor.ofConstructor(DefaultValuesConfigSource.class, Map.class, String.class, int.class), map, + clinit.load("BuildTime RunTime Fixed"), clinit.load(Integer.MAX_VALUE)); + ResultHandle disableableConfigSource = clinit.newInstance( MethodDescriptor.ofConstructor(DisableableConfigSource.class, ConfigSource.class), - buildTimeRunTimeConfigSource); + defaultValuesSource); clinit.writeStaticField(source, disableableConfigSource); clinit.returnVoid(); @@ -135,120 +150,104 @@ void buildTimeRunTimeConfig( method.returnValue(configBuilder); } - reflectiveClass.produce( - ReflectiveClassBuildItem.builder(builderClassName).build()); + reflectiveClass.produce(ReflectiveClassBuildItem.builder(builderClassName).build()); staticInitConfigBuilder.produce(new StaticInitConfigBuilderBuildItem(builderClassName)); runTimeConfigBuilder.produce(new RunTimeConfigBuilderBuildItem(builderClassName)); } @BuildStep - void runtimeDefaultsConfig( + void generateMappings( ConfigurationBuildItem configItem, - List runTimeDefaults, - BuildProducer generatedClass, - BuildProducer reflectiveClass, - BuildProducer staticInitConfigBuilder, - BuildProducer runTimeConfigBuilder) { - - Map defaults = new HashMap<>(); - for (RunTimeConfigurationDefaultBuildItem e : runTimeDefaults) { - defaults.put(e.getKey(), e.getValue()); - } - defaults.putAll(configItem.getReadResult().getRunTimeDefaultValues()); - - String className = "io.quarkus.runtime.generated.RunTimeDefaultsConfigSource"; - generateDefaultsConfigSource(generatedClass, reflectiveClass, defaults, - className, "RunTime Defaults", Integer.MIN_VALUE + 100); - - String builderClassName = className + "Builder"; - try (ClassCreator classCreator = ClassCreator.builder() - .classOutput(new GeneratedClassGizmoAdaptor(generatedClass, true)) - .className(builderClassName) - .interfaces(ConfigBuilder.class) - .setFinal(true) - .build()) { - - FieldDescriptor source = FieldDescriptor.of(classCreator.getClassName(), "source", ConfigSource.class); - classCreator.getFieldCreator(source).setModifiers(Opcodes.ACC_STATIC | Opcodes.ACC_FINAL); - - MethodCreator clinit = classCreator.getMethodCreator("", void.class); - clinit.setModifiers(Opcodes.ACC_STATIC); - ResultHandle runtimeDefaultsConfigSource = clinit.newInstance(MethodDescriptor.ofConstructor(className)); - clinit.writeStaticField(source, runtimeDefaultsConfigSource); - clinit.returnVoid(); - - MethodCreator method = classCreator.getMethodCreator(CONFIG_BUILDER); - ResultHandle configBuilder = method.getMethodParam(0); - - ResultHandle configSources = method.newArray(ConfigSource.class, 1); - method.writeArrayValue(configSources, 0, method.readStaticField(source)); - - method.invokeVirtualMethod(WITH_SOURCES, configBuilder, configSources); - - method.returnValue(configBuilder); - } - - reflectiveClass.produce( - ReflectiveClassBuildItem.builder(builderClassName).build()); - staticInitConfigBuilder.produce(new StaticInitConfigBuilderBuildItem(builderClassName)); - runTimeConfigBuilder.produce(new RunTimeConfigBuilderBuildItem(builderClassName)); - } - - @BuildStep - void mappings( CombinedIndexBuildItem combinedIndex, BuildProducer generatedClasses, BuildProducer reflectiveClasses, BuildProducer configClasses) { - processConfigClasses(combinedIndex, generatedClasses, reflectiveClasses, configClasses, CONFIG_MAPPING_NAME); - } - - @BuildStep - void extensionMappings(ConfigurationBuildItem configItem, - CombinedIndexBuildItem combinedIndex, - BuildProducer generatedClasses, - BuildProducer reflectiveClasses, - BuildProducer configClasses) { + processConfigMapping(combinedIndex, generatedClasses, reflectiveClasses, configClasses); List buildTimeRunTimeMappings = configItem.getReadResult().getBuildTimeRunTimeMappings(); for (ConfigClassWithPrefix buildTimeRunTimeMapping : buildTimeRunTimeMappings) { - processExtensionConfigMapping(buildTimeRunTimeMapping.getKlass(), buildTimeRunTimeMapping.getPrefix(), - combinedIndex, generatedClasses, reflectiveClasses, configClasses); + processExtensionConfigMapping(buildTimeRunTimeMapping, combinedIndex, generatedClasses, reflectiveClasses, + configClasses); } - final List runTimeMappings = configItem.getReadResult().getRunTimeMappings(); + List runTimeMappings = configItem.getReadResult().getRunTimeMappings(); for (ConfigClassWithPrefix runTimeMapping : runTimeMappings) { - processExtensionConfigMapping(runTimeMapping.getKlass(), runTimeMapping.getPrefix(), combinedIndex, - generatedClasses, reflectiveClasses, configClasses); + processExtensionConfigMapping(runTimeMapping, combinedIndex, generatedClasses, reflectiveClasses, configClasses); } } @BuildStep - void builderMappings( + void generateBuilders( ConfigurationBuildItem configItem, List configMappings, + List runTimeDefaults, + List staticInitConfigBuilders, + List runTimeConfigBuilders, BuildProducer generatedClass, - BuildProducer reflectiveClass, - BuildProducer staticInitConfigBuilder, - BuildProducer runTimeConfigBuilder) { + BuildProducer reflectiveClass) throws Exception { + + // Default Values collected from mappings / roots and build item + Map defaultValues = new HashMap<>(); + for (RunTimeConfigurationDefaultBuildItem e : runTimeDefaults) { + defaultValues.put(e.getKey(), e.getValue()); + } + defaultValues.putAll(configItem.getReadResult().getRunTimeDefaultValues()); + + Set converters = discoverService(Converter.class, reflectiveClass); + Set interceptors = discoverService(ConfigSourceInterceptor.class, reflectiveClass); + Set interceptorFactories = discoverService(ConfigSourceInterceptorFactory.class, reflectiveClass); + Set configSources = discoverService(ConfigSource.class, reflectiveClass); + Set configSourceProviders = discoverService(ConfigSourceProvider.class, reflectiveClass); + Set configSourceFactories = discoverService(ConfigSourceFactory.class, reflectiveClass); + Set secretKeyHandlers = discoverService(SecretKeysHandler.class, reflectiveClass); + Set secretKeyHandlerFactories = discoverService(SecretKeysHandlerFactory.class, reflectiveClass); + Set configCustomizers = discoverService(SmallRyeConfigBuilderCustomizer.class, reflectiveClass); // For Static Init Config Set staticMappings = new HashSet<>(); staticMappings.addAll(staticSafeConfigMappings(configMappings)); staticMappings.addAll(configItem.getReadResult().getBuildTimeRunTimeMappings()); - String staticInitMappingsConfigBuilder = "io.quarkus.runtime.generated.StaticInitMappingsConfigBuilder"; - generateMappingsConfigBuilder(generatedClass, reflectiveClass, staticInitMappingsConfigBuilder, staticMappings); - staticInitConfigBuilder.produce(new StaticInitConfigBuilderBuildItem(staticInitMappingsConfigBuilder)); + Set staticCustomizers = new HashSet<>(staticSafeServices(configCustomizers)); + staticCustomizers.add(StaticInitConfigBuilderCustomizer.class.getName()); + + generateConfigBuilder(generatedClass, reflectiveClass, CONFIG_BUILDER_STATIC_NAME, + defaultValues, + converters, + interceptors, + staticSafeServices(interceptorFactories), + staticSafeServices(configSources), + staticSafeServices(configSourceProviders), + staticSafeServices(configSourceFactories), + secretKeyHandlers, + staticSafeServices(secretKeyHandlerFactories), + staticMappings, + staticCustomizers, + staticInitConfigBuilders.stream().map(StaticInitConfigBuilderBuildItem::getBuilderClassName).collect(toSet())); + reflectiveClass.produce(ReflectiveClassBuildItem.builder(CONFIG_BUILDER_STATIC_NAME).build()); // For RunTime Config Set runTimeMappings = new HashSet<>(); runTimeMappings.addAll(runtimeConfigMappings(configMappings)); runTimeMappings.addAll(configItem.getReadResult().getBuildTimeRunTimeMappings()); runTimeMappings.addAll(configItem.getReadResult().getRunTimeMappings()); - String runTimeMappingsConfigBuilder = "io.quarkus.runtime.generated.RunTimeMappingsConfigBuilder"; - generateMappingsConfigBuilder(generatedClass, reflectiveClass, runTimeMappingsConfigBuilder, runTimeMappings); - runTimeConfigBuilder.produce(new RunTimeConfigBuilderBuildItem(runTimeMappingsConfigBuilder)); + Set runtimeCustomizers = new HashSet<>(configCustomizers); + runtimeCustomizers.add(RuntimeConfigBuilderCustomizer.class.getName()); + + generateConfigBuilder(generatedClass, reflectiveClass, CONFIG_BUILDER_RUNTIME_NAME, + defaultValues, + converters, + interceptors, + interceptorFactories, + configSources, + configSourceProviders, + configSourceFactories, + secretKeyHandlers, + secretKeyHandlerFactories, + runTimeMappings, + runtimeCustomizers, + runTimeConfigBuilders.stream().map(RunTimeConfigBuilderBuildItem::getBuilderClassName).collect(toSet())); + reflectiveClass.produce(ReflectiveClassBuildItem.builder(CONFIG_BUILDER_RUNTIME_NAME).build()); } /** @@ -260,43 +259,16 @@ void generateConfigClass( List typeItems, LaunchModeBuildItem launchModeBuildItem, BuildProducer generatedClass, - BuildProducer reflectiveClass, - LiveReloadBuildItem liveReloadBuildItem, - List configMappings, - List staticInitConfigBuilders, - List runTimeConfigBuilders) - throws IOException { + LiveReloadBuildItem liveReloadBuildItem) { reportUnknownBuildProperties(launchModeBuildItem.getLaunchMode(), configItem.getReadResult().getUnknownBuildProperties()); + // TODO - Test live reload with ConfigSource if (liveReloadBuildItem.isLiveReload()) { return; } - Set discoveredConfigSources = discoverService(ConfigSource.class, reflectiveClass); - Set discoveredConfigSourceProviders = discoverService(ConfigSourceProvider.class, reflectiveClass); - Set discoveredConfigSourceFactories = discoverService(ConfigSourceFactory.class, reflectiveClass); - - Set staticConfigSourceProviders = staticSafeServices(discoveredConfigSourceProviders); - Set staticConfigSourceFactories = staticSafeServices(discoveredConfigSourceFactories); - - // TODO - duplicated now builderMappings. Still required to filter the unknown properties - Set staticMappings = new HashSet<>(); - staticMappings.addAll(staticSafeConfigMappings(configMappings)); - staticMappings.addAll(configItem.getReadResult().getBuildTimeRunTimeMappings()); - - Set runtimeMappings = new HashSet<>(); - runtimeMappings.addAll(runtimeConfigMappings(configMappings)); - runtimeMappings.addAll(configItem.getReadResult().getBuildTimeRunTimeMappings()); - runtimeMappings.addAll(configItem.getReadResult().getRunTimeMappings()); - - Set runtimeConfigBuilderClassNames = runTimeConfigBuilders.stream() - .map(RunTimeConfigBuilderBuildItem::getBuilderClassName).collect(toSet()); - reflectiveClass - .produce(ReflectiveClassBuildItem.builder(runtimeConfigBuilderClassNames.toArray(new String[0])) - .build()); - RunTimeConfigurationGenerator.GenerateOperation .builder() .setBuildTimeReadResult(configItem.getReadResult()) @@ -305,17 +277,6 @@ void generateConfigClass( .setLiveReloadPossible(launchModeBuildItem.getLaunchMode() == LaunchMode.DEVELOPMENT || launchModeBuildItem.isAuxiliaryApplication()) .setAdditionalTypes(typeItems.stream().map(ConfigurationTypeBuildItem::getValueType).collect(toList())) - .setStaticConfigSources(staticSafeServices(discoveredConfigSources)) - .setStaticConfigSourceProviders(staticConfigSourceProviders) - .setStaticConfigSourceFactories(staticConfigSourceFactories) - .setStaticConfigMappings(staticMappings) - .setStaticConfigBuilders(staticInitConfigBuilders.stream() - .map(StaticInitConfigBuilderBuildItem::getBuilderClassName).collect(toSet())) - .setRuntimeConfigSources(discoveredConfigSources) - .setRuntimeConfigSourceProviders(discoveredConfigSourceProviders) - .setRuntimeConfigSourceFactories(discoveredConfigSourceFactories) - .setRuntimeConfigMappings(runtimeMappings) - .setRuntimeConfigBuilders(runtimeConfigBuilderClassNames) .build() .run(); } @@ -490,72 +451,132 @@ private static String getPathWithoutExtension(Path path) { return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex); } - private static void generateDefaultsConfigSource( + private static final MethodDescriptor BUILDER_CUSTOMIZER = MethodDescriptor.ofMethod(SmallRyeConfigBuilderCustomizer.class, + "configBuilder", + void.class, SmallRyeConfigBuilder.class); + + private static final MethodDescriptor WITH_DEFAULT = MethodDescriptor.ofMethod(AbstractConfigBuilder.class, + "withDefaultValue", + void.class, SmallRyeConfigBuilder.class, String.class, String.class); + private static final MethodDescriptor WITH_CONVERTER = MethodDescriptor.ofMethod(AbstractConfigBuilder.class, + "withConverter", void.class, SmallRyeConfigBuilder.class, Converter.class); + private static final MethodDescriptor WITH_INTERCEPTOR = MethodDescriptor.ofMethod(AbstractConfigBuilder.class, + "withInterceptor", + void.class, SmallRyeConfigBuilder.class, ConfigSourceInterceptor.class); + private static final MethodDescriptor WITH_INTERCEPTOR_FACTORY = MethodDescriptor.ofMethod(AbstractConfigBuilder.class, + "withInterceptorFactory", + void.class, SmallRyeConfigBuilder.class, ConfigSourceInterceptorFactory.class); + private static final MethodDescriptor WITH_SOURCE = MethodDescriptor.ofMethod(AbstractConfigBuilder.class, + "withSource", + void.class, SmallRyeConfigBuilder.class, ConfigSource.class); + private static final MethodDescriptor WITH_SOURCE_PROVIDER = MethodDescriptor.ofMethod(AbstractConfigBuilder.class, + "withSource", + void.class, SmallRyeConfigBuilder.class, ConfigSourceProvider.class); + private static final MethodDescriptor WITH_SOURCE_FACTORY = MethodDescriptor.ofMethod(AbstractConfigBuilder.class, + "withSource", + void.class, SmallRyeConfigBuilder.class, ConfigSourceFactory.class); + private static final MethodDescriptor WITH_SECRET_HANDLER = MethodDescriptor.ofMethod(AbstractConfigBuilder.class, + "withSecretKeyHandler", void.class, SmallRyeConfigBuilder.class, SecretKeysHandler.class); + private static final MethodDescriptor WITH_SECRET_HANDLER_FACTORY = MethodDescriptor.ofMethod(AbstractConfigBuilder.class, + "withSecretKeyHandler", void.class, SmallRyeConfigBuilder.class, SecretKeysHandlerFactory.class); + private static final MethodDescriptor WITH_MAPPING = MethodDescriptor.ofMethod(AbstractConfigBuilder.class, + "withMapping", + void.class, SmallRyeConfigBuilder.class, String.class, String.class); + private static final MethodDescriptor WITH_CUSTOMIZER = MethodDescriptor.ofMethod(AbstractConfigBuilder.class, + "withCustomizer", + void.class, SmallRyeConfigBuilder.class, SmallRyeConfigBuilderCustomizer.class); + private static final MethodDescriptor WITH_BUILDER = MethodDescriptor.ofMethod(AbstractConfigBuilder.class, + "withBuilder", + void.class, SmallRyeConfigBuilder.class, ConfigBuilder.class); + + private static void generateConfigBuilder( BuildProducer generatedClass, BuildProducer reflectiveClass, - Map defaults, String className, - String sourceName, - int sourceOrdinal) { + Map defaultValues, + Set converters, + Set interceptors, + Set interceptorFactories, + Set configSources, + Set configSourceProviders, + Set configSourceFactories, + Set secretKeyHandlers, + Set secretKeyHandlerFactories, + Set mappings, + Set configCustomizers, + Set configBuilders) { try (ClassCreator classCreator = ClassCreator.builder() .classOutput(new GeneratedClassGizmoAdaptor(generatedClass, true)) .className(className) - .superClass(DefaultsConfigSource.class) + .interfaces(SmallRyeConfigBuilderCustomizer.class) + .superClass(AbstractConfigBuilder.class) .setFinal(true) .build()) { - FieldDescriptor properties = FieldDescriptor.of(classCreator.getClassName(), "properties", Map.class); - classCreator.getFieldCreator(properties).setModifiers(Opcodes.ACC_STATIC | Opcodes.ACC_FINAL); + MethodCreator method = classCreator.getMethodCreator(BUILDER_CUSTOMIZER); + ResultHandle configBuilder = method.getMethodParam(0); - MethodCreator clinit = classCreator.getMethodCreator("", void.class); - clinit.setModifiers(Opcodes.ACC_STATIC); - clinit.writeStaticField(properties, clinit.newInstance(MethodDescriptor.ofConstructor(HashMap.class))); + for (Map.Entry entry : defaultValues.entrySet()) { + method.invokeStaticMethod(WITH_DEFAULT, configBuilder, method.load(entry.getKey()), + method.load(entry.getValue())); + } - ResultHandle map = clinit.readStaticField(properties); - MethodDescriptor put = MethodDescriptor.ofMethod(Map.class, "put", Object.class, Object.class, Object.class); - for (Map.Entry entry : defaults.entrySet()) { - clinit.invokeInterfaceMethod(put, map, clinit.load(entry.getKey()), clinit.load(entry.getValue())); + for (String converter : converters) { + method.invokeStaticMethod(WITH_CONVERTER, configBuilder, + method.newInstance(MethodDescriptor.ofConstructor(converter))); } - clinit.returnVoid(); - MethodCreator ctor = classCreator.getMethodCreator("", void.class); - MethodDescriptor superCtor = MethodDescriptor.ofConstructor(DefaultsConfigSource.class, Map.class, String.class, - int.class); - ctor.invokeSpecialMethod(superCtor, ctor.getThis(), ctor.readStaticField(properties), - ctor.load(sourceName), ctor.load(sourceOrdinal)); - ctor.returnVoid(); - } + for (String interceptor : interceptors) { + method.invokeStaticMethod(WITH_INTERCEPTOR, configBuilder, + method.newInstance(MethodDescriptor.ofConstructor(interceptor))); + } - reflectiveClass - .produce(ReflectiveClassBuildItem.builder(className).build()); - } + for (String interceptorFactory : interceptorFactories) { + method.invokeStaticMethod(WITH_INTERCEPTOR_FACTORY, configBuilder, + method.newInstance(MethodDescriptor.ofConstructor(interceptorFactory))); + } - private static void generateMappingsConfigBuilder( - BuildProducer generatedClass, - BuildProducer reflectiveClass, - String className, - Set mappings) { + for (String configSource : configSources) { + method.invokeStaticMethod(WITH_SOURCE, configBuilder, + method.newInstance(MethodDescriptor.ofConstructor(configSource))); + } - try (ClassCreator classCreator = ClassCreator.builder() - .classOutput(new GeneratedClassGizmoAdaptor(generatedClass, true)) - .className(className) - .interfaces(ConfigBuilder.class) - .superClass(MappingsConfigBuilder.class) - .setFinal(true) - .build()) { + for (String configSourceProvider : configSourceProviders) { + method.invokeStaticMethod(WITH_SOURCE_PROVIDER, configBuilder, + method.newInstance(MethodDescriptor.ofConstructor(configSourceProvider))); + } - MethodCreator method = classCreator.getMethodCreator(CONFIG_BUILDER); - ResultHandle configBuilder = method.getMethodParam(0); + for (String configSourceFactory : configSourceFactories) { + method.invokeStaticMethod(WITH_SOURCE_FACTORY, configBuilder, + method.newInstance(MethodDescriptor.ofConstructor(configSourceFactory))); + } - MethodDescriptor addMapping = MethodDescriptor.ofMethod(MappingsConfigBuilder.class, "addMapping", void.class, - SmallRyeConfigBuilder.class, String.class, String.class); + for (String secretKeyHandler : secretKeyHandlers) { + method.invokeStaticMethod(WITH_SECRET_HANDLER, configBuilder, + method.newInstance(MethodDescriptor.ofConstructor(secretKeyHandler))); + } + + for (String secretKeyHandlerFactory : secretKeyHandlerFactories) { + method.invokeStaticMethod(WITH_SECRET_HANDLER_FACTORY, configBuilder, + method.newInstance(MethodDescriptor.ofConstructor(secretKeyHandlerFactory))); + } for (ConfigClassWithPrefix mapping : mappings) { - method.invokeStaticMethod(addMapping, configBuilder, method.load(mapping.getKlass().getName()), + method.invokeStaticMethod(WITH_MAPPING, configBuilder, method.load(mapping.getKlass().getName()), method.load(mapping.getPrefix())); } + for (String configCustomizer : configCustomizers) { + method.invokeStaticMethod(WITH_CUSTOMIZER, configBuilder, + method.newInstance(MethodDescriptor.ofConstructor(configCustomizer))); + } + + for (String builder : configBuilders) { + method.invokeStaticMethod(WITH_BUILDER, configBuilder, + method.newInstance(MethodDescriptor.ofConstructor(builder))); + } + method.returnValue(configBuilder); } @@ -568,15 +589,16 @@ private static Set discoverService( ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Set services = new HashSet<>(); for (String service : classNamesNamedIn(classLoader, SERVICES_PREFIX + serviceClass.getName())) { - services.add(service); - reflectiveClass - .produce(ReflectiveClassBuildItem.builder(service).build()); + // The discovery includes deployment modules, so we only include services available at runtime + if (QuarkusClassLoader.isClassPresentAtRuntime(service)) { + services.add(service); + reflectiveClass.produce(ReflectiveClassBuildItem.builder(service).build()); + } } return services; } private static Set staticSafeServices(Set services) { - // TODO - Replace with Jandex? The issue is that the sources may not be in the index... ClassLoader classloader = Thread.currentThread().getContextClassLoader(); Set staticSafe = new HashSet<>(); for (String service : services) { @@ -595,13 +617,13 @@ private static Set staticSafeServices(Set services) { private static Set staticSafeConfigMappings(List configMappings) { return configMappings.stream() .filter(ConfigMappingBuildItem::isStaticInitSafe) - .map(configMapping -> configClassWithPrefix(configMapping.getConfigClass(), configMapping.getPrefix())) + .map(ConfigMappingBuildItem::toConfigClassWithPrefix) .collect(toSet()); } private static Set runtimeConfigMappings(List configMappings) { return configMappings.stream() - .map(configMapping -> configClassWithPrefix(configMapping.getConfigClass(), configMapping.getPrefix())) + .map(ConfigMappingBuildItem::toConfigClassWithPrefix) .collect(toSet()); } } diff --git a/core/runtime/src/main/java/io/quarkus/runtime/ConfigConfig.java b/core/runtime/src/main/java/io/quarkus/runtime/ConfigConfig.java index 9f73f81cfc768b..cfc366e24b5657 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/ConfigConfig.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/ConfigConfig.java @@ -7,7 +7,6 @@ import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; import io.smallrye.config.ConfigMapping; -import io.smallrye.config.WithDefault; import io.smallrye.config.WithName; /** @@ -23,7 +22,6 @@ public interface ConfigConfig { /** * Profile that will be active when Quarkus launches. */ - @WithDefault("prod") Optional profile(); /** diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/AbstractConfigBuilder.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/AbstractConfigBuilder.java new file mode 100644 index 00000000000000..b2753b0eb7cde1 --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/runtime/configuration/AbstractConfigBuilder.java @@ -0,0 +1,94 @@ +package io.quarkus.runtime.configuration; + +import org.eclipse.microprofile.config.spi.ConfigSource; +import org.eclipse.microprofile.config.spi.ConfigSourceProvider; +import org.eclipse.microprofile.config.spi.Converter; + +import io.smallrye.config.ConfigSourceFactory; +import io.smallrye.config.ConfigSourceInterceptor; +import io.smallrye.config.ConfigSourceInterceptorFactory; +import io.smallrye.config.SecretKeysHandler; +import io.smallrye.config.SecretKeysHandlerFactory; +import io.smallrye.config.SmallRyeConfigBuilder; +import io.smallrye.config.SmallRyeConfigBuilderCustomizer; + +public abstract class AbstractConfigBuilder implements SmallRyeConfigBuilderCustomizer { + protected static void withDefaultValue(SmallRyeConfigBuilder builder, String name, String value) { + builder.withDefaultValue(name, value); + } + + // TODO - radcortez - Can be improved by avoiding introspection work in the Converter class. + // Not a big issue, because registering Converters via ServiceLoader is not a common case + protected static void withConverter(SmallRyeConfigBuilder builder, Converter converter) { + builder.withConverters(new Converter[] { converter }); + } + + protected static void withInterceptor(SmallRyeConfigBuilder builder, ConfigSourceInterceptor interceptor) { + builder.withInterceptors(interceptor); + } + + protected static void withInterceptorFactory( + SmallRyeConfigBuilder builder, + ConfigSourceInterceptorFactory interceptorFactory) { + builder.withInterceptorFactories(interceptorFactory); + } + + protected static void withSource(SmallRyeConfigBuilder builder, ConfigSource configSource) { + builder.withSources(configSource); + } + + protected static void withSource(SmallRyeConfigBuilder builder, ConfigSourceProvider configSourceProvider) { + builder.withSources(configSourceProvider); + } + + protected static void withSource(SmallRyeConfigBuilder builder, ConfigSourceFactory configSourceFactory) { + builder.withSources(configSourceFactory); + } + + protected static void withSecretKeyHandler(SmallRyeConfigBuilder builder, SecretKeysHandler secretKeysHandler) { + builder.withSecretKeysHandlers(secretKeysHandler); + } + + protected static void withSecretKeyHandler(SmallRyeConfigBuilder builder, + SecretKeysHandlerFactory secretKeysHandlerFactory) { + builder.withSecretKeyHandlerFactories(secretKeysHandlerFactory); + } + + protected static void withMapping(SmallRyeConfigBuilder builder, String mappingClass, String prefix) { + try { + // To support mappings that are not public + builder.withMapping(builder.getClassLoader().loadClass(mappingClass), prefix); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + protected static void withBuilder(SmallRyeConfigBuilder builder, ConfigBuilder configBuilder) { + builder.withCustomizers(new SmallRyeConfigBuilderCustomizer() { + @Override + public void configBuilder(final SmallRyeConfigBuilder builder) { + configBuilder.configBuilder(builder); + } + + @Override + public int priority() { + return configBuilder.priority(); + } + }); + } + + protected static void withCustomizer(SmallRyeConfigBuilder builder, SmallRyeConfigBuilderCustomizer customizer) { + builder.withCustomizers(customizer); + } + + @SuppressWarnings("unchecked") + public static void withCustomizer(SmallRyeConfigBuilder builder, String customizer) { + try { + Class customizerClass = (Class) builder + .getClassLoader().loadClass(customizer); + customizerClass.getDeclaredConstructor().newInstance().configBuilder(builder); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/ConfigSourceFactoryProvider.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/ConfigSourceFactoryProvider.java deleted file mode 100644 index 15090cf88cba0a..00000000000000 --- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/ConfigSourceFactoryProvider.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.quarkus.runtime.configuration; - -import io.smallrye.config.ConfigSourceFactory; - -public interface ConfigSourceFactoryProvider { - ConfigSourceFactory getConfigSourceFactory(final ClassLoader forClassLoader); -} diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/ConfigUtils.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/ConfigUtils.java index 8b8c2291111025..6b80e16ba3dde7 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/ConfigUtils.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/configuration/ConfigUtils.java @@ -1,42 +1,22 @@ package io.quarkus.runtime.configuration; -import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_LOCATIONS; -import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_LOG_VALUES; -import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_MAPPING_VALIDATE_UNKNOWN; -import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_PROFILE; -import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_PROFILE_PARENT; - -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; -import java.util.Comparator; -import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; import java.util.Optional; -import java.util.OptionalInt; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.UUID; -import java.util.function.Function; import java.util.function.IntFunction; import org.eclipse.microprofile.config.Config; import org.eclipse.microprofile.config.ConfigProvider; import org.eclipse.microprofile.config.spi.ConfigSource; -import org.eclipse.microprofile.config.spi.ConfigSourceProvider; import io.quarkus.runtime.LaunchMode; -import io.smallrye.config.ConfigSourceInterceptor; -import io.smallrye.config.ConfigSourceInterceptorContext; -import io.smallrye.config.ConfigSourceInterceptorFactory; import io.smallrye.config.DotEnvConfigSourceProvider; -import io.smallrye.config.FallbackConfigSourceInterceptor; -import io.smallrye.config.NameIterator; -import io.smallrye.config.Priorities; -import io.smallrye.config.RelocateConfigSourceInterceptor; import io.smallrye.config.SmallRyeConfig; import io.smallrye.config.SmallRyeConfigBuilder; @@ -81,96 +61,21 @@ public static SmallRyeConfigBuilder configBuilder(final boolean runTime, final b SmallRyeConfigBuilder builder = emptyConfigBuilder(); if (launchMode.isDevOrTest() && runTime) { - builder.withSources(new RuntimeOverrideConfigSource(Thread.currentThread().getContextClassLoader())); + builder.withSources(new RuntimeOverrideConfigSource(builder.getClassLoader())); } if (runTime) { builder.withDefaultValue(UUID_KEY, UUID.randomUUID().toString()); } if (addDiscovered) { - builder.addDiscoveredSources(); + builder.addDiscoveredCustomizers().addDiscoveredSources(); } return builder; } public static SmallRyeConfigBuilder emptyConfigBuilder() { - SmallRyeConfigBuilder builder = new SmallRyeConfigBuilder(); - LaunchMode launchMode = ProfileManager.getLaunchMode(); - builder.withDefaultValue(launchMode.getProfileKey(), launchMode.getDefaultProfile()); - - builder.withInterceptorFactories(new ConfigSourceInterceptorFactory() { - @Override - public ConfigSourceInterceptor getInterceptor(final ConfigSourceInterceptorContext context) { - return new RelocateConfigSourceInterceptor(Map.of(SMALLRYE_CONFIG_PROFILE, launchMode.getProfileKey())); - } - - @Override - public OptionalInt getPriority() { - return OptionalInt.of(Priorities.LIBRARY + 200 - 10); - } - }); - - builder.withInterceptorFactories(new ConfigSourceInterceptorFactory() { - @Override - public ConfigSourceInterceptor getInterceptor(final ConfigSourceInterceptorContext context) { - Map relocations = new HashMap<>(); - relocations.put(SMALLRYE_CONFIG_LOCATIONS, "quarkus.config.locations"); - relocations.put(SMALLRYE_CONFIG_PROFILE_PARENT, "quarkus.config.profile.parent"); - relocations.put(SMALLRYE_CONFIG_MAPPING_VALIDATE_UNKNOWN, "quarkus.config.mapping.validate-unknown"); - relocations.put(SMALLRYE_CONFIG_LOG_VALUES, "quarkus.config.log.values"); - - // Also adds relocations to all profiles - return new RelocateConfigSourceInterceptor(new Function() { - @Override - public String apply(final String name) { - String relocate = relocations.get(name); - if (relocate != null) { - return relocate; - } - - if (name.startsWith("%") && name.endsWith(SMALLRYE_CONFIG_LOCATIONS)) { - io.smallrye.config.NameIterator ni = new io.smallrye.config.NameIterator(name); - return ni.getNextSegment() + "." + "quarkus.config.locations"; - } - - if (name.startsWith("%") && name.endsWith(SMALLRYE_CONFIG_PROFILE_PARENT)) { - io.smallrye.config.NameIterator ni = new NameIterator(name); - return ni.getNextSegment() + "." + "quarkus.config.profile.parent"; - } - - return name; - } - }); - } - - @Override - public OptionalInt getPriority() { - // So it executes before the ProfileConfigSourceInterceptor and applies the profile relocation - return OptionalInt.of(Priorities.LIBRARY + 200 - 5); - } - }); - - builder.withInterceptorFactories(new ConfigSourceInterceptorFactory() { - @Override - public ConfigSourceInterceptor getInterceptor(final ConfigSourceInterceptorContext context) { - Map fallbacks = new HashMap<>(); - fallbacks.put("quarkus.profile", SMALLRYE_CONFIG_PROFILE); - fallbacks.put("quarkus.config.locations", SMALLRYE_CONFIG_LOCATIONS); - fallbacks.put("quarkus.config.profile.parent", SMALLRYE_CONFIG_PROFILE_PARENT); - fallbacks.put("quarkus.config.mapping.validate-unknown", SMALLRYE_CONFIG_MAPPING_VALIDATE_UNKNOWN); - fallbacks.put("quarkus.config.log.values", SMALLRYE_CONFIG_LOG_VALUES); - return new FallbackConfigSourceInterceptor(fallbacks); - } - - @Override - public OptionalInt getPriority() { - return OptionalInt.of(Priorities.LIBRARY + 600 - 5); - } - }); - - // Ignore unmapped quarkus properties, because properties in the same root may be split between build / runtime - builder.withMappingIgnore("quarkus.**"); - - builder.forClassLoader(Thread.currentThread().getContextClassLoader()) + return new SmallRyeConfigBuilder() + .forClassLoader(Thread.currentThread().getContextClassLoader()) + .withCustomizers(new QuarkusConfigBuilderCustomizer()) .addDiscoveredConverters() .addDefaultInterceptors() .addDiscoveredInterceptors() @@ -179,63 +84,6 @@ public OptionalInt getPriority() { .withSources(new ApplicationPropertiesConfigSourceLoader.InFileSystem()) .withSources(new ApplicationPropertiesConfigSourceLoader.InClassPath()) .withSources(new DotEnvConfigSourceProvider()); - - return builder; - } - - @SuppressWarnings("unchecked") - public static SmallRyeConfigBuilder configBuilder(SmallRyeConfigBuilder builder, List configBuildersNames) { - ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); - try { - List configBuilders = new ArrayList<>(); - for (String configBuilderName : configBuildersNames) { - Class configBuilderClass = (Class) contextClassLoader - .loadClass(configBuilderName); - configBuilders.add(configBuilderClass.getDeclaredConstructor().newInstance()); - } - configBuilders.sort(ConfigBuilderComparator.INSTANCE); - - for (ConfigBuilder configBuilder : configBuilders) { - builder = configBuilder.configBuilder(builder); - if (builder == null) { - throw new ConfigurationException(configBuilder.getClass().getName() + " returned a null builder"); - } - } - - } catch (ClassNotFoundException | InstantiationException | InvocationTargetException | NoSuchMethodException - | IllegalAccessException e) { - throw new ConfigurationException(e); - } - return builder; - } - - /** - * Add a configuration source provider to the builder. - * - * @param builder the builder - * @param provider the provider to add - */ - public static void addSourceProvider(SmallRyeConfigBuilder builder, ConfigSourceProvider provider) { - final Iterable sources = provider.getConfigSources(Thread.currentThread().getContextClassLoader()); - for (ConfigSource source : sources) { - builder.withSources(source); - } - } - - /** - * Add a configuration source providers to the builder. - * - * @param builder the builder - * @param providers the providers to add - */ - public static void addSourceProviders(SmallRyeConfigBuilder builder, Collection providers) { - for (ConfigSourceProvider provider : providers) { - addSourceProvider(builder, provider); - } - } - - public static void addSourceFactoryProvider(SmallRyeConfigBuilder builder, ConfigSourceFactoryProvider provider) { - builder.withSources(provider.getConfigSourceFactory(Thread.currentThread().getContextClassLoader())); } public static List getProfiles() { @@ -304,13 +152,4 @@ public static Optional getFirstOptionalValue(List propertyNames, } return Optional.empty(); } - - private static class ConfigBuilderComparator implements Comparator { - private static final ConfigBuilderComparator INSTANCE = new ConfigBuilderComparator(); - - @Override - public int compare(ConfigBuilder o1, ConfigBuilder o2) { - return Integer.compare(o1.priority(), o2.priority()); - } - } } diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/DefaultsConfigSource.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/DefaultsConfigSource.java deleted file mode 100644 index 1445e25bf3ad37..00000000000000 --- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/DefaultsConfigSource.java +++ /dev/null @@ -1,42 +0,0 @@ -package io.quarkus.runtime.configuration; - -import java.util.HashMap; -import java.util.Map; - -import io.quarkus.runtime.annotations.StaticInitSafe; -import io.smallrye.config.KeyMap; -import io.smallrye.config.common.MapBackedConfigSource; - -@StaticInitSafe -public class DefaultsConfigSource extends MapBackedConfigSource { - private final KeyMap wildcards; - - public DefaultsConfigSource(final Map properties, final String name, final int ordinal) { - // Defaults may contain wildcards, but we don't want to expose them in getPropertyNames, so we need to filter - // them - super(name, filterWildcards(properties), ordinal); - this.wildcards = new KeyMap<>(); - for (Map.Entry entry : properties.entrySet()) { - if (entry.getKey().contains("*")) { - this.wildcards.findOrAdd(entry.getKey()).putRootValue(entry.getValue()); - } - } - } - - @Override - public String getValue(final String propertyName) { - String value = super.getValue(propertyName); - return value == null ? wildcards.findRootValue(propertyName) : value; - } - - private static Map filterWildcards(final Map properties) { - Map filtered = new HashMap<>(); - for (Map.Entry entry : properties.entrySet()) { - if (entry.getKey().contains("*")) { - continue; - } - filtered.put(entry.getKey(), entry.getValue()); - } - return filtered; - } -} diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/MappingsConfigBuilder.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/MappingsConfigBuilder.java deleted file mode 100644 index 24d1b607074bea..00000000000000 --- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/MappingsConfigBuilder.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.quarkus.runtime.configuration; - -import io.smallrye.config.SmallRyeConfigBuilder; - -/** - * To support mappings that are not public - */ -public abstract class MappingsConfigBuilder implements ConfigBuilder { - protected static void addMapping(SmallRyeConfigBuilder builder, String mappingClass, String prefix) { - // TODO - Ideally should use the classloader passed to Config, but the method is not public. Requires a change in SmallRye Config. - ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); - try { - builder.withMapping(contextClassLoader.loadClass(mappingClass), prefix); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } -} 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 4a87c6b0f191af..c2d6b78f1e2754 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 @@ -11,6 +11,10 @@ public class PropertiesUtil { private PropertiesUtil() { } + /** + * @deprecated Use {@link PropertiesUtil#filterPropertiesInRoots(Iterable, Set)} instead. + */ + @Deprecated(forRemoval = true) public static boolean isPropertyInRoot(Set roots, NameIterator propertyName) { for (String root : roots) { // match everything diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/QuarkusConfigBuilderCustomizer.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/QuarkusConfigBuilderCustomizer.java new file mode 100644 index 00000000000000..6d9e82852aa308 --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/runtime/configuration/QuarkusConfigBuilderCustomizer.java @@ -0,0 +1,104 @@ +package io.quarkus.runtime.configuration; + +import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_LOCATIONS; +import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_LOG_VALUES; +import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_MAPPING_VALIDATE_UNKNOWN; +import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_PROFILE; +import static io.smallrye.config.SmallRyeConfig.SMALLRYE_CONFIG_PROFILE_PARENT; + +import java.util.HashMap; +import java.util.Map; +import java.util.OptionalInt; +import java.util.function.Function; + +import io.quarkus.runtime.LaunchMode; +import io.smallrye.config.ConfigSourceInterceptor; +import io.smallrye.config.ConfigSourceInterceptorContext; +import io.smallrye.config.ConfigSourceInterceptorFactory; +import io.smallrye.config.FallbackConfigSourceInterceptor; +import io.smallrye.config.NameIterator; +import io.smallrye.config.Priorities; +import io.smallrye.config.RelocateConfigSourceInterceptor; +import io.smallrye.config.SmallRyeConfigBuilder; +import io.smallrye.config.SmallRyeConfigBuilderCustomizer; + +public class QuarkusConfigBuilderCustomizer implements SmallRyeConfigBuilderCustomizer { + @Override + public void configBuilder(final SmallRyeConfigBuilder builder) { + LaunchMode launchMode = ProfileManager.getLaunchMode(); + builder.withDefaultValue(launchMode.getProfileKey(), launchMode.getDefaultProfile()); + + builder.withInterceptorFactories(new ConfigSourceInterceptorFactory() { + @Override + public ConfigSourceInterceptor getInterceptor(final ConfigSourceInterceptorContext context) { + return new RelocateConfigSourceInterceptor(Map.of(SMALLRYE_CONFIG_PROFILE, launchMode.getProfileKey())); + } + + @Override + public OptionalInt getPriority() { + return OptionalInt.of(Priorities.LIBRARY + 200 - 10); + } + }); + + builder.withInterceptorFactories(new ConfigSourceInterceptorFactory() { + @Override + public ConfigSourceInterceptor getInterceptor(final ConfigSourceInterceptorContext context) { + Map relocations = new HashMap<>(); + relocations.put(SMALLRYE_CONFIG_LOCATIONS, "quarkus.config.locations"); + relocations.put(SMALLRYE_CONFIG_PROFILE_PARENT, "quarkus.config.profile.parent"); + relocations.put(SMALLRYE_CONFIG_MAPPING_VALIDATE_UNKNOWN, "quarkus.config.mapping.validate-unknown"); + relocations.put(SMALLRYE_CONFIG_LOG_VALUES, "quarkus.config.log.values"); + + // Also adds relocations to all profiles + return new RelocateConfigSourceInterceptor(new Function() { + @Override + public String apply(final String name) { + String relocate = relocations.get(name); + if (relocate != null) { + return relocate; + } + + if (name.startsWith("%") && name.endsWith(SMALLRYE_CONFIG_LOCATIONS)) { + io.smallrye.config.NameIterator ni = new io.smallrye.config.NameIterator(name); + return ni.getNextSegment() + "." + "quarkus.config.locations"; + } + + if (name.startsWith("%") && name.endsWith(SMALLRYE_CONFIG_PROFILE_PARENT)) { + io.smallrye.config.NameIterator ni = new NameIterator(name); + return ni.getNextSegment() + "." + "quarkus.config.profile.parent"; + } + + return name; + } + }); + } + + @Override + public OptionalInt getPriority() { + // So it executes before the ProfileConfigSourceInterceptor and applies the profile relocation + return OptionalInt.of(Priorities.LIBRARY + 200 - 5); + } + }); + + builder.withInterceptorFactories(new ConfigSourceInterceptorFactory() { + @Override + public ConfigSourceInterceptor getInterceptor(final ConfigSourceInterceptorContext context) { + Map fallbacks = new HashMap<>(); + fallbacks.put("quarkus.profile", SMALLRYE_CONFIG_PROFILE); + fallbacks.put("quarkus.config.locations", SMALLRYE_CONFIG_LOCATIONS); + fallbacks.put("quarkus.config.profile.parent", SMALLRYE_CONFIG_PROFILE_PARENT); + fallbacks.put("quarkus.config.mapping.validate-unknown", SMALLRYE_CONFIG_MAPPING_VALIDATE_UNKNOWN); + fallbacks.put("quarkus.config.log.values", SMALLRYE_CONFIG_LOG_VALUES); + return new FallbackConfigSourceInterceptor(fallbacks); + } + + @Override + public OptionalInt getPriority() { + return OptionalInt.of(Priorities.LIBRARY + 600 - 5); + } + }); + + // Ignore unmapped quarkus properties, because properties in the same root may be split between build / runtime + builder.withMappingIgnore("quarkus.**"); + } +} diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/QuarkusConfigFactory.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/QuarkusConfigFactory.java index 9f168ae907e6f8..34adb96ea33625 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/QuarkusConfigFactory.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/configuration/QuarkusConfigFactory.java @@ -2,6 +2,7 @@ import org.eclipse.microprofile.config.spi.ConfigProviderResolver; +import io.quarkus.runtime.LaunchMode; import io.smallrye.config.SmallRyeConfig; import io.smallrye.config.SmallRyeConfigFactory; import io.smallrye.config.SmallRyeConfigProviderResolver; @@ -23,10 +24,7 @@ public QuarkusConfigFactory() { public SmallRyeConfig getConfigFor(final SmallRyeConfigProviderResolver configProviderResolver, final ClassLoader classLoader) { if (config == null) { - //TODO: this code path is only hit when start fails in dev mode very early in the process - //the recovery code will fail without this as it cannot read any properties such as - //the HTTP port or logging info - return ConfigUtils.emptyConfigBuilder().addDiscoveredSources().build(); + return ConfigUtils.configBuilder(true, true, LaunchMode.NORMAL).build(); } return config; } @@ -36,5 +34,8 @@ public static void setConfig(SmallRyeConfig config) { ConfigProviderResolver.instance().releaseConfig(QuarkusConfigFactory.config); } QuarkusConfigFactory.config = config; + if (QuarkusConfigFactory.config != null) { + ConfigProviderResolver.instance().registerConfig(config, Thread.currentThread().getContextClassLoader()); + } } } diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigBuilderCustomizer.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigBuilderCustomizer.java new file mode 100644 index 00000000000000..f7002876025af3 --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigBuilderCustomizer.java @@ -0,0 +1,23 @@ +package io.quarkus.runtime.configuration; + +import java.util.UUID; + +import io.smallrye.config.DotEnvConfigSourceProvider; +import io.smallrye.config.SmallRyeConfigBuilder; +import io.smallrye.config.SmallRyeConfigBuilderCustomizer; + +public class RuntimeConfigBuilderCustomizer implements SmallRyeConfigBuilderCustomizer { + @Override + public void configBuilder(final SmallRyeConfigBuilder builder) { + new QuarkusConfigBuilderCustomizer().configBuilder(builder); + + builder.withDefaultValue("quarkus.uuid", UUID.randomUUID().toString()); + + builder.forClassLoader(Thread.currentThread().getContextClassLoader()) + .addDefaultInterceptors() + .addDefaultSources() + .withSources(new ApplicationPropertiesConfigSourceLoader.InFileSystem()) + .withSources(new ApplicationPropertiesConfigSourceLoader.InClassPath()) + .withSources(new DotEnvConfigSourceProvider()); + } +} diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigSource.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigSource.java deleted file mode 100644 index eeb2f1117618fd..00000000000000 --- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigSource.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.quarkus.runtime.configuration; - -import java.lang.reflect.InvocationTargetException; -import java.util.Collections; - -import org.eclipse.microprofile.config.spi.ConfigSource; -import org.eclipse.microprofile.config.spi.ConfigSourceProvider; - -public class RuntimeConfigSource implements ConfigSourceProvider { - private final String configSourceClassName; - - public RuntimeConfigSource(final String configSourceClassName) { - this.configSourceClassName = configSourceClassName; - } - - @Override - public Iterable getConfigSources(final ClassLoader forClassLoader) { - try { - Class configSourceClass = (Class) forClassLoader.loadClass(configSourceClassName); - ConfigSource configSource = configSourceClass.getDeclaredConstructor().newInstance(); - return Collections.singleton(configSource); - } catch (ClassNotFoundException | InstantiationException | InvocationTargetException | NoSuchMethodException - | IllegalAccessException e) { - throw new ConfigurationException(e); - } - } -} diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigSourceFactory.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigSourceFactory.java deleted file mode 100644 index 355f22edd5baf6..00000000000000 --- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigSourceFactory.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.quarkus.runtime.configuration; - -import java.lang.reflect.InvocationTargetException; - -import io.smallrye.config.ConfigSourceFactory; - -public class RuntimeConfigSourceFactory implements ConfigSourceFactoryProvider { - private final String configSourceFactoryClassName; - - public RuntimeConfigSourceFactory(final String configSourceFactoryClassName) { - this.configSourceFactoryClassName = configSourceFactoryClassName; - } - - @Override - public ConfigSourceFactory getConfigSourceFactory(final ClassLoader forClassLoader) { - try { - Class configSourceFactoryClass = (Class) forClassLoader - .loadClass(configSourceFactoryClassName); - return configSourceFactoryClass.getDeclaredConstructor().newInstance(); - } catch (ClassNotFoundException | InstantiationException | InvocationTargetException | NoSuchMethodException - | IllegalAccessException e) { - throw new ConfigurationException(e); - } - } -} diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigSourceProvider.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigSourceProvider.java deleted file mode 100644 index 54e6e33290deee..00000000000000 --- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeConfigSourceProvider.java +++ /dev/null @@ -1,27 +0,0 @@ -package io.quarkus.runtime.configuration; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.microprofile.config.spi.ConfigSource; -import org.eclipse.microprofile.config.spi.ConfigSourceProvider; - -public class RuntimeConfigSourceProvider implements ConfigSourceProvider { - private final String configSourceProviderClassName; - - public RuntimeConfigSourceProvider(final String configSourceProviderClassName) { - this.configSourceProviderClassName = configSourceProviderClassName; - } - - @Override - public Iterable getConfigSources(final ClassLoader forClassLoader) { - try { - Class configSourceProviderClass = (Class) forClassLoader - .loadClass(configSourceProviderClassName); - ConfigSourceProvider configSourceProvider = configSourceProviderClass.getDeclaredConstructor().newInstance(); - return configSourceProvider.getConfigSources(forClassLoader); - } catch (ClassNotFoundException | InstantiationException | InvocationTargetException | NoSuchMethodException - | IllegalAccessException e) { - throw new ConfigurationException(e); - } - } -} diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeOverrideConfigSource.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeOverrideConfigSource.java index 02bd3d0d17d4d7..db6cd6bc3bc5c6 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeOverrideConfigSource.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/configuration/RuntimeOverrideConfigSource.java @@ -7,6 +7,8 @@ import org.eclipse.microprofile.config.spi.ConfigSource; +import io.smallrye.config.SmallRyeConfigBuilder; + /** * Config source that is used to handle {@code io.quarkus.bootstrap.app.StartupAction#overrideConfig(java.util.Map)} * @@ -62,4 +64,7 @@ public String getName() { return "Config Override Config Source"; } + public static void registerRuntimeOverrideConfigSource(SmallRyeConfigBuilder builder) { + builder.withSources(new RuntimeOverrideConfigSource(builder.getClassLoader())); + } } diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/StaticInitConfigBuilderCustomizer.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/StaticInitConfigBuilderCustomizer.java new file mode 100644 index 00000000000000..38849088016c4b --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/runtime/configuration/StaticInitConfigBuilderCustomizer.java @@ -0,0 +1,19 @@ +package io.quarkus.runtime.configuration; + +import io.smallrye.config.DotEnvConfigSourceProvider; +import io.smallrye.config.SmallRyeConfigBuilder; +import io.smallrye.config.SmallRyeConfigBuilderCustomizer; + +public class StaticInitConfigBuilderCustomizer implements SmallRyeConfigBuilderCustomizer { + @Override + public void configBuilder(final SmallRyeConfigBuilder builder) { + new QuarkusConfigBuilderCustomizer().configBuilder(builder); + + builder.forClassLoader(Thread.currentThread().getContextClassLoader()) + .addDefaultInterceptors() + .addDefaultSources() + .withSources(new ApplicationPropertiesConfigSourceLoader.InFileSystem()) + .withSources(new ApplicationPropertiesConfigSourceLoader.InClassPath()) + .withSources(new DotEnvConfigSourceProvider()); + } +} diff --git a/extensions/picocli/deployment/src/test/java/io/quarkus/picocli/deployment/AvailableConfigSourcesTest.java b/extensions/picocli/deployment/src/test/java/io/quarkus/picocli/deployment/AvailableConfigSourcesTest.java index eafb136eb75122..bbf6e13437fd0f 100644 --- a/extensions/picocli/deployment/src/test/java/io/quarkus/picocli/deployment/AvailableConfigSourcesTest.java +++ b/extensions/picocli/deployment/src/test/java/io/quarkus/picocli/deployment/AvailableConfigSourcesTest.java @@ -27,7 +27,7 @@ public class AvailableConfigSourcesTest { void sources() { ConfigValue value = config.getConfigValue("my.prop"); assertEquals("1234", value.getValue()); - assertEquals("RunTime Defaults", value.getConfigSourceName()); + assertEquals("DefaultValuesConfigSource", value.getConfigSourceName()); for (final ConfigSource configSource : config.getConfigSources()) { if (configSource.getName().contains("application.properties")) { diff --git a/extensions/resteasy-classic/rest-client/deployment/src/test/java/io/quarkus/restclient/configuration/RestClientOverrideRuntimeConfigTest.java b/extensions/resteasy-classic/rest-client/deployment/src/test/java/io/quarkus/restclient/configuration/RestClientOverrideRuntimeConfigTest.java index 9d6672277432ed..06f92ecfa218fe 100644 --- a/extensions/resteasy-classic/rest-client/deployment/src/test/java/io/quarkus/restclient/configuration/RestClientOverrideRuntimeConfigTest.java +++ b/extensions/resteasy-classic/rest-client/deployment/src/test/java/io/quarkus/restclient/configuration/RestClientOverrideRuntimeConfigTest.java @@ -39,7 +39,7 @@ public class RestClientOverrideRuntimeConfigTest { @Test void overrideConfig() { // Build time property recording - Optional specifiedDefaultValues = config.getConfigSource("RunTime Defaults"); + Optional specifiedDefaultValues = config.getConfigSource("DefaultValuesConfigSource"); assertTrue(specifiedDefaultValues.isPresent()); assertTrue(specifiedDefaultValues.get().getPropertyNames() .contains("io.quarkus.restclient.configuration.EchoClient/mp-rest/url")); diff --git a/extensions/resteasy-classic/rest-client/deployment/src/test/java/io/quarkus/restclient/configuration/RestClientRunTimeConfigSource.java b/extensions/resteasy-classic/rest-client/deployment/src/test/java/io/quarkus/restclient/configuration/RestClientRunTimeConfigSource.java index 6564cb70de796d..648022852df66a 100644 --- a/extensions/resteasy-classic/rest-client/deployment/src/test/java/io/quarkus/restclient/configuration/RestClientRunTimeConfigSource.java +++ b/extensions/resteasy-classic/rest-client/deployment/src/test/java/io/quarkus/restclient/configuration/RestClientRunTimeConfigSource.java @@ -41,7 +41,7 @@ public int getOrdinal() { private static boolean isRuntime() { for (ConfigSource configSource : ConfigProvider.getConfig().getConfigSources()) { - if (configSource.getName().equals("RunTime Defaults")) { + if (configSource.getName().equals("DefaultValuesConfigSource")) { return true; } } diff --git a/integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/ConfigBuilderCustomizer.java b/integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/ConfigBuilderCustomizer.java new file mode 100644 index 00000000000000..243fff08eb312d --- /dev/null +++ b/integration-tests/smallrye-config/src/main/java/io/quarkus/it/smallrye/config/ConfigBuilderCustomizer.java @@ -0,0 +1,13 @@ +package io.quarkus.it.smallrye.config; + +import io.quarkus.runtime.annotations.StaticInitSafe; +import io.smallrye.config.SmallRyeConfigBuilder; +import io.smallrye.config.SmallRyeConfigBuilderCustomizer; + +@StaticInitSafe +public class ConfigBuilderCustomizer implements SmallRyeConfigBuilderCustomizer { + @Override + public void configBuilder(final SmallRyeConfigBuilder builder) { + builder.withDefaultValue("exception.message", "This is an exception!"); + } +} diff --git a/integration-tests/smallrye-config/src/main/resources/META-INF/services/io.smallrye.config.SmallRyeConfigBuilderCustomizer b/integration-tests/smallrye-config/src/main/resources/META-INF/services/io.smallrye.config.SmallRyeConfigBuilderCustomizer new file mode 100644 index 00000000000000..9f865d958b21f5 --- /dev/null +++ b/integration-tests/smallrye-config/src/main/resources/META-INF/services/io.smallrye.config.SmallRyeConfigBuilderCustomizer @@ -0,0 +1 @@ +io.quarkus.it.smallrye.config.ConfigBuilderCustomizer diff --git a/integration-tests/smallrye-config/src/main/resources/config.properties b/integration-tests/smallrye-config/src/main/resources/config.properties index a057d5062f54c0..fc031ecfd4767b 100644 --- a/integration-tests/smallrye-config/src/main/resources/config.properties +++ b/integration-tests/smallrye-config/src/main/resources/config.properties @@ -1,3 +1 @@ config.properties=1234 - -exception.message=This is an exception! diff --git a/integration-tests/smallrye-config/src/main/resources/fallback.properties b/integration-tests/smallrye-config/src/main/resources/fallback.properties index 5403f0593c38c1..a7903ceca7189b 100644 --- a/integration-tests/smallrye-config/src/main/resources/fallback.properties +++ b/integration-tests/smallrye-config/src/main/resources/fallback.properties @@ -1,3 +1 @@ locations.fallback=1234 - -exception.message=This is an exception! diff --git a/integration-tests/smallrye-config/src/main/resources/test-profile.properties b/integration-tests/smallrye-config/src/main/resources/test-profile.properties index bcaec8b63ed77f..ad05d5b34bc4ca 100644 --- a/integration-tests/smallrye-config/src/main/resources/test-profile.properties +++ b/integration-tests/smallrye-config/src/main/resources/test-profile.properties @@ -1,3 +1 @@ test.profile.main=main - -exception.message=This is an exception! diff --git a/integration-tests/test-extension/extension/deployment/src/main/java/io/quarkus/extest/deployment/BuildTimeCustomConfigBuilder.java b/integration-tests/test-extension/extension/deployment/src/main/java/io/quarkus/extest/deployment/BuildTimeCustomConfigBuilder.java new file mode 100644 index 00000000000000..c52d2f5010593d --- /dev/null +++ b/integration-tests/test-extension/extension/deployment/src/main/java/io/quarkus/extest/deployment/BuildTimeCustomConfigBuilder.java @@ -0,0 +1,15 @@ +package io.quarkus.extest.deployment; + +import java.util.Map; + +import io.smallrye.config.PropertiesConfigSource; +import io.smallrye.config.SmallRyeConfigBuilder; +import io.smallrye.config.SmallRyeConfigBuilderCustomizer; + +public class BuildTimeCustomConfigBuilder implements SmallRyeConfigBuilderCustomizer { + @Override + public void configBuilder(final SmallRyeConfigBuilder builder) { + builder.withSources( + new PropertiesConfigSource(Map.of("prop.recorded.from.btconfigsource", "1234"), "BuildTimeConfigSource", 100)); + } +} diff --git a/integration-tests/test-extension/extension/deployment/src/main/resources/META-INF/services/io.smallrye.config.SmallRyeConfigBuilderCustomizer b/integration-tests/test-extension/extension/deployment/src/main/resources/META-INF/services/io.smallrye.config.SmallRyeConfigBuilderCustomizer new file mode 100644 index 00000000000000..69636f61699329 --- /dev/null +++ b/integration-tests/test-extension/extension/deployment/src/main/resources/META-INF/services/io.smallrye.config.SmallRyeConfigBuilderCustomizer @@ -0,0 +1 @@ +io.quarkus.extest.deployment.BuildTimeCustomConfigBuilder diff --git a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/ConfigBuilderTest.java b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/ConfigBuilderTest.java index 5254275f7dec63..41ebada063e1cd 100644 --- a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/ConfigBuilderTest.java +++ b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/ConfigBuilderTest.java @@ -1,6 +1,7 @@ package io.quarkus.config; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import jakarta.inject.Inject; @@ -30,4 +31,10 @@ void staticConfigBuilder() { void runTimeConfigBuilder() { assertEquals("1234", config.getRawValue("additional.builder.property")); } + + @Test + void buildTimeConfigBuilder() { + assertFalse(config.getConfigSource("BuildTimeConfigSource").isPresent()); + assertEquals("1234", config.getRawValue("prop.recorded.from.btconfigsource")); + } } diff --git a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/RecordedBuildProfileInRuntimeTest.java b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/RecordedBuildProfileInRuntimeTest.java index dd3c6ceb605ef5..b985f22b5cde0d 100644 --- a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/RecordedBuildProfileInRuntimeTest.java +++ b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/RecordedBuildProfileInRuntimeTest.java @@ -31,7 +31,7 @@ void recordedBuildProfileInRuntime() { ConfigValue profile = config.getConfigValue("quarkus.test.profile"); assertEquals("test", profile.getValue()); // Recorded by ProfileBuildStep - assertEquals("RunTime Defaults", profile.getConfigSourceName()); + assertEquals("DefaultValuesConfigSource", profile.getConfigSourceName()); Optional defaultValuesConfigSource = config.getConfigSource("DefaultValuesConfigSource"); assertTrue(defaultValuesConfigSource.isPresent()); diff --git a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/ConfigMappingTest.java b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/ConfigMappingTest.java index 0203c51396b5b0..7ceae79dd2046d 100644 --- a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/ConfigMappingTest.java +++ b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/ConfigMappingTest.java @@ -35,6 +35,6 @@ void mappingBuildTimeRunTime() { @Test void mappingRunTime() { - assertEquals("value", mappingBuildTimeRunTime.value()); + assertEquals("value", mappingRunTime.value()); } } diff --git a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/ConfiguredBeanTest.java b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/ConfiguredBeanTest.java index 962237d464860b..269e8cac7c023f 100644 --- a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/ConfiguredBeanTest.java +++ b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/ConfiguredBeanTest.java @@ -333,10 +333,10 @@ public void testBuiltTimeNamedMapWithProfiles() { @Test public void testConfigDefaultValuesSourceOrdinal() { - Optional source = config.getConfigSource("RunTime Defaults"); + Optional source = config.getConfigSource("DefaultValuesConfigSource"); assertTrue(source.isPresent()); ConfigSource defaultValues = source.get(); - assertEquals(Integer.MIN_VALUE + 100, defaultValues.getOrdinal()); + assertEquals(Integer.MIN_VALUE, defaultValues.getOrdinal()); ConfigSource applicationProperties = null; for (ConfigSource configSource : config.getConfigSources()) { @@ -355,7 +355,7 @@ public void testConfigDefaultValuesSourceOrdinal() { @Test public void testProfileDefaultValuesSource() { - Optional source = config.getConfigSource("RunTime Defaults"); + Optional source = config.getConfigSource("DefaultValuesConfigSource"); assertTrue(source.isPresent()); ConfigSource defaultValues = source.get(); @@ -388,7 +388,7 @@ void prefixConfig() { assertEquals("5678", anotherPrefixConfig.prop); assertEquals("5678", anotherPrefixConfig.map.get("prop")); - Optional runTimeDefaults = config.getConfigSource("RunTime Defaults"); + Optional runTimeDefaults = config.getConfigSource("DefaultValuesConfigSource"); assertTrue(runTimeDefaults.isPresent()); // java.version should not be recorded assertFalse(runTimeDefaults.get().getPropertyNames().contains("java.version")); @@ -402,7 +402,7 @@ void shadowBuildTimeToRunTimeConfig() { assertEquals("quarkus.bt.bt-config-value", btConfigValue.getName()); assertEquals("value", btConfigValue.getValue()); - Optional source = config.getConfigSource("RunTime Defaults"); + Optional source = config.getConfigSource("DefaultValuesConfigSource"); assertTrue(source.isPresent()); ConfigSource defaultValues = source.get(); diff --git a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/RuntimeDefaultsTest.java b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/RuntimeDefaultsTest.java index db522995ff2b9f..e208cbf882e0f6 100644 --- a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/RuntimeDefaultsTest.java +++ b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/RuntimeDefaultsTest.java @@ -29,14 +29,15 @@ public class RuntimeDefaultsTest { @Test void doNotRecordEnvRuntimeDefaults() { - Optional defaultValues = config.getConfigSource("RunTime Defaults"); + Optional 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")); } @Test void doNotRecordActiveUnprofiledPropertiesDefaults() { - Optional defaultValues = config.getConfigSource("RunTime Defaults"); + Optional defaultValues = config.getConfigSource("DefaultValuesConfigSource"); assertTrue(defaultValues.isPresent()); assertEquals("properties", config.getRawValue("bt.profile.record")); assertEquals("properties", defaultValues.get().getValue("%test.bt.profile.record")); diff --git a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/StaticInitSourcesTest.java b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/StaticInitSourcesTest.java index 8c72f140e5579f..49c72019e089cd 100644 --- a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/StaticInitSourcesTest.java +++ b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/extest/StaticInitSourcesTest.java @@ -5,7 +5,9 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import io.quarkus.extest.runtime.config.StaticInitNotSafeConfigBuilderCustomizer; import io.quarkus.extest.runtime.config.StaticInitNotSafeConfigSource; +import io.quarkus.extest.runtime.config.StaticInitSafeConfigBuilderCustomizer; import io.quarkus.extest.runtime.config.StaticInitSafeConfigSource; import io.quarkus.test.QuarkusUnitTest; @@ -15,9 +17,9 @@ public class StaticInitSourcesTest { .withApplicationRoot((jar) -> jar .addClasses(ConfiguredBean.class) // Don't change this to types, because of classloader class cast exception. - .addAsServiceProvider("org.eclipse.microprofile.config.spi.ConfigSource", - StaticInitSafeConfigSource.class.getName(), - StaticInitNotSafeConfigSource.class.getName()) + .addAsServiceProvider("io.smallrye.config.SmallRyeConfigBuilderCustomizer", + StaticInitSafeConfigBuilderCustomizer.class.getName(), + StaticInitNotSafeConfigBuilderCustomizer.class.getName()) .addAsResource("application.properties")); @Test diff --git a/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/EnvBuildTimeConfigSource.java b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/EnvBuildTimeConfigSource.java index ebfc255b2d0e2d..27d297ac883e4b 100644 --- a/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/EnvBuildTimeConfigSource.java +++ b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/EnvBuildTimeConfigSource.java @@ -6,8 +6,9 @@ public class EnvBuildTimeConfigSource extends EnvConfigSource { public EnvBuildTimeConfigSource() { - super(new HashMap() { + super(new HashMap<>() { { + put("QUARKUS_RT_RT_STRING_OPT", "changed"); put("BT_DO_NOT_RECORD", "env-source"); } }, Integer.MAX_VALUE); diff --git a/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/StaticInitNotSafeConfigBuilderCustomizer.java b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/StaticInitNotSafeConfigBuilderCustomizer.java new file mode 100644 index 00000000000000..a66bd73cd9e10e --- /dev/null +++ b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/StaticInitNotSafeConfigBuilderCustomizer.java @@ -0,0 +1,11 @@ +package io.quarkus.extest.runtime.config; + +import io.smallrye.config.SmallRyeConfigBuilder; +import io.smallrye.config.SmallRyeConfigBuilderCustomizer; + +public class StaticInitNotSafeConfigBuilderCustomizer implements SmallRyeConfigBuilderCustomizer { + @Override + public void configBuilder(final SmallRyeConfigBuilder builder) { + builder.withSources(new StaticInitNotSafeConfigSource()); + } +} diff --git a/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/StaticInitSafeConfigBuilderCustomizer.java b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/StaticInitSafeConfigBuilderCustomizer.java new file mode 100644 index 00000000000000..b2ba81d75c74ef --- /dev/null +++ b/integration-tests/test-extension/extension/runtime/src/main/java/io/quarkus/extest/runtime/config/StaticInitSafeConfigBuilderCustomizer.java @@ -0,0 +1,17 @@ +package io.quarkus.extest.runtime.config; + +import io.quarkus.runtime.annotations.StaticInitSafe; +import io.smallrye.config.SmallRyeConfigBuilder; +import io.smallrye.config.SmallRyeConfigBuilderCustomizer; + +@StaticInitSafe +public class StaticInitSafeConfigBuilderCustomizer implements SmallRyeConfigBuilderCustomizer { + public StaticInitSafeConfigBuilderCustomizer() { + System.out.println("StaticInitSafeConfigBuilderCustomizer.StaticInitSafeConfigBuilderCustomizer"); + } + + @Override + public void configBuilder(final SmallRyeConfigBuilder builder) { + builder.withSources(new StaticInitSafeConfigSource()); + } +} diff --git a/test-framework/common/src/main/java/io/quarkus/test/common/TestResourceManager.java b/test-framework/common/src/main/java/io/quarkus/test/common/TestResourceManager.java index 72b98a7f9764e1..9e088371f3fdee 100644 --- a/test-framework/common/src/main/java/io/quarkus/test/common/TestResourceManager.java +++ b/test-framework/common/src/main/java/io/quarkus/test/common/TestResourceManager.java @@ -25,13 +25,14 @@ import java.util.function.Function; import java.util.function.Predicate; -import org.eclipse.microprofile.config.spi.ConfigProviderResolver; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.IndexView; +import io.smallrye.config.SmallRyeConfigProviderResolver; + public class TestResourceManager implements Closeable { public static final String CLOSEABLE_NAME = TestResourceManager.class.getName() + ".closeable"; @@ -179,8 +180,8 @@ public void close() { } } try { - ConfigProviderResolver cpr = ConfigProviderResolver.instance(); - cpr.releaseConfig(cpr.getConfig()); + ((SmallRyeConfigProviderResolver) SmallRyeConfigProviderResolver.instance()) + .releaseConfig(Thread.currentThread().getContextClassLoader()); } catch (Throwable ignored) { } configProperties.clear();