Handle regex parsing errors in Gsub and Grok Processors
Currently, both Gsub and Grok parse regex strings during Pipeline creation. Thrown parsing exceptions were leaking out, this commit wraps those exceptions in ElasticsearchParseExceptions.
This commit is contained in:
parent
f8e84f0bbb
commit
534caa8927
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.ingest.processor;
|
package org.elasticsearch.ingest.processor;
|
||||||
|
|
||||||
|
import org.elasticsearch.ElasticsearchParseException;
|
||||||
import org.elasticsearch.ingest.core.AbstractProcessor;
|
import org.elasticsearch.ingest.core.AbstractProcessor;
|
||||||
import org.elasticsearch.ingest.core.AbstractProcessorFactory;
|
import org.elasticsearch.ingest.core.AbstractProcessorFactory;
|
||||||
import org.elasticsearch.ingest.core.IngestDocument;
|
import org.elasticsearch.ingest.core.IngestDocument;
|
||||||
|
@ -28,6 +29,9 @@ import java.util.Map;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static org.elasticsearch.ingest.core.ConfigurationUtils.newConfigurationException;
|
||||||
|
import static org.elasticsearch.ingest.core.ConfigurationUtils.readStringProperty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processor that allows to search for patterns in field content and replace them with corresponding string replacement.
|
* Processor that allows to search for patterns in field content and replace them with corresponding string replacement.
|
||||||
* Support fields of string type only, throws exception if a field is of a different type.
|
* Support fields of string type only, throws exception if a field is of a different type.
|
||||||
|
@ -79,10 +83,15 @@ public final class GsubProcessor extends AbstractProcessor {
|
||||||
public static final class Factory extends AbstractProcessorFactory<GsubProcessor> {
|
public static final class Factory extends AbstractProcessorFactory<GsubProcessor> {
|
||||||
@Override
|
@Override
|
||||||
public GsubProcessor doCreate(String processorTag, Map<String, Object> config) throws Exception {
|
public GsubProcessor doCreate(String processorTag, Map<String, Object> config) throws Exception {
|
||||||
String field = ConfigurationUtils.readStringProperty(TYPE, processorTag, config, "field");
|
String field = readStringProperty(TYPE, processorTag, config, "field");
|
||||||
String pattern = ConfigurationUtils.readStringProperty(TYPE, processorTag, config, "pattern");
|
String pattern = readStringProperty(TYPE, processorTag, config, "pattern");
|
||||||
String replacement = ConfigurationUtils.readStringProperty(TYPE, processorTag, config, "replacement");
|
String replacement = readStringProperty(TYPE, processorTag, config, "replacement");
|
||||||
Pattern searchPattern = Pattern.compile(pattern);
|
Pattern searchPattern;
|
||||||
|
try {
|
||||||
|
searchPattern = Pattern.compile(pattern);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw newConfigurationException(TYPE, processorTag, "pattern", "Invalid regex pattern. " + e.getMessage());
|
||||||
|
}
|
||||||
return new GsubProcessor(processorTag, field, searchPattern, replacement);
|
return new GsubProcessor(processorTag, field, searchPattern, replacement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,4 +84,18 @@ public class GsubProcessorFactoryTests extends ESTestCase {
|
||||||
assertThat(e.getMessage(), equalTo("[replacement] required property is missing"));
|
assertThat(e.getMessage(), equalTo("[replacement] required property is missing"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCreateInvalidPattern() throws Exception {
|
||||||
|
GsubProcessor.Factory factory = new GsubProcessor.Factory();
|
||||||
|
Map<String, Object> config = new HashMap<>();
|
||||||
|
config.put("field", "field1");
|
||||||
|
config.put("pattern", "[");
|
||||||
|
config.put("replacement", "-");
|
||||||
|
try {
|
||||||
|
factory.create(config);
|
||||||
|
fail("factory create should have failed");
|
||||||
|
} catch(ElasticsearchParseException e) {
|
||||||
|
assertThat(e.getMessage(), equalTo("[pattern] Invalid regex pattern. Unclosed character class near index 0\n[\n^"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ import org.elasticsearch.ingest.core.IngestDocument;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.elasticsearch.ingest.core.ConfigurationUtils.newConfigurationException;
|
||||||
|
|
||||||
public final class GrokProcessor extends AbstractProcessor {
|
public final class GrokProcessor extends AbstractProcessor {
|
||||||
|
|
||||||
public static final String TYPE = "grok";
|
public static final String TYPE = "grok";
|
||||||
|
@ -82,7 +84,12 @@ public final class GrokProcessor extends AbstractProcessor {
|
||||||
patternBank.putAll(customPatternBank);
|
patternBank.putAll(customPatternBank);
|
||||||
}
|
}
|
||||||
|
|
||||||
Grok grok = new Grok(patternBank, matchPattern);
|
Grok grok;
|
||||||
|
try {
|
||||||
|
grok = new Grok(patternBank, matchPattern);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw newConfigurationException(TYPE, processorTag, "pattern", "Invalid regex pattern. " + e.getMessage());
|
||||||
|
}
|
||||||
return new GrokProcessor(processorTag, grok, matchField);
|
return new GrokProcessor(processorTag, grok, matchField);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,4 +84,33 @@ public class GrokProcessorFactoryTests extends ESTestCase {
|
||||||
assertThat(processor.getGrok(), notNullValue());
|
assertThat(processor.getGrok(), notNullValue());
|
||||||
assertThat(processor.getGrok().match("foo!"), equalTo(true));
|
assertThat(processor.getGrok().match("foo!"), equalTo(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCreateWithInvalidPattern() throws Exception {
|
||||||
|
GrokProcessor.Factory factory = new GrokProcessor.Factory(Collections.emptyMap());
|
||||||
|
Map<String, Object> config = new HashMap<>();
|
||||||
|
config.put("field", "_field");
|
||||||
|
config.put("pattern", "[");
|
||||||
|
try {
|
||||||
|
factory.create(config);
|
||||||
|
fail("should fail");
|
||||||
|
} catch (ElasticsearchParseException e) {
|
||||||
|
assertThat(e.getMessage(), equalTo("[pattern] Invalid regex pattern. premature end of char-class"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateWithInvalidPatternDefinition() throws Exception {
|
||||||
|
GrokProcessor.Factory factory = new GrokProcessor.Factory(Collections.emptyMap());
|
||||||
|
Map<String, Object> config = new HashMap<>();
|
||||||
|
config.put("field", "_field");
|
||||||
|
config.put("pattern", "%{MY_PATTERN:name}!");
|
||||||
|
config.put("pattern_definitions", Collections.singletonMap("MY_PATTERN", "["));
|
||||||
|
try {
|
||||||
|
factory.create(config);
|
||||||
|
fail("should fail");
|
||||||
|
} catch (ElasticsearchParseException e) {
|
||||||
|
assertThat(e.getMessage(), equalTo("[pattern] Invalid regex pattern. premature end of char-class"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue