diff --git a/src/main/java/usi/vaa/elasticsearch/plugin/ingest/lookup/LookupProcessor.java b/src/main/java/usi/vaa/elasticsearch/plugin/ingest/lookup/LookupProcessor.java index dc655df..b3f5f10 100644 --- a/src/main/java/usi/vaa/elasticsearch/plugin/ingest/lookup/LookupProcessor.java +++ b/src/main/java/usi/vaa/elasticsearch/plugin/ingest/lookup/LookupProcessor.java @@ -17,59 +17,77 @@ package usi.vaa.elasticsearch.plugin.ingest.lookup; -import org.elasticsearch.common.Strings; import org.elasticsearch.ingest.AbstractProcessor; import org.elasticsearch.ingest.IngestDocument; import org.elasticsearch.ingest.Processor; -import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; import java.util.Map; +import java.util.regex.MatchResult; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static org.elasticsearch.ingest.ConfigurationUtils.readMap; import static org.elasticsearch.ingest.ConfigurationUtils.readStringProperty; public class LookupProcessor extends AbstractProcessor { - + public static final String FIELD_PROPERTY = "field"; + public static final String LOOKUP_MAP_PROPERTY = "lookup-map"; public static final String TYPE = "lookup"; + private static final Pattern PATTERN = Pattern.compile("([^\\s\\p{Z}]+)([\\s\\p{Z}]+|$)"); + private final String field; + private final Map lookupMap; - private final String field = ""; - - - // TODO this signature and method might be incomplete - change as needed - public LookupProcessor(String tag, String description, String field, - Map lookupMap) throws IOException { + public LookupProcessor(String tag, String description, String field, Map lookupMap) { super(tag, description); + this.field = field; + this.lookupMap = new HashMap<>(lookupMap); + } + + private String replaceWord(final MatchResult toReplace) { + if (toReplace.groupCount() != 2) { + throw new IllegalArgumentException("Captured groups should be coherent with PATTERN regex"); + } + + final String word = toReplace.group(1); + final String spacesAfterWord = toReplace.group(2); + + return lookupMap.getOrDefault(word, word) + spacesAfterWord; } @Override - public IngestDocument execute(IngestDocument ingestDocument) throws Exception{ - String originalContent = ingestDocument.getFieldValue(field, String.class); - ingestDocument.setFieldValue(field, "Hello world"); - return null; + public IngestDocument execute(IngestDocument ingestDocument) { + final String originalContent = ingestDocument.getFieldValue(field, String.class); + final Matcher matcher = PATTERN.matcher(originalContent); + final String replacedContent = matcher.replaceAll(this::replaceWord); + ingestDocument.setFieldValue(field, replacedContent); + return ingestDocument; } @Override public String getType() { - // TODO your job! - return null; + return TYPE; } String getField() { - // TODO your job! - return null; + return this.field; } + Map getLookupMap() { + return Collections.unmodifiableMap(lookupMap); + } public static final class Factory implements Processor.Factory { @Override - public LookupProcessor create(Map factories, String tag, - String description, Map config) - throws Exception { - String field = readStringProperty(TYPE, tag, config, "field"); - - // TODO your job! Also initialize the lookup processor properly if needed, after you changed the constructor - return null; + public LookupProcessor create(final Map factories, + final String tag, + final String description, + final Map config) { + final String field = readStringProperty(TYPE, tag, config, FIELD_PROPERTY); + final Map lookupMap = readMap(TYPE, tag, config, LOOKUP_MAP_PROPERTY); + return new LookupProcessor(tag, description, field, lookupMap); } } } diff --git a/src/test/java/usi/vaa/elasticsearch/plugin/ingest/lookup/LookupProcessorFactoryTests.java b/src/test/java/usi/vaa/elasticsearch/plugin/ingest/lookup/LookupProcessorFactoryTests.java index c31ca1b..9bf995b 100644 --- a/src/test/java/usi/vaa/elasticsearch/plugin/ingest/lookup/LookupProcessorFactoryTests.java +++ b/src/test/java/usi/vaa/elasticsearch/plugin/ingest/lookup/LookupProcessorFactoryTests.java @@ -24,25 +24,47 @@ import org.junit.BeforeClass; import java.util.HashMap; import java.util.Map; -import static org.hamcrest.Matchers.equalTo; +import static usi.vaa.elasticsearch.plugin.ingest.lookup.LookupProcessor.*; public class LookupProcessorFactoryTests extends ESTestCase { + private static String tag; + private static String description; + private static LookupProcessor.Factory factory; @BeforeClass public static void defaultSettings() { - // TODO your job! + tag = "lookup-test"; + description = "lookup pipeline test"; + factory = new LookupProcessor.Factory(); } - private Map getDefaultConfig() { - // TODO your job! + private LookupProcessor callFactory(final Map config) { + // if the `config` map is not cloned here java.lang.UnsupportedOperationException is thrown + // for some reflective magic related reason, therefore do not remove + return factory.create(null, tag, description, new HashMap<>(config)); } - public void testDefaultConfiguration() throws Exception{ - // TODO your job! + public void testDefaultConfiguration() { + final String testField = "theTestField"; + final Map testMap = Map.of( + "C001", "tyre", + "C010", "front wing", + "C100", "damper" + ); + + final Map config = Map.of( + FIELD_PROPERTY, testField, + LOOKUP_MAP_PROPERTY, testMap + ); + final LookupProcessor processor = callFactory(config); + + assertEquals(tag, processor.getTag()); + assertEquals(description, processor.getDescription()); + assertEquals(testMap, processor.getLookupMap()); + assertEquals(testField, processor.getField()); } - public void testInvalidConfiguration() throws Exception{ - // TODO your job! + public void testInvalidConfiguration() { + expectThrows(ElasticsearchParseException.class, () -> callFactory(Map.of("invalid", "config"))); } - } diff --git a/src/test/java/usi/vaa/elasticsearch/plugin/ingest/lookup/LookupProcessorTests.java b/src/test/java/usi/vaa/elasticsearch/plugin/ingest/lookup/LookupProcessorTests.java index a437a27..4493fc5 100644 --- a/src/test/java/usi/vaa/elasticsearch/plugin/ingest/lookup/LookupProcessorTests.java +++ b/src/test/java/usi/vaa/elasticsearch/plugin/ingest/lookup/LookupProcessorTests.java @@ -22,25 +22,58 @@ import org.elasticsearch.ingest.IngestDocument; import org.elasticsearch.ingest.RandomDocumentPicks; import org.elasticsearch.test.ESTestCase; import org.junit.BeforeClass; + import java.util.HashMap; import java.util.Map; -import static org.hamcrest.Matchers.equalTo; +import static usi.vaa.elasticsearch.plugin.ingest.lookup.LookupProcessor.FIELD_PROPERTY; +import static usi.vaa.elasticsearch.plugin.ingest.lookup.LookupProcessor.LOOKUP_MAP_PROPERTY; public class LookupProcessorTests extends ESTestCase { - + private static final String DOC_FIELD = "field_to_replace"; + private static LookupProcessor processor; @BeforeClass public static void defaultSettings() { - // TODO your job! + processor = new LookupProcessor.Factory().create( + null, + "test-lookup", + "Test lookup processor pipeline", + new HashMap<>(Map.of( + FIELD_PROPERTY, DOC_FIELD, + LOOKUP_MAP_PROPERTY, Map.of( + "C001", "tyre", + "C010", "front wing", + "C100", "damper" + ) + )) + ); } - public void testSimple() throws Exception{ - // TODO your job! + private IngestDocument getDocWithContent(final String content) { + final Map doc = Map.of(DOC_FIELD, content); + return RandomDocumentPicks.randomIngestDocument(random(), doc); } - public void testEmptyField() throws Exception{ - // TODO your job! + private void testWithContent(final String originalContent, final String expectedContent) { + final IngestDocument doc = getDocWithContent(originalContent); + processor.execute(doc); + assertEquals(expectedContent, doc.getSourceAndMetadata().get(DOC_FIELD)); } + public void testSimple() { + final String originalContent = "Need to optimize the C001 temperature.\n" + + "C010 needs to be changed as it is damaged.\tC100 seems ok."; + final String expectedContent = "Need to optimize the tyre temperature.\n" + + "front wing needs to be changed as it is damaged.\tdamper seems ok."; + + testWithContent(originalContent, expectedContent); + } + + public void testEmptyField() { + final String originalContent = ""; + final String expectedContent = ""; + + testWithContent(originalContent, expectedContent); + } }