Skip to content

Commit

Permalink
Preserve YAML timestamp values. (#505)
Browse files Browse the repository at this point in the history
  • Loading branch information
radcortez authored Feb 15, 2021
1 parent f4489d8 commit 16beec2
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import org.eclipse.microprofile.config.spi.ConfigSource;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.nodes.Tag;

import io.smallrye.common.classloader.ClassPathUtils;
import io.smallrye.common.constraint.Assert;
Expand Down Expand Up @@ -84,7 +86,7 @@ private static Map<String, String> streamToMap(InputStream inputStream) throws I
Assert.checkNotNullParam("inputStream", inputStream);
final Map<String, String> yamlInput = new TreeMap<>();
try {
final Iterable<Object> objects = new Yaml().loadAll(inputStream);
final Iterable<Object> objects = new Yaml(new StringConstructor()).loadAll(inputStream);
for (Object object : objects) {
if (object instanceof Map) {
yamlInput.putAll(yamlInputToMap((Map<Object, Object>) object));
Expand All @@ -104,7 +106,7 @@ private static Map<String, String> streamToMap(InputStream inputStream) throws I

@SuppressWarnings("unchecked")
private static Map<String, String> stringToMap(String str) {
final Map<Object, Object> yamlInput = new Yaml().loadAs(str, HashMap.class);
final Map<Object, Object> yamlInput = new Yaml(new StringConstructor()).loadAs(str, HashMap.class);
return yamlInputToMap(yamlInput);
}

Expand Down Expand Up @@ -185,4 +187,15 @@ private static Set<String> filterIndexedNames(Set<String> names) {
final Pattern pattern = Pattern.compile(".*\\[[0-9]+].*");
return names.stream().filter(s -> !pattern.matcher(s).find()).collect(Collectors.toSet());
}

/**
* Override some of the yaml constructors, so that the value written in the flatten result is more alike with the
* source. For instance, timestamps may be written in a completely different format which prevents converters to
* convert the correct value.
*/
private static class StringConstructor extends Constructor {
public StringConstructor() {
this.yamlConstructors.put(Tag.TIMESTAMP, new ConstructYamlStr());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,16 @@ void listValue() {
}

@Test
void EmptyFile() {
void emptyFile() {
String yaml = "";
ConfigSource src = new YamlConfigSource("Yaml", yaml);
assertNotNull(src, "Should create config source for empty file correctly");
}

@Test
void preserveOriginal() {
String yaml = "date: 2010-10-10";
ConfigSource source = new YamlConfigSource("Yaml", yaml);
assertEquals("2010-10-10", source.getValue("date"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
Expand Down Expand Up @@ -149,6 +153,20 @@ void configMapping() throws Exception {
assertEquals(usersMapping.users().users.get(0).getRoles(), Stream.of("Moderator", "Admin").collect(toList()));
}

@Test
void timestampConverters() {
SmallRyeConfig config = new SmallRyeConfigBuilder()
.withSources(new YamlConfigSource("yaml", "date: 2010-10-10\n" +
"dateTime: 2010-10-10T10:10:10\n" +
"zonedDateTime: 2020-10-10T10:10:10-05:00"))
.build();

assertEquals(LocalDate.of(2010, 10, 10), config.getValue("date", LocalDate.class));
assertEquals(LocalDateTime.of(2010, 10, 10, 10, 10, 10), config.getValue("dateTime", LocalDateTime.class));
assertEquals(ZonedDateTime.of(2020, 10, 10, 10, 10, 10, 0, ZoneId.of("-5")),
config.getValue("zonedDateTime", ZonedDateTime.class));
}

public static class Users {
List<User> users;

Expand Down

0 comments on commit 16beec2

Please sign in to comment.