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 b841edc24ee9f..111b6171fdba6 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 @@ -403,11 +403,6 @@ public static final class GenerateOperation implements AutoCloseable { clinit.invokeStaticMethod(CU_ADD_SOURCE_FACTORY_PROVIDER, buildTimeBuilder, clinit.newInstance(RCSF_NEW, clinit.load(discoveredConfigSourceFactory))); } - // add mappings - for (ConfigClassWithPrefix configMapping : staticConfigMappings) { - clinit.invokeStaticMethod(CU_WITH_MAPPING, buildTimeBuilder, - clinit.load(configMapping.getKlass().getName()), clinit.load(configMapping.getPrefix())); - } // additional config builders ResultHandle configBuilders = clinit.newInstance(AL_NEW); @@ -468,11 +463,12 @@ public void run() { reinit.invokeStaticMethod(CU_ADD_SOURCE_FACTORY_PROVIDER, buildTimeBuilder, reinit.newInstance(RCSF_NEW, reinit.load(discoveredConfigSourceFactory))); } - // add mappings - for (ConfigClassWithPrefix configMapping : staticConfigMappings) { - reinit.invokeStaticMethod(CU_WITH_MAPPING, buildTimeBuilder, - reinit.load(configMapping.getKlass().getName()), reinit.load(configMapping.getPrefix())); + // 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); ResultHandle clinitConfig = reinit.checkCast(reinit.invokeVirtualMethod(SRCB_BUILD, buildTimeBuilder), SmallRyeConfig.class); @@ -555,12 +551,6 @@ public void run() { readBootstrapConfig.invokeStaticMethod(CU_ADD_SOURCE_FACTORY_PROVIDER, bootstrapBuilder, readBootstrapConfig.newInstance(RCSF_NEW, readBootstrapConfig.load(discoveredConfigSourceFactory))); } - // add bootstrap mappings - for (ConfigClassWithPrefix configMapping : staticConfigMappings) { - readBootstrapConfig.invokeStaticMethod(CU_WITH_MAPPING, bootstrapBuilder, - readBootstrapConfig.load(configMapping.getKlass().getName()), - readBootstrapConfig.load(configMapping.getPrefix())); - } // add bootstrap config builders ResultHandle bootstrapConfigBuilders = readBootstrapConfig.newInstance(AL_NEW); @@ -649,12 +639,6 @@ public void run() { readConfig.newInstance(RCSF_NEW, readConfig.load(discoveredConfigSourceFactory))); } - // add mappings - for (ConfigClassWithPrefix configMapping : runtimeConfigMappings) { - readConfig.invokeStaticMethod(CU_WITH_MAPPING, runTimeBuilder, - readConfig.load(configMapping.getKlass().getName()), readConfig.load(configMapping.getPrefix())); - } - // additional config builders ResultHandle configBuilders = readConfig.newInstance(AL_NEW); for (String configBuilder : runtimeConfigBuilders) { 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 111a05329b92f..4a9aa31c796c6 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 @@ -88,6 +88,10 @@ public class ConfigGenerationBuildStep { SmallRyeConfigBuilder.class, "withSources", SmallRyeConfigBuilder.class, ConfigSource[].class); + private static final MethodDescriptor WITH_MAPPING = MethodDescriptor.ofMethod( + SmallRyeConfigBuilder.class, "withMapping", + SmallRyeConfigBuilder.class, Class.class, String.class); + @BuildStep void staticInitSources( BuildProducer staticInitConfigSourceProviderBuildItem, @@ -217,6 +221,33 @@ void extensionMappings(ConfigurationBuildItem configItem, } } + @BuildStep + void builderMappings( + ConfigurationBuildItem configItem, + List configMappings, + BuildProducer generatedClass, + BuildProducer reflectiveClass, + BuildProducer staticInitConfigBuilder, + BuildProducer runTimeConfigBuilder) { + + // 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)); + + // 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)); + } + /** * Generate the Config class that instantiates MP Config and holds all the config objects */ @@ -256,6 +287,7 @@ void generateConfigClass( staticConfigSourceFactories.addAll(staticInitConfigSourceFactories.stream() .map(StaticInitConfigSourceFactoryBuildItem::getFactoryClassName).collect(Collectors.toSet())); + // TODO - duplicated now builderMappings. Still required to filter the unknown properties Set staticMappings = new HashSet<>(); staticMappings.addAll(staticSafeConfigMappings(configMappings)); staticMappings.addAll(configItem.getReadResult().getBuildTimeRunTimeMappings()); @@ -484,6 +516,34 @@ private static void generateDefaultsConfigSource( reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, false, className)); } + private static void generateMappingsConfigBuilder( + BuildProducer generatedClass, + BuildProducer reflectiveClass, + String className, + Set mappings) { + + try (ClassCreator classCreator = ClassCreator.builder() + .classOutput(new GeneratedClassGizmoAdaptor(generatedClass, true)) + .className(className) + .interfaces(ConfigBuilder.class) + .setFinal(true) + .build()) { + + MethodCreator method = classCreator.getMethodCreator(CONFIG_BUILDER); + ResultHandle configBuilder = method.getMethodParam(0); + + for (ConfigClassWithPrefix mapping : mappings) { + method.invokeVirtualMethod(WITH_MAPPING, configBuilder, + method.loadClass(mapping.getKlass()), + method.load(mapping.getPrefix())); + } + + method.returnValue(configBuilder); + } + + reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, false, className)); + } + private static Set discoverService( Class serviceClass, BuildProducer reflectiveClass) throws IOException { diff --git a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/SecretKeysConfigTest.java b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/SecretKeysConfigTest.java index 120c4c6da57ec..c299b5b3de497 100644 --- a/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/SecretKeysConfigTest.java +++ b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/SecretKeysConfigTest.java @@ -39,7 +39,7 @@ void secrets() { } @ConfigMapping(prefix = "secrets.my") - interface MappingSecret { + public interface MappingSecret { String secret(); } }