[7.x] Make for each processor resistant to field modification () ()

* Make for each processor resistant to field modification  ()

This change provides consistent view of field that foreach processor is iterating over. That prevents it to go into infinite loop and put great pressure on the cluster.

Closes 

* fix compilation
This commit is contained in:
Przemko Robakowski 2020-09-23 10:46:00 +02:00 committed by GitHub
parent bc34ecc581
commit 005e0bffaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 1 deletions
modules/ingest-common/src
main/java/org/elasticsearch/ingest/common
test/java/org/elasticsearch/ingest/common

View File

@ -75,7 +75,7 @@ public final class ForEachProcessor extends AbstractProcessor implements Wrappin
handler.accept(null, new IllegalArgumentException("field [" + field + "] is null, cannot loop over its elements."));
}
} else {
innerExecute(0, values, new ArrayList<>(values.size()), ingestDocument, handler);
innerExecute(0, new ArrayList<>(values), new ArrayList<>(values.size()), ingestDocument, handler);
}
}

View File

@ -292,6 +292,30 @@ public class ForEachProcessorTests extends ESTestCase {
assertThat(testProcessor.getInvokedCounter(), equalTo(0));
}
public void testAppendingToTheSameField() {
Map<String, Object> source = Collections.singletonMap("field", Arrays.asList("a", "b"));
IngestDocument originalIngestDocument = new IngestDocument("_index", "_type", "_id", null, null, null, source);
IngestDocument ingestDocument = new IngestDocument(originalIngestDocument);
TestProcessor testProcessor = new TestProcessor(id->id.appendFieldValue("field", "a"));
ForEachProcessor processor = new ForEachProcessor("_tag", null, "field", testProcessor, true);
processor.execute(ingestDocument, (result, e) -> {});
assertThat(testProcessor.getInvokedCounter(), equalTo(2));
ingestDocument.removeField("_ingest._value");
assertThat(ingestDocument, equalTo(originalIngestDocument));
}
public void testRemovingFromTheSameField() {
Map<String, Object> source = Collections.singletonMap("field", Arrays.asList("a", "b"));
IngestDocument originalIngestDocument = new IngestDocument("_index", "_id", "_type", null, null, null, source);
IngestDocument ingestDocument = new IngestDocument(originalIngestDocument);
TestProcessor testProcessor = new TestProcessor(id -> id.removeField("field.0"));
ForEachProcessor processor = new ForEachProcessor("_tag", null, "field", testProcessor, true);
processor.execute(ingestDocument, (result, e) -> {});
assertThat(testProcessor.getInvokedCounter(), equalTo(2));
ingestDocument.removeField("_ingest._value");
assertThat(ingestDocument, equalTo(originalIngestDocument));
}
private class AsyncUpperCaseProcessor implements Processor {
private final String field;