Reputation: 31
While reading yaml if a key is missed how to validate that ? API used for reading yaml is snakeYaml
Yaml yaml = new Yaml(new Constructor(config.class));
InputStream in = Files.newInputStream(filepath);
yaml.load(in);
Expected YAML:
KEY1:
innerKey1:
innerKey2: value1
innerKey3: value2
innerKey4:value3
While reading yaml if a key is missed how to throw error? Example while reading yaml if innerKey3 is missed how to validate it without iterating over all the keys as we have a POJO defined already for that yaml.
Input yaml:
KEY1:
innerKey1:
innerKey2: value1
innerKey4:value3
Expected: innerKey3 is missing
Upvotes: 3
Views: 2890
Reputation: 39768
You will need to define a TypeDescription
that implements the additional logic for checking whether all fields are present:
public class FieldChecker extends TypeDescription {
public FieldChecker(Class<? extends Object> cls) {
super(cls);
}
/** This is called during construction for creating a new instance
of our class. The fields are filled later but we can check here
whether all fields are there. */
@Override
public Object newInstance(Node node) {
/** our objects will always be constructed from mapping nodes. */
final MappingNode m = (MappingNode)node;
/** TypeDescription implements the logic discovering the
class properties via getProperties() */
for (Property p : getProperties()) {
boolean found = false;
// search for a key with matching name in the mapping
for (NodeTuple p : m.getValue()) {
// assume all mapping keys are scalars
if (((ScalarNode)p.getKeyNode()).getValue().equals(p.getName())) {
found = true;
break;
}
}
if (!found) {
throw new ConstructorException(null, null,
"missing key: " + p.getName(), node.getStartMark(), null);
}
}
// the fields are filled later by SnakeYAML.
return getType().newInstance();
}
}
Now you need to use this for each class in your input where you want to check the fields:
Yaml yaml = new Yaml(new Constructor(new FieldChecker(config.class), List.of(
new FieldChecker(other.class), new FieldChecker(another.class), ...)));
Upvotes: 0
Reputation: 628
One of the ways could be, to convert the YAML to JSON and then use the json schema validator to validate that json. There are multiple libraries which can convert the yaml to JSON Please check this thread to convert the yaml to JSON. How do I convert from YAML to JSON in Java?
Once you get the JSON, you can use any of the json schema validators like Networklint/Everit.
Upvotes: 3
Reputation: 96
By default, the load() method returns a Map instance, so if you know the key name in advance, but it's not easy to traverse over nested properties. So after yaml.load(in)
you could add an assert to check.
assertTrue(document.containsKey("key_you_know"));
But if it's nested object, you should define some custom classes.
class Key {
private List<InnerKey> innerKeys; // innerKey1
private String value4; // equal to your innerKey4
// getters and setters
}
class InnerKey {
private String value2; // innerKey2
private String value3; // innerKey3
// getters and setters
}
Then do the assert
Key key = yaml.load(in);
assertNotNull(key.getValue3());
Upvotes: 0