Accept ingest simulate params as ints or strings (#23885)
* Allow ingest simulate to parse _id, _index, _type, _routing and _parent as either string or int (#23823) * Generate data that includes Integer and String type fields for testing document parsing.
This commit is contained in:
parent
4f5ce5598e
commit
8ef7438d6c
|
@ -174,16 +174,24 @@ public class SimulatePipelineRequest extends ActionRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<IngestDocument> parseDocs(Map<String, Object> config) {
|
private static List<IngestDocument> parseDocs(Map<String, Object> config) {
|
||||||
List<Map<String, Object>> docs = ConfigurationUtils.readList(null, null, config, Fields.DOCS);
|
List<Map<String, Object>> docs =
|
||||||
|
ConfigurationUtils.readList(null, null, config, Fields.DOCS);
|
||||||
List<IngestDocument> ingestDocumentList = new ArrayList<>();
|
List<IngestDocument> ingestDocumentList = new ArrayList<>();
|
||||||
for (Map<String, Object> dataMap : docs) {
|
for (Map<String, Object> dataMap : docs) {
|
||||||
Map<String, Object> document = ConfigurationUtils.readMap(null, null, dataMap, Fields.SOURCE);
|
Map<String, Object> document = ConfigurationUtils.readMap(null, null,
|
||||||
IngestDocument ingestDocument = new IngestDocument(ConfigurationUtils.readStringProperty(null, null, dataMap, MetaData.INDEX.getFieldName(), "_index"),
|
dataMap, Fields.SOURCE);
|
||||||
ConfigurationUtils.readStringProperty(null, null, dataMap, MetaData.TYPE.getFieldName(), "_type"),
|
String index = ConfigurationUtils.readStringOrIntProperty(null, null,
|
||||||
ConfigurationUtils.readStringProperty(null, null, dataMap, MetaData.ID.getFieldName(), "_id"),
|
dataMap, MetaData.INDEX.getFieldName(), "_index");
|
||||||
ConfigurationUtils.readOptionalStringProperty(null, null, dataMap, MetaData.ROUTING.getFieldName()),
|
String type = ConfigurationUtils.readStringOrIntProperty(null, null,
|
||||||
ConfigurationUtils.readOptionalStringProperty(null, null, dataMap, MetaData.PARENT.getFieldName()),
|
dataMap, MetaData.TYPE.getFieldName(), "_type");
|
||||||
document);
|
String id = ConfigurationUtils.readStringOrIntProperty(null, null,
|
||||||
|
dataMap, MetaData.ID.getFieldName(), "_id");
|
||||||
|
String routing = ConfigurationUtils.readOptionalStringOrIntProperty(null, null,
|
||||||
|
dataMap, MetaData.ROUTING.getFieldName());
|
||||||
|
String parent = ConfigurationUtils.readOptionalStringOrIntProperty(null, null,
|
||||||
|
dataMap, MetaData.PARENT.getFieldName());
|
||||||
|
IngestDocument ingestDocument =
|
||||||
|
new IngestDocument(index, type, id, routing, parent, document);
|
||||||
ingestDocumentList.add(ingestDocument);
|
ingestDocumentList.add(ingestDocument);
|
||||||
}
|
}
|
||||||
return ingestDocumentList;
|
return ingestDocumentList;
|
||||||
|
|
|
@ -92,6 +92,52 @@ public final class ConfigurationUtils {
|
||||||
value.getClass().getName() + "]");
|
value.getClass().getName() + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns and removes the specified property from the specified configuration map.
|
||||||
|
*
|
||||||
|
* If the property value isn't of type string or int a {@link ElasticsearchParseException} is thrown.
|
||||||
|
* If the property is missing and no default value has been specified a {@link ElasticsearchParseException} is thrown
|
||||||
|
*/
|
||||||
|
public static String readStringOrIntProperty(String processorType, String processorTag,
|
||||||
|
Map<String, Object> configuration, String propertyName, String defaultValue) {
|
||||||
|
Object value = configuration.remove(propertyName);
|
||||||
|
if (value == null && defaultValue != null) {
|
||||||
|
return defaultValue;
|
||||||
|
} else if (value == null) {
|
||||||
|
throw newConfigurationException(processorType, processorTag, propertyName,
|
||||||
|
"required property is missing");
|
||||||
|
}
|
||||||
|
return readStringOrInt(processorType, processorTag, propertyName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String readStringOrInt(String processorType, String processorTag,
|
||||||
|
String propertyName, Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value instanceof String) {
|
||||||
|
return (String) value;
|
||||||
|
} else if (value instanceof Integer) {
|
||||||
|
return String.valueOf(value);
|
||||||
|
}
|
||||||
|
throw newConfigurationException(processorType, processorTag, propertyName,
|
||||||
|
"property isn't a string or int, but of type [" + value.getClass().getName() + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns and removes the specified property from the specified configuration map.
|
||||||
|
*
|
||||||
|
* If the property value isn't of type string or int a {@link ElasticsearchParseException} is thrown.
|
||||||
|
*/
|
||||||
|
public static String readOptionalStringOrIntProperty(String processorType, String processorTag,
|
||||||
|
Map<String, Object> configuration, String propertyName) {
|
||||||
|
Object value = configuration.remove(propertyName);
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return readStringOrInt(processorType, processorTag, propertyName, value);
|
||||||
|
}
|
||||||
|
|
||||||
public static Boolean readBooleanProperty(String processorType, String processorTag, Map<String, Object> configuration,
|
public static Boolean readBooleanProperty(String processorType, String processorTag, Map<String, Object> configuration,
|
||||||
String propertyName, boolean defaultValue) {
|
String propertyName, boolean defaultValue) {
|
||||||
Object value = configuration.remove(propertyName);
|
Object value = configuration.remove(propertyName);
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.action.ingest;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -40,6 +41,8 @@ import static org.elasticsearch.action.ingest.SimulatePipelineRequest.Fields;
|
||||||
import static org.elasticsearch.action.ingest.SimulatePipelineRequest.SIMULATED_PIPELINE_ID;
|
import static org.elasticsearch.action.ingest.SimulatePipelineRequest.SIMULATED_PIPELINE_ID;
|
||||||
import static org.elasticsearch.ingest.IngestDocument.MetaData.ID;
|
import static org.elasticsearch.ingest.IngestDocument.MetaData.ID;
|
||||||
import static org.elasticsearch.ingest.IngestDocument.MetaData.INDEX;
|
import static org.elasticsearch.ingest.IngestDocument.MetaData.INDEX;
|
||||||
|
import static org.elasticsearch.ingest.IngestDocument.MetaData.PARENT;
|
||||||
|
import static org.elasticsearch.ingest.IngestDocument.MetaData.ROUTING;
|
||||||
import static org.elasticsearch.ingest.IngestDocument.MetaData.TYPE;
|
import static org.elasticsearch.ingest.IngestDocument.MetaData.TYPE;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
@ -116,20 +119,24 @@ public class SimulatePipelineRequestParsingTests extends ESTestCase {
|
||||||
requestContent.put(Fields.DOCS, docs);
|
requestContent.put(Fields.DOCS, docs);
|
||||||
for (int i = 0; i < numDocs; i++) {
|
for (int i = 0; i < numDocs; i++) {
|
||||||
Map<String, Object> doc = new HashMap<>();
|
Map<String, Object> doc = new HashMap<>();
|
||||||
String index = randomAlphaOfLengthBetween(1, 10);
|
Map<String, Object> expectedDoc = new HashMap<>();
|
||||||
String type = randomAlphaOfLengthBetween(1, 10);
|
List<IngestDocument.MetaData> fields = Arrays.asList(INDEX, TYPE, ID, ROUTING, PARENT);
|
||||||
String id = randomAlphaOfLengthBetween(1, 10);
|
for(IngestDocument.MetaData field : fields) {
|
||||||
doc.put(INDEX.getFieldName(), index);
|
if(randomBoolean()) {
|
||||||
doc.put(TYPE.getFieldName(), type);
|
String value = randomAlphaOfLengthBetween(1, 10);
|
||||||
doc.put(ID.getFieldName(), id);
|
doc.put(field.getFieldName(), value);
|
||||||
|
expectedDoc.put(field.getFieldName(), value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Integer value = randomIntBetween(1, 1000000);
|
||||||
|
doc.put(field.getFieldName(), value);
|
||||||
|
expectedDoc.put(field.getFieldName(), String.valueOf(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
String fieldName = randomAlphaOfLengthBetween(1, 10);
|
String fieldName = randomAlphaOfLengthBetween(1, 10);
|
||||||
String fieldValue = randomAlphaOfLengthBetween(1, 10);
|
String fieldValue = randomAlphaOfLengthBetween(1, 10);
|
||||||
doc.put(Fields.SOURCE, Collections.singletonMap(fieldName, fieldValue));
|
doc.put(Fields.SOURCE, Collections.singletonMap(fieldName, fieldValue));
|
||||||
docs.add(doc);
|
docs.add(doc);
|
||||||
Map<String, Object> expectedDoc = new HashMap<>();
|
|
||||||
expectedDoc.put(INDEX.getFieldName(), index);
|
|
||||||
expectedDoc.put(TYPE.getFieldName(), type);
|
|
||||||
expectedDoc.put(ID.getFieldName(), id);
|
|
||||||
expectedDoc.put(Fields.SOURCE, Collections.singletonMap(fieldName, fieldValue));
|
expectedDoc.put(Fields.SOURCE, Collections.singletonMap(fieldName, fieldValue));
|
||||||
expectedDocs.add(expectedDoc);
|
expectedDocs.add(expectedDoc);
|
||||||
}
|
}
|
||||||
|
@ -172,6 +179,8 @@ public class SimulatePipelineRequestParsingTests extends ESTestCase {
|
||||||
assertThat(metadataMap.get(INDEX), equalTo(expectedDocument.get(INDEX.getFieldName())));
|
assertThat(metadataMap.get(INDEX), equalTo(expectedDocument.get(INDEX.getFieldName())));
|
||||||
assertThat(metadataMap.get(TYPE), equalTo(expectedDocument.get(TYPE.getFieldName())));
|
assertThat(metadataMap.get(TYPE), equalTo(expectedDocument.get(TYPE.getFieldName())));
|
||||||
assertThat(metadataMap.get(ID), equalTo(expectedDocument.get(ID.getFieldName())));
|
assertThat(metadataMap.get(ID), equalTo(expectedDocument.get(ID.getFieldName())));
|
||||||
|
assertThat(metadataMap.get(ROUTING), equalTo(expectedDocument.get(ROUTING.getFieldName())));
|
||||||
|
assertThat(metadataMap.get(PARENT), equalTo(expectedDocument.get(PARENT.getFieldName())));
|
||||||
assertThat(ingestDocument.getSourceAndMetadata(), equalTo(expectedDocument.get(Fields.SOURCE)));
|
assertThat(ingestDocument.getSourceAndMetadata(), equalTo(expectedDocument.get(Fields.SOURCE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ public class ConfigurationUtilsTests extends ESTestCase {
|
||||||
Map<String, Object> fizz = new HashMap<>();
|
Map<String, Object> fizz = new HashMap<>();
|
||||||
fizz.put("buzz", "hello world");
|
fizz.put("buzz", "hello world");
|
||||||
config.put("fizz", fizz);
|
config.put("fizz", fizz);
|
||||||
|
config.put("num", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testReadStringProperty() {
|
public void testReadStringProperty() {
|
||||||
|
@ -93,6 +94,22 @@ public class ConfigurationUtilsTests extends ESTestCase {
|
||||||
assertThat(val, equalTo(Collections.singletonList(2)));
|
assertThat(val, equalTo(Collections.singletonList(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testReadStringOrIntProperty() {
|
||||||
|
String val1 = ConfigurationUtils.readStringOrIntProperty(null, null, config, "foo", null);
|
||||||
|
String val2 = ConfigurationUtils.readStringOrIntProperty(null, null, config, "num", null);
|
||||||
|
assertThat(val1, equalTo("bar"));
|
||||||
|
assertThat(val2, equalTo("1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testReadStringOrIntPropertyInvalidType() {
|
||||||
|
try {
|
||||||
|
ConfigurationUtils.readStringOrIntProperty(null, null, config, "arr", null);
|
||||||
|
} catch (ElasticsearchParseException e) {
|
||||||
|
assertThat(e.getMessage(), equalTo(
|
||||||
|
"[arr] property isn't a string or int, but of type [java.util.Arrays$ArrayList]"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testReadProcessors() throws Exception {
|
public void testReadProcessors() throws Exception {
|
||||||
Processor processor = mock(Processor.class);
|
Processor processor = mock(Processor.class);
|
||||||
Map<String, Processor.Factory> registry =
|
Map<String, Processor.Factory> registry =
|
||||||
|
|
Loading…
Reference in New Issue