Skip to content

Commit 71a57e5

Browse files
committed
Introduce SmallRyeConfig.subset
- Fixes #981
1 parent 6bd3669 commit 71a57e5

File tree

3 files changed

+119
-22
lines changed

3 files changed

+119
-22
lines changed

implementation/src/main/java/io/smallrye/config/SmallRyeConfig.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,6 @@ public <K, V> Map<K, V> getValuesAsMap(String name, Converter<K> keyConverter, C
223223
}
224224

225225
/**
226-
*
227226
* This method handles calls from both {@link Config#getValue} and {@link Config#getOptionalValue}.<br>
228227
*/
229228
@SuppressWarnings("unchecked")
@@ -246,17 +245,17 @@ public <T> T getValue(String name, Converter<T> converter) {
246245
/**
247246
* This method handles converting values for both CDI injections and programatical calls.<br>
248247
* <br>
249-
*
248+
* <p>
250249
* Calls for converting non-optional values ({@link Config#getValue} and "Injecting Native Values")
251250
* should throw an {@link Exception} for each of the following:<br>
252-
*
251+
* <p>
253252
* 1. {@link IllegalArgumentException} - if the property cannot be converted by the {@link Converter} to the specified type
254253
* <br>
255254
* 2. {@link NoSuchElementException} - if the property is not defined <br>
256255
* 3. {@link NoSuchElementException} - if the property is defined as an empty string <br>
257256
* 4. {@link NoSuchElementException} - if the {@link Converter} returns {@code null} <br>
258257
* <br>
259-
*
258+
* <p>
260259
* Calls for converting optional values ({@link Config#getOptionalValue} and "Injecting Optional Values")
261260
* should only throw an {@link Exception} for #1 ({@link IllegalArgumentException} when the property cannot be converted to
262261
* the specified type).
@@ -459,6 +458,11 @@ public Optional<ConfigSource> getConfigSource(final String name) {
459458
return Optional.empty();
460459
}
461460

461+
@Experimental("Return a subset of the configuration")
462+
public Config subset(final String prefix) {
463+
return new SmallRyeSubsetConfig(prefix, this);
464+
}
465+
462466
public <T> T convert(String value, Class<T> asType) {
463467
return value != null ? requireConverter(asType).convert(value) : null;
464468
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package io.smallrye.config;
2+
3+
import java.util.List;
4+
import java.util.Optional;
5+
import java.util.stream.Collectors;
6+
import java.util.stream.StreamSupport;
7+
8+
import org.eclipse.microprofile.config.Config;
9+
import org.eclipse.microprofile.config.ConfigValue;
10+
import org.eclipse.microprofile.config.spi.ConfigSource;
11+
import org.eclipse.microprofile.config.spi.Converter;
12+
13+
/**
14+
* @author George Gastaldi
15+
*/
16+
public class SmallRyeSubsetConfig implements Config {
17+
18+
private final String prefix;
19+
20+
private final Config delegate;
21+
22+
public SmallRyeSubsetConfig(String prefix, Config delegate) {
23+
this.prefix = prefix;
24+
this.delegate = delegate;
25+
}
26+
27+
@Override
28+
public <T> T getValue(String propertyName, Class<T> propertyType) {
29+
return delegate.getValue(toSubsetPropertyName(propertyName), propertyType);
30+
}
31+
32+
@Override
33+
public ConfigValue getConfigValue(String propertyName) {
34+
return delegate.getConfigValue(toSubsetPropertyName(propertyName));
35+
}
36+
37+
@Override
38+
public <T> List<T> getValues(String propertyName, Class<T> propertyType) {
39+
return delegate.getValues(toSubsetPropertyName(propertyName), propertyType);
40+
}
41+
42+
@Override
43+
public <T> Optional<T> getOptionalValue(String propertyName, Class<T> propertyType) {
44+
return delegate.getOptionalValue(toSubsetPropertyName(propertyName), propertyType);
45+
}
46+
47+
@Override
48+
public <T> Optional<List<T>> getOptionalValues(String propertyName, Class<T> propertyType) {
49+
return delegate.getOptionalValues(toSubsetPropertyName(propertyName), propertyType);
50+
}
51+
52+
@Override
53+
public Iterable<String> getPropertyNames() {
54+
return StreamSupport.stream(delegate.getPropertyNames().spliterator(), false)
55+
.filter(propertyName -> propertyName.startsWith(prefix))
56+
.map(this::chopSubsetPropertyName)
57+
.collect(Collectors.toSet());
58+
}
59+
60+
@Override
61+
public Iterable<ConfigSource> getConfigSources() {
62+
return delegate.getConfigSources();
63+
}
64+
65+
@Override
66+
public <T> Optional<Converter<T>> getConverter(Class<T> forType) {
67+
return delegate.getConverter(forType);
68+
}
69+
70+
@Override
71+
public <T> T unwrap(Class<T> type) {
72+
return delegate.unwrap(type);
73+
}
74+
75+
private String toSubsetPropertyName(String propertyName) {
76+
if (propertyName.isBlank()) {
77+
return prefix;
78+
}
79+
return prefix + "." + propertyName;
80+
}
81+
82+
private String chopSubsetPropertyName(String propertyName) {
83+
return propertyName.substring(prefix.length() + 1);
84+
}
85+
}

implementation/src/test/java/io/smallrye/config/SmallRyeConfigTest.java

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
package io.smallrye.config;
22

3-
import static io.smallrye.config.Converters.STRING_CONVERTER;
4-
import static io.smallrye.config.KeyValuesConfigSource.config;
5-
import static java.util.Collections.singletonList;
6-
import static java.util.Collections.singletonMap;
7-
import static java.util.stream.Collectors.toSet;
8-
import static java.util.stream.StreamSupport.stream;
9-
import static org.junit.jupiter.api.Assertions.assertEquals;
10-
import static org.junit.jupiter.api.Assertions.assertFalse;
11-
import static org.junit.jupiter.api.Assertions.assertNotNull;
12-
import static org.junit.jupiter.api.Assertions.assertNull;
13-
import static org.junit.jupiter.api.Assertions.assertThrows;
14-
import static org.junit.jupiter.api.Assertions.assertTrue;
3+
import io.smallrye.config.common.AbstractConfigSource;
4+
import io.smallrye.config.common.MapBackedConfigSource;
5+
import org.eclipse.microprofile.config.Config;
6+
import org.eclipse.microprofile.config.spi.ConfigSource;
7+
import org.junit.jupiter.api.Test;
158

169
import java.util.ArrayList;
1710
import java.util.Arrays;
@@ -23,12 +16,13 @@
2316
import java.util.Optional;
2417
import java.util.Set;
2518

26-
import org.eclipse.microprofile.config.Config;
27-
import org.eclipse.microprofile.config.spi.ConfigSource;
28-
import org.junit.jupiter.api.Test;
29-
30-
import io.smallrye.config.common.AbstractConfigSource;
31-
import io.smallrye.config.common.MapBackedConfigSource;
19+
import static io.smallrye.config.Converters.STRING_CONVERTER;
20+
import static io.smallrye.config.KeyValuesConfigSource.config;
21+
import static java.util.Collections.singletonList;
22+
import static java.util.Collections.singletonMap;
23+
import static java.util.stream.Collectors.toSet;
24+
import static java.util.stream.StreamSupport.stream;
25+
import static org.junit.jupiter.api.Assertions.*;
3226

3327
class SmallRyeConfigTest {
3428
@Test
@@ -405,4 +399,18 @@ void emptyPropertyNames() {
405399

406400
assertEquals("value", config.getRawValue(""));
407401
}
402+
403+
@Test
404+
void subset() {
405+
SmallRyeConfig config = new SmallRyeConfigBuilder()
406+
.withSources(config(
407+
"app.foo", "bar",
408+
"app.foo.user", "guest",
409+
"app.foo.password", "apassword"))
410+
.build();
411+
Config subset = config.subset("app.foo");
412+
assertEquals("bar", subset.getValue("", String.class));
413+
assertEquals("guest", subset.getValue("user", String.class));
414+
assertEquals("apassword", subset.getValue("password", String.class));
415+
}
408416
}

0 commit comments

Comments
 (0)