diff --git a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/IngestCommonPlugin.java b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/IngestCommonPlugin.java index bc900d32510..d9878cae9e2 100644 --- a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/IngestCommonPlugin.java +++ b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/IngestCommonPlugin.java @@ -62,7 +62,7 @@ public class IngestCommonPlugin extends Plugin implements ActionPlugin, IngestPl processors.put(DateProcessor.TYPE, new DateProcessor.Factory(parameters.scriptService)); processors.put(SetProcessor.TYPE, new SetProcessor.Factory(parameters.scriptService)); processors.put(AppendProcessor.TYPE, new AppendProcessor.Factory(parameters.scriptService)); - processors.put(RenameProcessor.TYPE, new RenameProcessor.Factory()); + processors.put(RenameProcessor.TYPE, new RenameProcessor.Factory(parameters.scriptService)); processors.put(RemoveProcessor.TYPE, new RemoveProcessor.Factory(parameters.scriptService)); processors.put(SplitProcessor.TYPE, new SplitProcessor.Factory()); processors.put(JoinProcessor.TYPE, new JoinProcessor.Factory()); diff --git a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/RenameProcessor.java b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/RenameProcessor.java index 90a6389d82e..a35a164ddd3 100644 --- a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/RenameProcessor.java +++ b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/RenameProcessor.java @@ -23,6 +23,8 @@ import org.elasticsearch.ingest.AbstractProcessor; import org.elasticsearch.ingest.ConfigurationUtils; import org.elasticsearch.ingest.IngestDocument; import org.elasticsearch.ingest.Processor; +import org.elasticsearch.script.ScriptService; +import org.elasticsearch.script.TemplateScript; import java.util.Map; @@ -33,22 +35,22 @@ public final class RenameProcessor extends AbstractProcessor { public static final String TYPE = "rename"; - private final String field; - private final String targetField; + private final TemplateScript.Factory field; + private final TemplateScript.Factory targetField; private final boolean ignoreMissing; - RenameProcessor(String tag, String field, String targetField, boolean ignoreMissing) { + RenameProcessor(String tag, TemplateScript.Factory field, TemplateScript.Factory targetField, boolean ignoreMissing) { super(tag); this.field = field; this.targetField = targetField; this.ignoreMissing = ignoreMissing; } - String getField() { + TemplateScript.Factory getField() { return field; } - String getTargetField() { + TemplateScript.Factory getTargetField() { return targetField; } @@ -58,28 +60,30 @@ public final class RenameProcessor extends AbstractProcessor { @Override public void execute(IngestDocument document) { - if (document.hasField(field, true) == false) { + String path = document.renderTemplate(field); + if (document.hasField(path, true) == false) { if (ignoreMissing) { return; } else { - throw new IllegalArgumentException("field [" + field + "] doesn't exist"); + throw new IllegalArgumentException("field [" + path + "] doesn't exist"); } } // We fail here if the target field point to an array slot that is out of range. // If we didn't do this then we would fail if we set the value in the target_field // and then on failure processors would not see that value we tried to rename as we already // removed it. - if (document.hasField(targetField, true)) { - throw new IllegalArgumentException("field [" + targetField + "] already exists"); + String target = document.renderTemplate(targetField); + if (document.hasField(target, true)) { + throw new IllegalArgumentException("field [" + target + "] already exists"); } - Object value = document.getFieldValue(field, Object.class); - document.removeField(field); + Object value = document.getFieldValue(path, Object.class); + document.removeField(path); try { - document.setFieldValue(targetField, value); + document.setFieldValue(target, value); } catch (Exception e) { // setting the value back to the original field shouldn't as we just fetched it from that field: - document.setFieldValue(field, value); + document.setFieldValue(path, value); throw e; } } @@ -90,13 +94,24 @@ public final class RenameProcessor extends AbstractProcessor { } public static final class Factory implements Processor.Factory { + + private final ScriptService scriptService; + + public Factory(ScriptService scriptService) { + this.scriptService = scriptService; + } + @Override public RenameProcessor create(Map registry, String processorTag, Map config) throws Exception { String field = ConfigurationUtils.readStringProperty(TYPE, processorTag, config, "field"); + TemplateScript.Factory fieldTemplate = ConfigurationUtils.compileTemplate(TYPE, processorTag, + "field", field, scriptService); String targetField = ConfigurationUtils.readStringProperty(TYPE, processorTag, config, "target_field"); + TemplateScript.Factory targetFieldTemplate = ConfigurationUtils.compileTemplate(TYPE, processorTag, + "target_field", targetField, scriptService); boolean ignoreMissing = ConfigurationUtils.readBooleanProperty(TYPE, processorTag, config, "ignore_missing", false); - return new RenameProcessor(processorTag, field, targetField, ignoreMissing); + return new RenameProcessor(processorTag, fieldTemplate, targetFieldTemplate , ignoreMissing); } } } 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 199c475a8f0..fde7f0c9b8a 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 @@ -21,6 +21,7 @@ package org.elasticsearch.ingest.common; import org.elasticsearch.ingest.IngestDocument; import org.elasticsearch.ingest.Processor; +import org.elasticsearch.ingest.TestTemplateService; import org.elasticsearch.test.ESTestCase; import java.util.Collections; @@ -86,7 +87,8 @@ public class DotExpanderProcessorTests extends ESTestCase { // so because foo is no branch field but a value field the `foo.bar` field can't be expanded // into [foo].[bar], so foo should be renamed first into `[foo].[bar]: IngestDocument document = new IngestDocument(source, Collections.emptyMap()); - Processor processor = new RenameProcessor("_tag", "foo", "foo.bar", false); + Processor processor = new RenameProcessor("_tag", new TestTemplateService.MockTemplateScript.Factory("foo"), + new TestTemplateService.MockTemplateScript.Factory("foo.bar"), false); processor.execute(document); processor = new DotExpanderProcessor("_tag", null, "foo.bar"); processor.execute(document); diff --git a/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/RenameProcessorFactoryTests.java b/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/RenameProcessorFactoryTests.java index 1eaac36a64c..9dd799ff339 100644 --- a/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/RenameProcessorFactoryTests.java +++ b/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/RenameProcessorFactoryTests.java @@ -20,8 +20,11 @@ package org.elasticsearch.ingest.common; import org.elasticsearch.ElasticsearchParseException; +import org.elasticsearch.ingest.TestTemplateService; import org.elasticsearch.test.ESTestCase; +import org.junit.Before; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -29,21 +32,26 @@ import static org.hamcrest.CoreMatchers.equalTo; public class RenameProcessorFactoryTests extends ESTestCase { + private RenameProcessor.Factory factory; + + @Before + public void init() { + factory = new RenameProcessor.Factory(TestTemplateService.instance()); + } + public void testCreate() throws Exception { - RenameProcessor.Factory factory = new RenameProcessor.Factory(); Map config = new HashMap<>(); config.put("field", "old_field"); config.put("target_field", "new_field"); String processorTag = randomAlphaOfLength(10); RenameProcessor renameProcessor = factory.create(null, processorTag, config); assertThat(renameProcessor.getTag(), equalTo(processorTag)); - assertThat(renameProcessor.getField(), equalTo("old_field")); - assertThat(renameProcessor.getTargetField(), equalTo("new_field")); + assertThat(renameProcessor.getField().newInstance(Collections.emptyMap()).execute(), equalTo("old_field")); + assertThat(renameProcessor.getTargetField().newInstance(Collections.emptyMap()).execute(), equalTo("new_field")); assertThat(renameProcessor.isIgnoreMissing(), equalTo(false)); } public void testCreateWithIgnoreMissing() throws Exception { - RenameProcessor.Factory factory = new RenameProcessor.Factory(); Map config = new HashMap<>(); config.put("field", "old_field"); config.put("target_field", "new_field"); @@ -51,13 +59,12 @@ public class RenameProcessorFactoryTests extends ESTestCase { String processorTag = randomAlphaOfLength(10); RenameProcessor renameProcessor = factory.create(null, processorTag, config); assertThat(renameProcessor.getTag(), equalTo(processorTag)); - assertThat(renameProcessor.getField(), equalTo("old_field")); - assertThat(renameProcessor.getTargetField(), equalTo("new_field")); + assertThat(renameProcessor.getField().newInstance(Collections.emptyMap()).execute(), equalTo("old_field")); + assertThat(renameProcessor.getTargetField().newInstance(Collections.emptyMap()).execute(), equalTo("new_field")); assertThat(renameProcessor.isIgnoreMissing(), equalTo(true)); } public void testCreateNoFieldPresent() throws Exception { - RenameProcessor.Factory factory = new RenameProcessor.Factory(); Map config = new HashMap<>(); config.put("target_field", "new_field"); try { @@ -69,7 +76,6 @@ public class RenameProcessorFactoryTests extends ESTestCase { } public void testCreateNoToPresent() throws Exception { - RenameProcessor.Factory factory = new RenameProcessor.Factory(); Map config = new HashMap<>(); config.put("field", "old_field"); try { diff --git a/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/RenameProcessorTests.java b/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/RenameProcessorTests.java index bf35918ad6e..5b3d88879ba 100644 --- a/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/RenameProcessorTests.java +++ b/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/RenameProcessorTests.java @@ -22,6 +22,7 @@ package org.elasticsearch.ingest.common; import org.elasticsearch.ingest.IngestDocument; import org.elasticsearch.ingest.Processor; import org.elasticsearch.ingest.RandomDocumentPicks; +import org.elasticsearch.ingest.TestTemplateService; import org.elasticsearch.test.ESTestCase; import java.util.ArrayList; @@ -45,7 +46,7 @@ public class RenameProcessorTests extends ESTestCase { do { newFieldName = RandomDocumentPicks.randomFieldName(random()); } while (RandomDocumentPicks.canAddField(newFieldName, ingestDocument) == false || newFieldName.equals(fieldName)); - Processor processor = new RenameProcessor(randomAlphaOfLength(10), fieldName, newFieldName, false); + Processor processor = createRenameProcessor(fieldName, newFieldName, false); processor.execute(ingestDocument); assertThat(ingestDocument.getFieldValue(newFieldName, Object.class), equalTo(fieldValue)); } @@ -63,7 +64,7 @@ public class RenameProcessorTests extends ESTestCase { document.put("one", one); IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document); - Processor processor = new RenameProcessor(randomAlphaOfLength(10), "list.0", "item", false); + Processor processor = createRenameProcessor("list.0", "item", false); processor.execute(ingestDocument); Object actualObject = ingestDocument.getSourceAndMetadata().get("list"); assertThat(actualObject, instanceOf(List.class)); @@ -76,7 +77,7 @@ public class RenameProcessorTests extends ESTestCase { assertThat(actualObject, instanceOf(String.class)); assertThat(actualObject, equalTo("item1")); - processor = new RenameProcessor(randomAlphaOfLength(10), "list.0", "list.3", false); + processor = createRenameProcessor("list.0", "list.3", false); try { processor.execute(ingestDocument); fail("processor execute should have failed"); @@ -91,7 +92,7 @@ public class RenameProcessorTests extends ESTestCase { public void testRenameNonExistingField() throws Exception { IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), new HashMap<>()); String fieldName = RandomDocumentPicks.randomFieldName(random()); - Processor processor = new RenameProcessor(randomAlphaOfLength(10), fieldName, + Processor processor = createRenameProcessor(fieldName, RandomDocumentPicks.randomFieldName(random()), false); try { processor.execute(ingestDocument); @@ -105,7 +106,7 @@ public class RenameProcessorTests extends ESTestCase { IngestDocument originalIngestDocument = RandomDocumentPicks.randomIngestDocument(random(), new HashMap<>()); IngestDocument ingestDocument = new IngestDocument(originalIngestDocument); String fieldName = RandomDocumentPicks.randomFieldName(random()); - Processor processor = new RenameProcessor(randomAlphaOfLength(10), fieldName, + Processor processor = createRenameProcessor(fieldName, RandomDocumentPicks.randomFieldName(random()), true); processor.execute(ingestDocument); assertIngestDocument(originalIngestDocument, ingestDocument); @@ -114,7 +115,7 @@ public class RenameProcessorTests extends ESTestCase { public void testRenameNewFieldAlreadyExists() throws Exception { IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random()); String fieldName = RandomDocumentPicks.randomExistingFieldName(random(), ingestDocument); - Processor processor = new RenameProcessor(randomAlphaOfLength(10), RandomDocumentPicks.randomExistingFieldName( + Processor processor = createRenameProcessor(RandomDocumentPicks.randomExistingFieldName( random(), ingestDocument), fieldName, false); try { processor.execute(ingestDocument); @@ -129,7 +130,7 @@ public class RenameProcessorTests extends ESTestCase { String fieldName = RandomDocumentPicks.randomFieldName(random()); ingestDocument.setFieldValue(fieldName, null); String newFieldName = randomValueOtherThanMany(ingestDocument::hasField, () -> RandomDocumentPicks.randomFieldName(random())); - Processor processor = new RenameProcessor(randomAlphaOfLength(10), fieldName, newFieldName, false); + Processor processor = createRenameProcessor(fieldName, newFieldName, false); processor.execute(ingestDocument); assertThat(ingestDocument.hasField(fieldName), equalTo(false)); assertThat(ingestDocument.hasField(newFieldName), equalTo(true)); @@ -149,7 +150,7 @@ public class RenameProcessorTests extends ESTestCase { source.put("list", Collections.singletonList("item")); IngestDocument ingestDocument = new IngestDocument(source, Collections.emptyMap()); - Processor processor = new RenameProcessor(randomAlphaOfLength(10), "list", "new_field", false); + Processor processor = createRenameProcessor("list", "new_field", false); try { processor.execute(ingestDocument); fail("processor execute should have failed"); @@ -173,7 +174,7 @@ public class RenameProcessorTests extends ESTestCase { source.put("list", Collections.singletonList("item")); IngestDocument ingestDocument = new IngestDocument(source, Collections.emptyMap()); - Processor processor = new RenameProcessor(randomAlphaOfLength(10), "list", "new_field", false); + Processor processor = createRenameProcessor("list", "new_field", false); try { processor.execute(ingestDocument); fail("processor execute should have failed"); @@ -188,12 +189,12 @@ public class RenameProcessorTests extends ESTestCase { Map source = new HashMap<>(); source.put("foo", "bar"); IngestDocument ingestDocument = new IngestDocument(source, Collections.emptyMap()); - Processor processor1 = new RenameProcessor(randomAlphaOfLength(10), "foo", "foo.bar", false); + Processor processor1 = createRenameProcessor("foo", "foo.bar", false); processor1.execute(ingestDocument); assertThat(ingestDocument.getFieldValue("foo", Map.class), equalTo(Collections.singletonMap("bar", "bar"))); assertThat(ingestDocument.getFieldValue("foo.bar", String.class), equalTo("bar")); - Processor processor2 = new RenameProcessor(randomAlphaOfLength(10), "foo.bar", "foo.bar.baz", false); + Processor processor2 = createRenameProcessor( "foo.bar", "foo.bar.baz", false); processor2.execute(ingestDocument); assertThat(ingestDocument.getFieldValue("foo", Map.class), equalTo(Collections.singletonMap("bar", Collections.singletonMap("baz", "bar")))); @@ -201,9 +202,13 @@ public class RenameProcessorTests extends ESTestCase { assertThat(ingestDocument.getFieldValue("foo.bar.baz", String.class), equalTo("bar")); // for fun lets try to restore it (which don't allow today) - Processor processor3 = new RenameProcessor(randomAlphaOfLength(10), "foo.bar.baz", "foo", false); + Processor processor3 = createRenameProcessor("foo.bar.baz", "foo", false); Exception e = expectThrows(IllegalArgumentException.class, () -> processor3.execute(ingestDocument)); assertThat(e.getMessage(), equalTo("field [foo] already exists")); } + private RenameProcessor createRenameProcessor(String field, String targetField, boolean ignoreMissing) { + return new RenameProcessor(randomAlphaOfLength(10), new TestTemplateService.MockTemplateScript.Factory(field), + new TestTemplateService.MockTemplateScript.Factory(targetField), ignoreMissing); + } }