From 5cf686e7e5da947fbf8c6b362b2ba5d29ae52ea0 Mon Sep 17 00:00:00 2001 From: Roberto Cortez Date: Sat, 17 Sep 2022 12:35:13 +0100 Subject: [PATCH] Initial work to support multiple profiles --- .../RunTimeConfigurationGenerator.java | 5 -- .../deployment/steps/ProfileBuildStep.java | 16 ++--- .../runtime/ApplicationLifecycleManager.java | 5 +- .../java/io/quarkus/runtime/ConfigConfig.java | 18 ++++-- .../java/io/quarkus/runtime/LaunchMode.java | 14 +++-- .../quarkus/runtime/TopLevelRootConfig.java | 25 -------- .../runtime/configuration/ConfigUtils.java | 24 +++++++- .../runtime/configuration/ProfileManager.java | 6 ++ .../configuration/QuarkusConfigFactory.java | 9 +-- .../configuration/ConfigProfileTestCase.java | 60 +++++++++---------- .../deployment/BuildTimeEnabledProcessor.java | 6 +- .../console/ConfigEditorProcessor.java | 21 +++---- .../jpa/configurationless/CRUDResource.java | 4 +- .../RecordedBuildProfileInRuntimeTest.java | 41 +++++++++++++ 14 files changed, 145 insertions(+), 109 deletions(-) delete mode 100644 core/runtime/src/main/java/io/quarkus/runtime/TopLevelRootConfig.java create mode 100644 integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/RecordedBuildProfileInRuntimeTest.java 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 9b365bb8b99de..5f26e1176ce3e 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 @@ -69,7 +69,6 @@ import io.quarkus.runtime.configuration.ConfigurationException; import io.quarkus.runtime.configuration.HyphenateEnumConverter; import io.quarkus.runtime.configuration.NameIterator; -import io.quarkus.runtime.configuration.ProfileManager; import io.quarkus.runtime.configuration.PropertiesUtil; import io.quarkus.runtime.configuration.QuarkusConfigFactory; import io.quarkus.runtime.configuration.RuntimeConfigSource; @@ -210,9 +209,6 @@ public final class RunTimeConfigurationGenerator { static final MethodDescriptor OPT_IS_PRESENT = MethodDescriptor.ofMethod(Optional.class, "isPresent", boolean.class); static final MethodDescriptor OPT_OF = MethodDescriptor.ofMethod(Optional.class, "of", Optional.class, Object.class); - static final MethodDescriptor PM_SET_RUNTIME_DEFAULT_PROFILE = MethodDescriptor.ofMethod(ProfileManager.class, - "setRuntimeDefaultProfile", void.class, String.class); - static final MethodDescriptor SB_NEW = MethodDescriptor.ofConstructor(StringBuilder.class); static final MethodDescriptor SB_NEW_STR = MethodDescriptor.ofConstructor(StringBuilder.class, String.class); static final MethodDescriptor SB_APPEND_STRING = MethodDescriptor.ofMethod(StringBuilder.class, "append", @@ -365,7 +361,6 @@ public static final class GenerateOperation implements AutoCloseable { cc.getFieldCreator(C_UNKNOWN_RUNTIME).setModifiers(Opcodes.ACC_STATIC | Opcodes.ACC_FINAL); clinit.writeStaticField(C_UNKNOWN_RUNTIME, clinit.newInstance(AL_NEW)); - clinit.invokeStaticMethod(PM_SET_RUNTIME_DEFAULT_PROFILE, clinit.load(ProfileManager.getActiveProfile())); clinitNameBuilder = clinit.newInstance(SB_NEW); // static field containing the instance of the class - is set when createBootstrapConfig is run diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/ProfileBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/ProfileBuildStep.java index b3c6f5ce6e820..cc1950662174a 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/ProfileBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/ProfileBuildStep.java @@ -1,23 +1,15 @@ package io.quarkus.deployment.steps; +import org.eclipse.microprofile.config.ConfigProvider; + import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.LaunchModeBuildItem; import io.quarkus.deployment.builditem.RunTimeConfigurationDefaultBuildItem; -import io.quarkus.runtime.LaunchMode; public class ProfileBuildStep { @BuildStep RunTimeConfigurationDefaultBuildItem defaultProfile(LaunchModeBuildItem launchModeBuildItem) { - return new RunTimeConfigurationDefaultBuildItem("quarkus.profile", - getProfileValue(launchModeBuildItem.getLaunchMode())); - } - - private String getProfileValue(LaunchMode launchMode) { - if (launchMode == LaunchMode.DEVELOPMENT) { - return "dev"; - } else if (launchMode == LaunchMode.TEST) { - return "test"; - } - return "prod"; + return new RunTimeConfigurationDefaultBuildItem(launchModeBuildItem.getLaunchMode().getProfileKey(), + ConfigProvider.getConfig().getConfigValue(launchModeBuildItem.getLaunchMode().getProfileKey()).getValue()); } } diff --git a/core/runtime/src/main/java/io/quarkus/runtime/ApplicationLifecycleManager.java b/core/runtime/src/main/java/io/quarkus/runtime/ApplicationLifecycleManager.java index 1d5893b5ec6b4..e6423f8187550 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/ApplicationLifecycleManager.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/ApplicationLifecycleManager.java @@ -25,8 +25,8 @@ import io.quarkus.bootstrap.logging.InitialConfigurator; import io.quarkus.bootstrap.runner.RunnerClassLoader; +import io.quarkus.runtime.configuration.ConfigUtils; import io.quarkus.runtime.configuration.ConfigurationException; -import io.quarkus.runtime.configuration.ProfileManager; import io.quarkus.runtime.graal.DiagnosticPrinter; import sun.misc.Signal; import sun.misc.SignalHandler; @@ -192,8 +192,9 @@ public static void run(Application application, Class * Relocation of the Config configurations to the Quarkus namespace is done in * {@link io.quarkus.runtime.configuration.ConfigUtils#configBuilder}. */ @ConfigRoot(name = ConfigItem.PARENT, phase = ConfigPhase.RUN_TIME) public class ConfigConfig { /** - * Additional config locations to be loaded with the Config. The configuration support multiple locations - * separated by a comma and each must represent a valid {@link java.net.URI}. + * Profile that will be active when Quarkus launches. */ - @ConfigItem(name = "config.locations") - public Optional> locations; + @ConfigItem(name = "profile", defaultValue = "prod") + public Optional profile; /** * Accepts a single configuration profile name. If a configuration property cannot be found in the current active @@ -31,10 +30,17 @@ public class ConfigConfig { @ConfigItem(name = "config.profile.parent") public Optional profileParent; + /** + * Additional config locations to be loaded with the Config. The configuration support multiple locations + * separated by a comma and each must represent a valid {@link java.net.URI}. + */ + @ConfigItem(name = "config.locations") + public Optional> locations; + /** * A property that allows accessing a generated UUID. * It generates that UUID at startup time. So it changes between two starts including in dev mode. - * + *
* Access this generated UUID using expressions: `${quarkus.uuid}`. */ @ConfigItem(name = "uuid") diff --git a/core/runtime/src/main/java/io/quarkus/runtime/LaunchMode.java b/core/runtime/src/main/java/io/quarkus/runtime/LaunchMode.java index 2ad440b3641ad..ad109bd8b4020 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/LaunchMode.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/LaunchMode.java @@ -8,15 +8,15 @@ public enum LaunchMode { * A normal production build. At the moment this can be both native image or * JVM mode, but eventually these will likely be split */ - NORMAL("prod"), + NORMAL("prod", "quarkus.profile"), /** * quarkus:dev or an IDE launch (when we support IDE launch) */ - DEVELOPMENT("dev"), + DEVELOPMENT("dev", "quarkus.profile"), /** * a test run */ - TEST("test"); + TEST("test", "quarkus.test.profile"); public boolean isDevOrTest() { return this != NORMAL; @@ -30,15 +30,21 @@ public static boolean isRemoteDev() { } private final String defaultProfile; + private final String profileKey; - LaunchMode(String defaultProfile) { + LaunchMode(final String defaultProfile, final String profileKey) { this.defaultProfile = defaultProfile; + this.profileKey = profileKey; } public String getDefaultProfile() { return defaultProfile; } + public String getProfileKey() { + return profileKey; + } + /** * * @return The current launch mode diff --git a/core/runtime/src/main/java/io/quarkus/runtime/TopLevelRootConfig.java b/core/runtime/src/main/java/io/quarkus/runtime/TopLevelRootConfig.java deleted file mode 100644 index 6fcffe4e28612..0000000000000 --- a/core/runtime/src/main/java/io/quarkus/runtime/TopLevelRootConfig.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.quarkus.runtime; - -import java.util.Optional; - -import io.quarkus.runtime.annotations.ConfigItem; -import io.quarkus.runtime.annotations.ConfigPhase; -import io.quarkus.runtime.annotations.ConfigRoot; - -/** - * This is used currently only to suppress warnings about unknown properties - * when the user supplies something like: -Dquarkus.profile=someProfile - * - * TODO refactor code to actually use these values - */ -@ConfigRoot(name = ConfigItem.PARENT, phase = ConfigPhase.RUN_TIME) -public class TopLevelRootConfig { - - /** - * Profile that will be active when Quarkus launches - * - * Default value is 'prod' - */ - @ConfigItem - Optional profile; -} 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 8b602411e5a77..42227069a1816 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 @@ -134,7 +134,20 @@ public static SmallRyeConfigBuilder configBuilder(final boolean runTime, final b public static SmallRyeConfigBuilder emptyConfigBuilder() { SmallRyeConfigBuilder builder = new SmallRyeConfigBuilder(); - builder.withDefaultValue(SMALLRYE_CONFIG_PROFILE, ProfileManager.getActiveProfile()); + 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 @@ -178,6 +191,7 @@ public OptionalInt getPriority() { @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); return new FallbackConfigSourceInterceptor(fallbacks); @@ -269,6 +283,14 @@ public static void addMapping(SmallRyeConfigBuilder builder, String mappingClass } } + public static List getProfiles() { + return ConfigProvider.getConfig().unwrap(SmallRyeConfig.class).getProfiles(); + } + + public static boolean isProfileActive(final String profile) { + return getProfiles().contains(profile); + } + /** * Checks if a property is present in the current Configuration. *

diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/ProfileManager.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/ProfileManager.java index ce264bbbc1fb5..c1a58d7963778 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/ProfileManager.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/configuration/ProfileManager.java @@ -40,6 +40,12 @@ public static void setRuntimeDefaultProfile(final String profile) { } //NOTE: changes made here must be replicated in BootstrapProfile + + /** + * @deprecated This method is not suited to multiple profiles, because it returns a single string. Please use + * {@link ConfigUtils#getProfiles()} instead, which returns a List of profiles. + */ + @Deprecated public static String getActiveProfile() { if (launchMode == LaunchMode.TEST) { String profile = System.getProperty(QUARKUS_TEST_PROFILE_PROP); 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 0ea4c1503e66a..eafd80022e91b 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 @@ -26,14 +26,7 @@ public SmallRyeConfig getConfigFor(final SmallRyeConfigProviderResolver configPr //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 configProviderResolver.getBuilder().forClassLoader(classLoader) - .addDefaultSources() - .addDefaultInterceptors() - .addDiscoveredSources() - .addDiscoveredConverters() - .addDiscoveredInterceptors() - .withProfile(ProfileManager.getActiveProfile()) - .build(); + return ConfigUtils.emptyConfigBuilder().addDefaultSources().addDiscoveredSources().build(); } return config; } diff --git a/core/runtime/src/test/java/io/quarkus/runtime/configuration/ConfigProfileTestCase.java b/core/runtime/src/test/java/io/quarkus/runtime/configuration/ConfigProfileTestCase.java index 8bbcf1fdc8805..ed3f9c559fb63 100644 --- a/core/runtime/src/test/java/io/quarkus/runtime/configuration/ConfigProfileTestCase.java +++ b/core/runtime/src/test/java/io/quarkus/runtime/configuration/ConfigProfileTestCase.java @@ -1,5 +1,6 @@ package io.quarkus.runtime.configuration; +import static io.quarkus.runtime.configuration.ConfigUtils.emptyConfigBuilder; import static java.util.stream.Collectors.toList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -20,17 +21,14 @@ import io.smallrye.config.SmallRyeConfigBuilder; public class ConfigProfileTestCase { - private SmallRyeConfigBuilder configBuilder(String... keyValues) { - return new SmallRyeConfigBuilder() - .addDefaultInterceptors() - .withSources(new PropertiesConfigSource(maps(keyValues), "test input", 500)) - .withProfile(ProfileManager.getActiveProfile()); + return emptyConfigBuilder() + .addDefaultSources() + .withSources(new PropertiesConfigSource(maps(keyValues), "test input", 500)); } private SmallRyeConfig buildConfig(String... keyValues) { - final SmallRyeConfig config = configBuilder(keyValues).build(); - return config; + return configBuilder(keyValues).build(); } private Map maps(String... keyValues) { @@ -79,7 +77,7 @@ void overriddenProfile() { @Test void overriddenProfileHigherOrdinal() { - System.setProperty("quarkus-profile", "foo"); + System.setProperty("quarkus.profile", "foo"); try { final SmallRyeConfig config = configBuilder() .withSources(new PropertiesConfigSource(maps("foo", "default"), "source", 1000)) @@ -88,25 +86,25 @@ void overriddenProfileHigherOrdinal() { assertEquals("default", config.getRawValue("foo")); } finally { - System.clearProperty("quarkus-profile"); + System.clearProperty("quarkus.profile"); } } @Test void profileNoErrorOnExpansion() { - System.setProperty("quarkus-profile", "foo"); + System.setProperty("quarkus.profile", "foo"); try { final SmallRyeConfig config = configBuilder("foo", "${noExpansionAvailable}", "%foo.foo", "profile").build(); assertEquals("profile", config.getRawValue("foo")); } finally { - System.clearProperty("quarkus-profile"); + System.clearProperty("quarkus.profile"); } } @Test public void profile() { - System.setProperty("quarkus-profile", "prof"); + System.setProperty("quarkus.profile", "prof"); try { final SmallRyeConfig config = buildConfig("my.prop", "1", "%prof.my.prop", "2"); @@ -115,51 +113,51 @@ public void profile() { assertEquals("my.prop", config.getConfigValue("my.prop").getName()); assertEquals("my.prop", config.getConfigValue("%prof.my.prop").getName()); } finally { - System.clearProperty("quarkus-profile"); + System.clearProperty("quarkus.profile"); } } @Test public void profileOnly() { - System.setProperty("quarkus-profile", "prof"); + System.setProperty("quarkus.profile", "prof"); try { final SmallRyeConfig config = buildConfig("my.prop", "1", "%prof.my.prop", "2"); assertEquals("2", config.getRawValue("my.prop")); } finally { - System.clearProperty("quarkus-profile"); + System.clearProperty("quarkus.profile"); } } @Test public void fallback() { - System.setProperty("quarkus-profile", "prof"); + System.setProperty("quarkus.profile", "prof"); try { final SmallRyeConfig config = buildConfig("my.prop", "1"); assertEquals("1", config.getRawValue("my.prop")); } finally { - System.clearProperty("quarkus-profile"); + System.clearProperty("quarkus.profile"); } } @Test public void expressions() { - System.setProperty("quarkus-profile", "prof"); + System.setProperty("quarkus.profile", "prof"); System.setProperty("my.prop", "1"); try { final SmallRyeConfig config = buildConfig("my.prop", "1", "%prof.my.prop", "${my.prop}"); assertThrows(IllegalArgumentException.class, () -> config.getRawValue("my.prop")); } finally { - System.clearProperty("quarkus-profile"); + System.clearProperty("quarkus.profile"); System.clearProperty("my.prop"); } } @Test public void profileExpressions() { - System.setProperty("quarkus-profile", "prof"); + System.setProperty("quarkus.profile", "prof"); System.setProperty("%prof.my.prop.profile", "2"); try { final SmallRyeConfig config = buildConfig("my.prop", "1", @@ -168,14 +166,14 @@ public void profileExpressions() { assertEquals("2", config.getRawValue("my.prop")); } finally { - System.clearProperty("quarkus-profile"); + System.clearProperty("quarkus.profile"); System.clearProperty("%prof.my.prop.profile"); } } @Test public void customConfigProfile() { - System.setProperty("quarkus-profile", "prof"); + System.setProperty("quarkus.profile", "prof"); try { final SmallRyeConfig config = configBuilder() .addDefaultSources() @@ -184,7 +182,7 @@ public void customConfigProfile() { assertEquals("2", config.getValue("my.prop", String.class)); } finally { - System.clearProperty("quarkus-profile"); + System.clearProperty("quarkus.profile"); } } @@ -203,7 +201,7 @@ public void noConfigProfile() { @Test public void priorityProfile() { - System.setProperty("quarkus-profile", "prof"); + System.setProperty("quarkus.profile", "prof"); try { final SmallRyeConfig config = configBuilder() .addDefaultSources() @@ -214,13 +212,13 @@ public void priorityProfile() { assertEquals("higher-profile", config.getRawValue("my.prop")); } finally { - System.clearProperty("quarkus-profile"); + System.clearProperty("quarkus.profile"); } } @Test public void priorityOverrideProfile() { - System.setProperty("quarkus-profile", "prof"); + System.setProperty("quarkus.profile", "prof"); try { final SmallRyeConfig config = new SmallRyeConfigBuilder() .addDefaultSources() @@ -231,13 +229,13 @@ public void priorityOverrideProfile() { assertEquals("higher", config.getRawValue("my.prop")); } finally { - System.clearProperty("quarkus-profile"); + System.clearProperty("quarkus.profile"); } } @Test public void priorityProfileOverOriginal() { - System.setProperty("quarkus-profile", "prof"); + System.setProperty("quarkus.profile", "prof"); try { final SmallRyeConfig config = configBuilder() .addDefaultSources() @@ -249,13 +247,13 @@ public void priorityProfileOverOriginal() { assertEquals("higher-profile", config.getRawValue("my.prop")); } finally { - System.clearProperty("quarkus-profile"); + System.clearProperty("quarkus.profile"); } } @Test public void propertyNames() { - System.setProperty("quarkus-profile", "prof"); + System.setProperty("quarkus.profile", "prof"); try { final SmallRyeConfig config = buildConfig("my.prop", "1", "%prof.my.prop", "2", "%prof.prof.only", "1"); @@ -268,7 +266,7 @@ public void propertyNames() { assertTrue(properties.contains("my.prop")); assertTrue(properties.contains("prof.only")); } finally { - System.clearProperty("quarkus-profile"); + System.clearProperty("quarkus.profile"); } } } diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BuildTimeEnabledProcessor.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BuildTimeEnabledProcessor.java index caa4d1c7d521f..af0554f12876c 100644 --- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BuildTimeEnabledProcessor.java +++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BuildTimeEnabledProcessor.java @@ -37,7 +37,7 @@ import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.CombinedIndexBuildItem; -import io.quarkus.runtime.configuration.ProfileManager; +import io.quarkus.runtime.configuration.ConfigUtils; public class BuildTimeEnabledProcessor { @@ -60,7 +60,7 @@ void ifBuildProfile(CombinedIndexBuildItem index, BuildProducer annotationInstances = index.getIndex().getAnnotations(IF_BUILD_PROFILE); for (AnnotationInstance instance : annotationInstances) { String profileOnInstance = instance.value().asString(); - boolean enabled = profileOnInstance.equals(ProfileManager.getActiveProfile()); + boolean enabled = ConfigUtils.isProfileActive(profileOnInstance); if (enabled) { LOGGER.debug("Enabling " + instance.target() + " since the profile value matches the active profile."); } else { @@ -75,7 +75,7 @@ void unlessBuildProfile(CombinedIndexBuildItem index, BuildProducer annotationInstances = index.getIndex().getAnnotations(UNLESS_BUILD_PROFILE); for (AnnotationInstance instance : annotationInstances) { String profileOnInstance = instance.value().asString(); - boolean enabled = !profileOnInstance.equals(ProfileManager.getActiveProfile()); + boolean enabled = !ConfigUtils.isProfileActive(profileOnInstance); if (enabled) { LOGGER.debug("Enabling " + instance.target() + " since the profile value does not match the active profile."); } else { diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/ConfigEditorProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/ConfigEditorProcessor.java index 6a64312e47773..456320c9d91e3 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/ConfigEditorProcessor.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/ConfigEditorProcessor.java @@ -46,7 +46,7 @@ import io.quarkus.devconsole.runtime.spi.DevConsolePostHandler; import io.quarkus.devconsole.spi.DevConsoleRouteBuildItem; import io.quarkus.devconsole.spi.DevConsoleRuntimeTemplateInfoBuildItem; -import io.quarkus.runtime.configuration.ProfileManager; +import io.quarkus.runtime.configuration.ConfigUtils; import io.quarkus.vertx.http.runtime.devmode.ConfigDescription; import io.quarkus.vertx.http.runtime.devmode.ConfigDescriptionsManager; import io.quarkus.vertx.http.runtime.devmode.ConfigDescriptionsRecorder; @@ -215,18 +215,22 @@ static void updateConfig(Map values) { if (values != null && !values.isEmpty()) { try { Path configPath = getConfigPath(); - String profile = ProfileManager.getActiveProfile(); + List profiles = ConfigUtils.getProfiles(); List lines = Files.readAllLines(configPath); for (Map.Entry entry : values.entrySet()) { String name = entry.getKey(); String value = entry.getValue(); - name = !profile.equals(DEVELOPMENT.getDefaultProfile()) ? "%" + profile + "." + name : name; int nameLine = -1; for (int i = 0, linesSize = lines.size(); i < linesSize; i++) { - final String line = lines.get(i); - if (line.startsWith(name + "=")) { - nameLine = i; - break; + String line = lines.get(i); + for (String profile : profiles) { + String profileName = !profile.equals(DEVELOPMENT.getDefaultProfile()) ? "%" + profile + "." + name + : name; + if (line.startsWith(profileName + "=")) { + name = profileName; + nameLine = i; + break; + } } } @@ -259,9 +263,6 @@ static void updateConfig(Map values) { static void setConfig(String value) { try { Path configPath = getConfigPath(); - String profile = ProfileManager.getActiveProfile(); - List lines = Files.readAllLines(configPath); - try (BufferedWriter writer = Files.newBufferedWriter(configPath)) { if (value == null || value.isEmpty()) { writer.newLine(); diff --git a/integration-tests/jpa/src/main/java/io/quarkus/it/jpa/configurationless/CRUDResource.java b/integration-tests/jpa/src/main/java/io/quarkus/it/jpa/configurationless/CRUDResource.java index faec3b6ddcc51..f51b59dacb89f 100644 --- a/integration-tests/jpa/src/main/java/io/quarkus/it/jpa/configurationless/CRUDResource.java +++ b/integration-tests/jpa/src/main/java/io/quarkus/it/jpa/configurationless/CRUDResource.java @@ -17,7 +17,7 @@ import org.hibernate.internal.SessionImpl; import io.quarkus.runtime.LaunchMode; -import io.quarkus.runtime.configuration.ProfileManager; +import io.quarkus.runtime.configuration.ConfigUtils; /** * @author Emmanuel Bernard emmanuel@hibernate.org @@ -82,7 +82,7 @@ public Map createUserTransaction() { @Transactional @Path("/import") public Map get() { - boolean isProdMode = ProfileManager.getActiveProfile().equals(LaunchMode.NORMAL.getDefaultProfile()); + boolean isProdMode = ConfigUtils.isProfileActive(LaunchMode.NORMAL.getDefaultProfile()); Gift gift = em.find(Gift.class, 100000L); Map map = new HashMap<>(); // Native tests are run under the 'prod' profile for now. In NORMAL mode, Quarkus doesn't execute the SQL import file 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 new file mode 100644 index 0000000000000..3d938f1b963b9 --- /dev/null +++ b/integration-tests/test-extension/extension/deployment/src/test/java/io/quarkus/config/RecordedBuildProfileInRuntimeTest.java @@ -0,0 +1,41 @@ +package io.quarkus.config; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Optional; + +import javax.inject.Inject; + +import org.eclipse.microprofile.config.spi.ConfigSource; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.smallrye.config.ConfigValue; +import io.smallrye.config.SmallRyeConfig; + +public class RecordedBuildProfileInRuntimeTest { + @RegisterExtension + static final QuarkusUnitTest TEST = new QuarkusUnitTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)) + .withConfigurationResource("application.properties"); + + @Inject + SmallRyeConfig config; + + @Test + void recordedBuildProfileInRuntime() { + ConfigValue profile = config.getConfigValue("quarkus.test.profile"); + assertEquals("test", profile.getValue()); + // Recorded by ProfileBuildStep + assertEquals("RunTime Defaults", profile.getConfigSourceName()); + + Optional defaultValuesConfigSource = config.getConfigSource("DefaultValuesConfigSource"); + assertTrue(defaultValuesConfigSource.isPresent()); + // The default set in ConfigUtils, based on the LaunchMode + assertEquals("test", defaultValuesConfigSource.get().getValue("quarkus.test.profile")); + } +}