ingest: dot_expander_processor prevent null add/append to source document (#35106)

* don't allow null values to be added or appended to the 
source document if the field does not exist.
This commit is contained in:
Jake Landis 2018-11-05 17:16:42 -06:00 committed by GitHub
parent 9ac7af6b3e
commit 9150a93b1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 18 deletions

View File

@ -52,28 +52,30 @@ public final class DotExpanderProcessor extends AbstractProcessor {
map = ingestDocument.getSourceAndMetadata();
}
if (ingestDocument.hasField(path)) {
Object value = map.remove(field);
ingestDocument.appendFieldValue(path, value);
} else {
// check whether we actually can expand the field in question into an object field.
// part of the path may already exist and if part of it would be a value field (string, integer etc.)
// then we can't override it with an object field and we should fail with a good reason.
// IngestDocument#setFieldValue(...) would fail too, but the error isn't very understandable
for (int index = path.indexOf('.'); index != -1; index = path.indexOf('.', index + 1)) {
String partialPath = path.substring(0, index);
if (ingestDocument.hasField(partialPath)) {
Object val = ingestDocument.getFieldValue(partialPath, Object.class);
if ((val instanceof Map) == false) {
throw new IllegalArgumentException("cannot expend [" + path + "], because [" + partialPath +
if (map.containsKey(field)) {
if (ingestDocument.hasField(path)) {
Object value = map.remove(field);
ingestDocument.appendFieldValue(path, value);
} else {
// check whether we actually can expand the field in question into an object field.
// part of the path may already exist and if part of it would be a value field (string, integer etc.)
// then we can't override it with an object field and we should fail with a good reason.
// IngestDocument#setFieldValue(...) would fail too, but the error isn't very understandable
for (int index = path.indexOf('.'); index != -1; index = path.indexOf('.', index + 1)) {
String partialPath = path.substring(0, index);
if (ingestDocument.hasField(partialPath)) {
Object val = ingestDocument.getFieldValue(partialPath, Object.class);
if ((val instanceof Map) == false) {
throw new IllegalArgumentException("cannot expend [" + path + "], because [" + partialPath +
"] is not an object field, but a value field");
}
} else {
break;
}
} else {
break;
}
Object value = map.remove(field);
ingestDocument.setFieldValue(path, value);
}
Object value = map.remove(field);
ingestDocument.setFieldValue(path, value);
}
return ingestDocument;
}

View File

@ -143,4 +143,38 @@ public class DotExpanderProcessorTests extends ESTestCase {
assertThat(document.getFieldValue("field.foo.bar.baz", String.class), equalTo("value"));
}
public void testEscapeFields_doNothingIfFieldNotInSourceDoc() throws Exception {
//asking to expand a (literal) field that is not present in the source document
Map<String, Object> source = new HashMap<>();
source.put("foo.bar", "baz1");
IngestDocument document = new IngestDocument(source, Collections.emptyMap());
//abc.def does not exist in source, so don't mutate document
DotExpanderProcessor processor = new DotExpanderProcessor("_tag", null, "abc.def");
processor.execute(document);
//hasField returns false since it requires the expanded form, which is not expanded since we did not ask for it to be
assertFalse(document.hasField("foo.bar"));
//nothing has changed
assertEquals(document.getSourceAndMetadata().get("foo.bar"), "baz1");
//abc.def is not found anywhere
assertFalse(document.hasField("abc.def"));
assertFalse(document.getSourceAndMetadata().containsKey("abc"));
assertFalse(document.getSourceAndMetadata().containsKey("abc.def"));
//asking to expand a (literal) field that does not exist, but the nested field does exist
source = new HashMap<>();
Map<String, Object> inner = new HashMap<>();
inner.put("bar", "baz1");
source.put("foo", inner);
document = new IngestDocument(source, Collections.emptyMap());
//foo.bar, the literal value (as opposed to nested value) does not exist in source, so don't mutate document
processor = new DotExpanderProcessor("_tag", null, "foo.bar");
processor.execute(document);
//hasField returns true because the nested/expanded form exists in the source document
assertTrue(document.hasField("foo.bar"));
//nothing changed
assertThat(document.getFieldValue("foo", Map.class).size(), equalTo(1));
assertThat(document.getFieldValue("foo.bar", String.class), equalTo("baz1"));
}
}