diff --git a/bom/runtime/pom.xml b/bom/runtime/pom.xml
index 6dd65b47f29d9..e139f56e7b8cc 100644
--- a/bom/runtime/pom.xml
+++ b/bom/runtime/pom.xml
@@ -32,7 +32,7 @@
1.3.3
1.0.1
1.4.1
- 1.8.1
+ 1.8.4
2.2.2
2.4.2
2.0.2
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 161d2643da9dd..273525ababad2 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
@@ -71,7 +71,7 @@ public static SmallRyeConfigBuilder configBuilder(final boolean runTime, final b
final ApplicationPropertiesConfigSource.InJar inJar = new ApplicationPropertiesConfigSource.InJar();
final ApplicationPropertiesConfigSource.MpConfigInJar mpConfig = new ApplicationPropertiesConfigSource.MpConfigInJar();
builder.withSources(inFileSystem, inJar, mpConfig, new DotEnvConfigSource());
- builder.withInterceptors(new QuarkusProfileConfigSourceInterceptor(ProfileManager.getActiveProfile()));
+ builder.withProfile(ProfileManager.getActiveProfile());
builder.addDefaultInterceptors();
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (runTime) {
diff --git a/core/runtime/src/main/java/io/quarkus/runtime/configuration/QuarkusProfileConfigSourceInterceptor.java b/core/runtime/src/main/java/io/quarkus/runtime/configuration/QuarkusProfileConfigSourceInterceptor.java
deleted file mode 100644
index fe6a819c1f789..0000000000000
--- a/core/runtime/src/main/java/io/quarkus/runtime/configuration/QuarkusProfileConfigSourceInterceptor.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package io.quarkus.runtime.configuration;
-
-import io.smallrye.config.ConfigSourceInterceptorContext;
-import io.smallrye.config.ConfigValue;
-import io.smallrye.config.ProfileConfigSourceInterceptor;
-
-class QuarkusProfileConfigSourceInterceptor extends ProfileConfigSourceInterceptor {
- private final String profile;
-
- public QuarkusProfileConfigSourceInterceptor(final String profile) {
- super(profile);
- this.profile = profile;
- }
-
- @Override
- public ConfigValue getValue(final ConfigSourceInterceptorContext context, final String name) {
- if (profile != null) {
- final String normalizeName = normalizeName(name);
- final ConfigValue profileValue = context.proceed("%" + profile + "." + normalizeName);
- if (profileValue != null) {
- return profileValue.withName(normalizeName);
- }
- }
-
- return context.proceed(name);
- }
-
- private String normalizeName(final String name) {
- return name.startsWith("%" + profile + ".") ? name.substring(profile.length() + 2) : name;
- }
-}
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 89fddf0655b65..6b9be41d66154 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,18 +1,23 @@
package io.quarkus.runtime.configuration;
-import static java.util.Collections.singletonMap;
+import static java.util.stream.Collectors.toList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.stream.StreamSupport;
-import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import io.smallrye.config.ExpressionConfigSourceInterceptor;
+import io.smallrye.config.ProfileConfigSourceInterceptor;
import io.smallrye.config.PropertiesConfigSource;
import io.smallrye.config.SmallRyeConfig;
import io.smallrye.config.SmallRyeConfigBuilder;
@@ -21,7 +26,6 @@ public class ConfigProfileTestCase {
static ClassLoader classLoader;
static ConfigProviderResolver cpr;
- Config config;
@BeforeAll
public static void initConfig() {
@@ -38,31 +42,39 @@ public void doAfter() {
}
}
- private SmallRyeConfig buildConfig(Map configMap) {
- final SmallRyeConfigBuilder builder = new SmallRyeConfigBuilder();
- builder.withInterceptors(new QuarkusProfileConfigSourceInterceptor(ProfileManager.getActiveProfile()));
- builder.withSources(new PropertiesConfigSource(configMap, "test input", 500));
- final SmallRyeConfig config = (SmallRyeConfig) builder.build();
+ private SmallRyeConfigBuilder configBuilder(String... keyValues) {
+ return new SmallRyeConfigBuilder()
+ .addDefaultInterceptors()
+ .withSources(new PropertiesConfigSource(maps(keyValues), "test input", 500))
+ .withProfile(ProfileManager.getActiveProfile());
+ }
+
+ private SmallRyeConfig buildConfig(String... keyValues) {
+ final SmallRyeConfig config = configBuilder(keyValues).build();
cpr.registerConfig(config, classLoader);
- this.config = config;
return config;
}
- private Map maps(Map... maps) {
- Map out = new HashMap<>();
- for (Map map : maps) {
- out.putAll(map);
+ private Map maps(String... keyValues) {
+ if (keyValues.length % 2 != 0) {
+ throw new IllegalArgumentException("keyValues array must be a multiple of 2");
+ }
+
+ Map props = new HashMap<>();
+ for (int i = 0; i < keyValues.length; i += 2) {
+ props.put(keyValues[i], keyValues[i + 1]);
}
- return out;
+
+ return props;
}
@Test
- public void testDefaultProfile() {
- final SmallRyeConfig config = buildConfig(maps(
- singletonMap("foo.one", "v1"),
- singletonMap("foo.two", "v2"),
- singletonMap("%foo.foo.three", "f1"),
- singletonMap("%prod.foo.four", "v4")));
+ void defaultProfile() {
+ final SmallRyeConfig config = buildConfig(
+ "foo.one", "v1",
+ "foo.two", "v2",
+ "%foo.foo.three", "f1",
+ "%prod.foo.four", "v4");
assertEquals("v1", config.getValue("foo.one", String.class));
assertEquals("v2", config.getValue("foo.two", String.class));
assertFalse(config.getOptionalValue("foo.three", String.class).isPresent());
@@ -70,14 +82,14 @@ public void testDefaultProfile() {
}
@Test
- public void testOverridenProfile() {
+ void overriddenProfile() {
System.setProperty("quarkus.profile", "foo");
try {
- final SmallRyeConfig config = buildConfig(maps(
- singletonMap("foo.one", "v1"),
- singletonMap("foo.two", "v2"),
- singletonMap("%foo.foo.three", "f1"),
- singletonMap("%prod.foo.four", "v4")));
+ final SmallRyeConfig config = buildConfig(
+ "foo.one", "v1",
+ "foo.two", "v2",
+ "%foo.foo.three", "f1",
+ "%prod.foo.four", "v4");
assertEquals("v1", config.getValue("foo.one", String.class));
assertEquals("v2", config.getValue("foo.two", String.class));
assertEquals("f1", config.getValue("foo.three", String.class));
@@ -88,43 +100,195 @@ public void testOverridenProfile() {
}
@Test
- public void testBackwardCompatibleOverridenProfile() {
+ void overriddenProfileHigherOrdinal() {
System.setProperty("quarkus-profile", "foo");
try {
- final SmallRyeConfig config = buildConfig(maps(
- singletonMap("foo.one", "v1"),
- singletonMap("foo.two", "v2"),
- singletonMap("%foo.foo.three", "f1"),
- singletonMap("%prod.foo.four", "v4")));
- assertEquals("v1", config.getValue("foo.one", String.class));
- assertEquals("v2", config.getValue("foo.two", String.class));
- assertEquals("f1", config.getValue("foo.three", String.class));
- assertFalse(config.getOptionalValue("foo.four", String.class).isPresent());
+ final SmallRyeConfig config = configBuilder()
+ .withSources(new PropertiesConfigSource(maps("foo", "default"), "source", 1000))
+ .withSources(new PropertiesConfigSource(maps("%foo.foo", "profile"), "source", 100))
+ .build();
+
+ assertEquals("default", config.getRawValue("foo"));
} finally {
System.clearProperty("quarkus-profile");
}
}
@Test
- public void testBackwardCompatibleOrdinalProfile() {
+ void profileNoErrorOnExpansion() {
System.setProperty("quarkus-profile", "foo");
try {
- final SmallRyeConfigBuilder builder = new SmallRyeConfigBuilder();
- builder.withInterceptors(new QuarkusProfileConfigSourceInterceptor(ProfileManager.getActiveProfile()));
- builder.withSources(new PropertiesConfigSource(new HashMap() {
- {
- put("foo", "default");
- }
- }, "source", Integer.MAX_VALUE));
- builder.withSources(new PropertiesConfigSource(new HashMap() {
- {
- put("%foo.foo", "profile");
- }
- }, "source", Integer.MIN_VALUE));
- final SmallRyeConfig config = builder.build();
- cpr.registerConfig(config, classLoader);
-
- assertEquals("profile", config.getValue("foo", String.class));
+ final SmallRyeConfig config = configBuilder("foo", "${noExpansionAvailable}", "%foo.foo", "profile").build();
+
+ assertEquals("profile", config.getRawValue("foo"));
+ } finally {
+ System.clearProperty("quarkus-profile");
+ }
+ }
+
+ @Test
+ public void profile() {
+ System.setProperty("quarkus-profile", "prof");
+ try {
+ final SmallRyeConfig config = buildConfig("my.prop", "1", "%prof.my.prop", "2");
+
+ assertEquals("2", config.getValue("my.prop", String.class));
+
+ assertEquals("my.prop", config.getConfigValue("my.prop").getName());
+ assertEquals("my.prop", config.getConfigValue("%prof.my.prop").getName());
+ } finally {
+ System.clearProperty("quarkus-profile");
+ }
+ }
+
+ @Test
+ public void profileOnly() {
+ 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");
+ }
+ }
+
+ @Test
+ public void fallback() {
+ System.setProperty("quarkus-profile", "prof");
+ try {
+ final SmallRyeConfig config = buildConfig("my.prop", "1");
+
+ assertEquals("1", config.getRawValue("my.prop"));
+ } finally {
+ System.clearProperty("quarkus-profile");
+ }
+ }
+
+ @Test
+ public void expressions() {
+ 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("my.prop");
+ }
+ }
+
+ @Test
+ public void profileExpressions() {
+ System.setProperty("quarkus-profile", "prof");
+ System.setProperty("%prof.my.prop.profile", "2");
+ try {
+ final SmallRyeConfig config = buildConfig("my.prop", "1",
+ "%prof.my.prop", "${%prof.my.prop.profile}",
+ "%prof.my.prop.profile", "2");
+
+ assertEquals("2", config.getRawValue("my.prop"));
+ } finally {
+ System.clearProperty("quarkus-profile");
+ System.clearProperty("%prof.my.prop.profile");
+ }
+ }
+
+ @Test
+ public void customConfigProfile() {
+ System.setProperty("quarkus-profile", "prof");
+ try {
+ final SmallRyeConfig config = configBuilder()
+ .addDefaultSources()
+ .withSources(new PropertiesConfigSource(maps("my.prop", "1", "%prof.my.prop", "2"), "test", 100))
+ .build();
+
+ assertEquals("2", config.getValue("my.prop", String.class));
+ } finally {
+ System.clearProperty("quarkus-profile");
+ }
+ }
+
+ @Test
+ public void noConfigProfile() {
+ final SmallRyeConfig config = configBuilder()
+ .addDefaultSources()
+ .withSources(new PropertiesConfigSource(maps("my.prop", "1", "%prof.my.prop", "2"), "test", 100))
+ .withInterceptors(
+ new ProfileConfigSourceInterceptor("prof"),
+ new ExpressionConfigSourceInterceptor())
+ .build();
+
+ assertEquals("2", config.getRawValue("my.prop"));
+ }
+
+ @Test
+ public void priorityProfile() {
+ System.setProperty("quarkus-profile", "prof");
+ try {
+ final SmallRyeConfig config = configBuilder()
+ .addDefaultSources()
+ .withSources(new PropertiesConfigSource(maps("%prof.my.prop", "higher-profile"), "higher", 200))
+ .withSources(new PropertiesConfigSource(maps("my.prop", "lower", "%prof.my.prop", "lower-profile"), "lower",
+ 100))
+ .build();
+
+ assertEquals("higher-profile", config.getRawValue("my.prop"));
+ } finally {
+ System.clearProperty("quarkus-profile");
+ }
+ }
+
+ @Test
+ public void priorityOverrideProfile() {
+ System.setProperty("quarkus-profile", "prof");
+ try {
+ final SmallRyeConfig config = new SmallRyeConfigBuilder()
+ .addDefaultSources()
+ .withSources(new PropertiesConfigSource(maps("my.prop", "higher"), "higher", 200))
+ .withSources(new PropertiesConfigSource(maps("my.prop", "lower", "%prof.my.prop", "lower-profile"), "lower",
+ 100))
+ .build();
+
+ assertEquals("higher", config.getRawValue("my.prop"));
+ } finally {
+ System.clearProperty("quarkus-profile");
+ }
+ }
+
+ @Test
+ public void priorityProfileOverOriginal() {
+ System.setProperty("quarkus-profile", "prof");
+ try {
+ final SmallRyeConfig config = configBuilder()
+ .addDefaultSources()
+ .withSources(new PropertiesConfigSource(maps("my.prop", "higher", "%prof.my.prop", "higher-profile"),
+ "higher", 200))
+ .withSources(new PropertiesConfigSource(maps("my.prop", "lower", "%prof.my.prop", "lower-profile"), "lower",
+ 100))
+ .build();
+
+ assertEquals("higher-profile", config.getRawValue("my.prop"));
+ } finally {
+ System.clearProperty("quarkus-profile");
+ }
+ }
+
+ @Test
+ public void propertyNames() {
+ System.setProperty("quarkus-profile", "prof");
+ try {
+ final SmallRyeConfig config = buildConfig("my.prop", "1", "%prof.my.prop", "2", "%prof.prof.only", "1");
+
+ assertEquals("2", config.getRawValue("my.prop"));
+ assertEquals("1", config.getRawValue("prof.only"));
+
+ final List properties = StreamSupport.stream(config.getPropertyNames().spliterator(), false)
+ .collect(toList());
+ assertFalse(properties.contains("%prof.my.prop")); // We are removing profile properties in SmallRyeConfig and keep only the main name.
+ assertTrue(properties.contains("my.prop"));
+ assertTrue(properties.contains("prof.only"));
} finally {
System.clearProperty("quarkus-profile");
}