diff --git a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/DotExpanderProcessor.java b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/DotExpanderProcessor.java index 0698f6ed0a6c9..f4215af8390dd 100644 --- a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/DotExpanderProcessor.java +++ b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/DotExpanderProcessor.java @@ -52,28 +52,30 @@ public IngestDocument execute(IngestDocument ingestDocument) throws Exception { 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; } diff --git a/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/DotExpanderProcessorTests.java b/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/DotExpanderProcessorTests.java index fde7f0c9b8a02..d6a207b859eb0 100644 --- a/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/DotExpanderProcessorTests.java +++ b/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/DotExpanderProcessorTests.java @@ -143,4 +143,38 @@ public void testEscapeFields_path() throws Exception { 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 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 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")); + } + }