diff --git a/data-prepper-plugin-schema-cli/src/main/java/org/opensearch/dataprepper/schemas/DataPrepperPluginSchemaExecute.java b/data-prepper-plugin-schema-cli/src/main/java/org/opensearch/dataprepper/schemas/DataPrepperPluginSchemaExecute.java index ffa8e6fa87..3f52bd2a20 100644 --- a/data-prepper-plugin-schema-cli/src/main/java/org/opensearch/dataprepper/schemas/DataPrepperPluginSchemaExecute.java +++ b/data-prepper-plugin-schema-cli/src/main/java/org/opensearch/dataprepper/schemas/DataPrepperPluginSchemaExecute.java @@ -1,13 +1,10 @@ package org.opensearch.dataprepper.schemas; -import com.github.victools.jsonschema.generator.Module; import com.github.victools.jsonschema.generator.OptionPreset; import com.github.victools.jsonschema.generator.SchemaVersion; -import com.github.victools.jsonschema.module.jakarta.validation.JakartaValidationModule; -import com.github.victools.jsonschema.module.jakarta.validation.JakartaValidationOption; import org.opensearch.dataprepper.plugin.ClasspathPluginProvider; import org.opensearch.dataprepper.plugin.PluginProvider; -import org.opensearch.dataprepper.schemas.module.CustomJacksonModule; +import org.opensearch.dataprepper.schemas.module.DataPrepperModules; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import picocli.CommandLine; @@ -17,16 +14,11 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collection; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; -import static com.github.victools.jsonschema.module.jackson.JacksonOption.FLATTENED_ENUMS_FROM_JSONVALUE; -import static com.github.victools.jsonschema.module.jackson.JacksonOption.RESPECT_JSONPROPERTY_ORDER; -import static com.github.victools.jsonschema.module.jackson.JacksonOption.RESPECT_JSONPROPERTY_REQUIRED; - public class DataPrepperPluginSchemaExecute implements Runnable { private static final Logger LOG = LoggerFactory.getLogger(DataPrepperPluginSchemaExecute.class); static final String DEFAULT_PLUGINS_CLASSPATH = "org.opensearch.dataprepper.plugins"; @@ -52,14 +44,9 @@ public static void main(String[] args) { @Override public void run() { - final List modules = List.of( - new CustomJacksonModule(RESPECT_JSONPROPERTY_REQUIRED, RESPECT_JSONPROPERTY_ORDER, FLATTENED_ENUMS_FROM_JSONVALUE), - new JakartaValidationModule(JakartaValidationOption.NOT_NULLABLE_FIELD_IS_REQUIRED, - JakartaValidationOption.INCLUDE_PATTERN_EXPRESSIONS) - ); final PluginProvider pluginProvider = new ClasspathPluginProvider(); final PluginConfigsJsonSchemaConverter pluginConfigsJsonSchemaConverter = new PluginConfigsJsonSchemaConverter( - pluginProvider, new JsonSchemaConverter(modules, pluginProvider), siteUrl, siteBaseUrl); + pluginProvider, new JsonSchemaConverter(DataPrepperModules.dataPrepperModules(), pluginProvider), siteUrl, siteBaseUrl); final Class pluginType = pluginConfigsJsonSchemaConverter.pluginTypeNameToPluginType(pluginTypeName); final Map pluginNameToJsonSchemaMap = pluginConfigsJsonSchemaConverter.convertPluginConfigsIntoJsonSchemas( SchemaVersion.DRAFT_2020_12, OptionPreset.PLAIN_JSON, pluginType); diff --git a/data-prepper-plugin-schema/src/main/java/org/opensearch/dataprepper/schemas/module/DataPrepperJakartaValidationModule.java b/data-prepper-plugin-schema/src/main/java/org/opensearch/dataprepper/schemas/module/DataPrepperJakartaValidationModule.java new file mode 100644 index 0000000000..a4d27e7d20 --- /dev/null +++ b/data-prepper-plugin-schema/src/main/java/org/opensearch/dataprepper/schemas/module/DataPrepperJakartaValidationModule.java @@ -0,0 +1,34 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensearch.dataprepper.schemas.module; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.victools.jsonschema.generator.MemberScope; +import com.github.victools.jsonschema.module.jakarta.validation.JakartaValidationModule; +import com.github.victools.jsonschema.module.jakarta.validation.JakartaValidationOption; + +/** + * Custom {@link JakartaValidationModule} which overrides the default behavior of {@link JakartaValidationModule} + * for Data Prepper. + * It considers the {@link JsonProperty} annotation as well as the Jakarta validations. + */ +class DataPrepperJakartaValidationModule extends JakartaValidationModule { + public DataPrepperJakartaValidationModule(final JakartaValidationOption... options) { + super(options); + } + + @Override + protected boolean isRequired(final MemberScope member) { + final JsonProperty jsonPropertyAnnotation = member.getAnnotationConsideringFieldAndGetter(JsonProperty.class); + if (jsonPropertyAnnotation != null) { + if (jsonPropertyAnnotation.defaultValue() != null && !jsonPropertyAnnotation.defaultValue().isEmpty()) { + return false; + } + } + + return super.isRequired(member); + } +} diff --git a/data-prepper-plugin-schema/src/main/java/org/opensearch/dataprepper/schemas/module/DataPrepperModules.java b/data-prepper-plugin-schema/src/main/java/org/opensearch/dataprepper/schemas/module/DataPrepperModules.java new file mode 100644 index 0000000000..1a169b364b --- /dev/null +++ b/data-prepper-plugin-schema/src/main/java/org/opensearch/dataprepper/schemas/module/DataPrepperModules.java @@ -0,0 +1,25 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensearch.dataprepper.schemas.module; + +import com.github.victools.jsonschema.generator.Module; +import com.github.victools.jsonschema.module.jakarta.validation.JakartaValidationOption; + +import java.util.List; + +import static com.github.victools.jsonschema.module.jackson.JacksonOption.FLATTENED_ENUMS_FROM_JSONVALUE; +import static com.github.victools.jsonschema.module.jackson.JacksonOption.RESPECT_JSONPROPERTY_ORDER; +import static com.github.victools.jsonschema.module.jackson.JacksonOption.RESPECT_JSONPROPERTY_REQUIRED; + +public class DataPrepperModules { + public static List dataPrepperModules() { + return List.of( + new DataPrepperJakartaValidationModule(JakartaValidationOption.NOT_NULLABLE_FIELD_IS_REQUIRED, + JakartaValidationOption.INCLUDE_PATTERN_EXPRESSIONS), + new CustomJacksonModule(RESPECT_JSONPROPERTY_REQUIRED, RESPECT_JSONPROPERTY_ORDER, FLATTENED_ENUMS_FROM_JSONVALUE) + ); + } +} diff --git a/data-prepper-plugin-schema/src/test/java/org/opensearch/dataprepper/schemas/module/DataPrepperJakartaValidationModuleTest.java b/data-prepper-plugin-schema/src/test/java/org/opensearch/dataprepper/schemas/module/DataPrepperJakartaValidationModuleTest.java new file mode 100644 index 0000000000..281a3a9bfc --- /dev/null +++ b/data-prepper-plugin-schema/src/test/java/org/opensearch/dataprepper/schemas/module/DataPrepperJakartaValidationModuleTest.java @@ -0,0 +1,113 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensearch.dataprepper.schemas.module; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.victools.jsonschema.generator.MemberScope; +import com.github.victools.jsonschema.module.jakarta.validation.JakartaValidationModule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.junit.platform.commons.support.ReflectionSupport; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.UUID; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class DataPrepperJakartaValidationModuleTest { + + @Mock + private MemberScope memberScope; + + DataPrepperJakartaValidationModule createObjectUnderTest() { + return spy(new DataPrepperJakartaValidationModule()); + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void isRequired_returns_inner_if_no_JsonProperty_annotation(final boolean innerIsRequired) throws NoSuchMethodException { + final DataPrepperJakartaValidationModule objectUnderTest = createObjectUnderTest(); + + final boolean isNullable = !innerIsRequired; + ReflectionSupport.invokeMethod( + JakartaValidationModule.class.getDeclaredMethod("isNullable", MemberScope.class), + doReturn(isNullable).when((JakartaValidationModule) objectUnderTest), + memberScope); + + assertThat(objectUnderTest.isRequired(memberScope), equalTo(innerIsRequired)); + } + + @Nested + class WithJsonProperty { + private JsonProperty jsonPropertyAnnotation; + + @BeforeEach + void setUp() { + jsonPropertyAnnotation = mock(JsonProperty.class); + when(memberScope.getAnnotationConsideringFieldAndGetter(JsonProperty.class)) + .thenReturn(jsonPropertyAnnotation); + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void isRequired_returns_inner_if_JsonProperty_annotation_has_null_defaultValue(final boolean innerIsRequired) throws NoSuchMethodException { + final DataPrepperJakartaValidationModule objectUnderTest = createObjectUnderTest(); + + final boolean isNullable = !innerIsRequired; + ReflectionSupport.invokeMethod( + JakartaValidationModule.class.getDeclaredMethod("isNullable", MemberScope.class), + doReturn(isNullable).when((JakartaValidationModule) objectUnderTest), + memberScope); + + when(jsonPropertyAnnotation.defaultValue()).thenReturn(null); + + assertThat(objectUnderTest.isRequired(memberScope), equalTo(innerIsRequired)); + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void isRequired_returns_inner_if_JsonProperty_annotation_has_empty_defaultValue(final boolean innerIsRequired) throws NoSuchMethodException { + final DataPrepperJakartaValidationModule objectUnderTest = createObjectUnderTest(); + + final boolean isNullable = !innerIsRequired; + ReflectionSupport.invokeMethod( + JakartaValidationModule.class.getDeclaredMethod("isNullable", MemberScope.class), + doReturn(isNullable).when((JakartaValidationModule) objectUnderTest), + memberScope); + + when(jsonPropertyAnnotation.defaultValue()).thenReturn(""); + + assertThat(objectUnderTest.isRequired(memberScope), equalTo(innerIsRequired)); + } + + @Test + void isRequired_returns_false_if_JsonProperty_has_default_value() throws NoSuchMethodException { + final DataPrepperJakartaValidationModule objectUnderTest = createObjectUnderTest(); + + when(jsonPropertyAnnotation.defaultValue()).thenReturn(UUID.randomUUID().toString()); + + assertThat(createObjectUnderTest().isRequired(memberScope), equalTo(false)); + + ReflectionSupport.invokeMethod( + JakartaValidationModule.class.getDeclaredMethod("isNullable", MemberScope.class), + verify(objectUnderTest, never()), + memberScope); + } + } +} \ No newline at end of file diff --git a/data-prepper-plugins/key-value-processor/src/main/java/org/opensearch/dataprepper/plugins/processor/keyvalue/KeyValueProcessor.java b/data-prepper-plugins/key-value-processor/src/main/java/org/opensearch/dataprepper/plugins/processor/keyvalue/KeyValueProcessor.java index 8c7cfeb28d..c7203bbbc1 100644 --- a/data-prepper-plugins/key-value-processor/src/main/java/org/opensearch/dataprepper/plugins/processor/keyvalue/KeyValueProcessor.java +++ b/data-prepper-plugins/key-value-processor/src/main/java/org/opensearch/dataprepper/plugins/processor/keyvalue/KeyValueProcessor.java @@ -62,6 +62,7 @@ public class KeyValueProcessor extends AbstractProcessor, Record bracketSet = Set.of('[', ']', '(', ')', '<', '>'); private final List tagsOnFailure; private final Character stringLiteralCharacter; + private final String keyPrefix; @DataPrepperPluginConstructor public KeyValueProcessor(final PluginMetrics pluginMetrics, @@ -190,6 +191,8 @@ public KeyValueProcessor(final PluginMetrics pluginMetrics, throw new InvalidPluginConfigurationException( String.format("key_value_when %s is not a valid expression statement", keyValueProcessorConfig.getKeyValueWhen())); } + + keyPrefix = keyValueProcessorConfig.getPrefix() != null ? keyValueProcessorConfig.getPrefix() : ""; } private String buildRegexFromCharacters(String s) { @@ -575,7 +578,7 @@ private Map executeConfigs(Map map) { if (keyValueProcessorConfig.getDeleteKeyRegex() != null && !Objects.equals(keyValueProcessorConfig.getDeleteKeyRegex(), "")) { key = key.replaceAll(keyValueProcessorConfig.getDeleteKeyRegex(), ""); } - key = keyValueProcessorConfig.getPrefix() + key; + key = keyPrefix + key; if (value != null && value instanceof String diff --git a/data-prepper-plugins/key-value-processor/src/main/java/org/opensearch/dataprepper/plugins/processor/keyvalue/KeyValueProcessorConfig.java b/data-prepper-plugins/key-value-processor/src/main/java/org/opensearch/dataprepper/plugins/processor/keyvalue/KeyValueProcessorConfig.java index 945b8f7faf..6ecbbfdda6 100644 --- a/data-prepper-plugins/key-value-processor/src/main/java/org/opensearch/dataprepper/plugins/processor/keyvalue/KeyValueProcessorConfig.java +++ b/data-prepper-plugins/key-value-processor/src/main/java/org/opensearch/dataprepper/plugins/processor/keyvalue/KeyValueProcessorConfig.java @@ -29,16 +29,9 @@ public class KeyValueProcessorConfig { static final Map DEFAULT_DEFAULT_VALUES = Map.of(); public static final String DEFAULT_VALUE_SPLIT_CHARACTERS = "="; static final Object DEFAULT_NON_MATCH_VALUE = null; - static final String DEFAULT_PREFIX = ""; - static final String DEFAULT_DELETE_KEY_REGEX = ""; - static final String DEFAULT_DELETE_VALUE_REGEX = ""; - static final WhitespaceOption DEFAULT_WHITESPACE = WhitespaceOption.LENIENT; - static final boolean DEFAULT_SKIP_DUPLICATE_VALUES = false; - static final boolean DEFAULT_REMOVE_BRACKETS = false; - static final boolean DEFAULT_VALUE_GROUPING = false; - static final boolean DEFAULT_RECURSIVE = false; @NotEmpty + @JsonProperty(defaultValue = DEFAULT_SOURCE) @JsonPropertyDescription("The source field to parse for key-value pairs. The default value is message.") private String source = DEFAULT_SOURCE; @@ -56,6 +49,7 @@ public class KeyValueProcessorConfig { @JsonProperty("field_delimiter_regex") @JsonPropertyDescription("A regular expression specifying the delimiter that separates key-value pairs. " + + "For example, to split on multiple & characters use &+. " + "Special regular expression characters such as [ and ] must be escaped with \\\\. " + "This field cannot be defined along with field_split_characters. " + "If this option is not defined, the key_value processor will parse the source using field_split_characters.") @@ -70,12 +64,13 @@ public class KeyValueProcessorConfig { @JsonProperty("key_value_delimiter_regex") @JsonPropertyDescription("A regular expression specifying the delimiter that separates keys from their values within a key-value pair. " + + "For example, to split on multiple = characters use =+. " + "Special regular expression characters such as [ and ] must be escaped with \\\\. " + "This field cannot be defined along with value_split_characters. " + "If this option is not defined, the key_value processor will parse the source using value_split_characters.") private String keyValueDelimiterRegex; - @JsonProperty("default_values") + @JsonProperty(value = "default_values", defaultValue = "{}") @JsonPropertyDescription("A map specifying the default keys and their values that should be added " + "to the event in case these keys do not exist in the source field being parsed. " + "If the key was parsed from the source field that value will remain and the default value is not used. " + @@ -89,63 +84,58 @@ public class KeyValueProcessorConfig { "The default behavior is to drop the key-value pair.") private Object nonMatchValue = DEFAULT_NON_MATCH_VALUE; - @JsonProperty("include_keys") + @JsonProperty(value = "include_keys", defaultValue = "[]") @JsonPropertyDescription("An array specifying the keys that should be included in the destination field. " + "By default, all keys will be added.") @NotNull private List includeKeys = DEFAULT_INCLUDE_KEYS; - @JsonProperty("exclude_keys") + @JsonProperty(value = "exclude_keys", defaultValue = "[]") @JsonPropertyDescription("An array specifying the parsed keys that should be excluded from the destination field. " + "By default, no keys will be excluded.") @NotNull private List excludeKeys = DEFAULT_EXCLUDE_KEYS; @JsonPropertyDescription("A prefix to append before all keys. By default no prefix is added.") - @NotNull - private String prefix = DEFAULT_PREFIX; + private String prefix = null; @JsonProperty("delete_key_regex") @JsonPropertyDescription("A regular expression specifying characters to delete from the key. " + "Special regular expression characters such as [ and ] must be escaped with \\\\. " + "Cannot be an empty string. " + "By default, no characters are deleted from the key.") - @NotNull - private String deleteKeyRegex = DEFAULT_DELETE_KEY_REGEX; + private String deleteKeyRegex; @JsonProperty("delete_value_regex") @JsonPropertyDescription("A regular expression specifying characters to delete from the value. " + "Special regular expression characters such as [ and ] must be escaped with \\\\. " + "Cannot be an empty string. " + "By default, no characters are deleted from the value.") - @NotNull - private String deleteValueRegex = DEFAULT_DELETE_VALUE_REGEX; + private String deleteValueRegex; - @JsonProperty("transform_key") + @JsonProperty(value = "transform_key", defaultValue = "none") @JsonPropertyDescription("Allows transforming the key's name such as making the name all lowercase.") - @NotNull private TransformOption transformKey = TransformOption.NONE; - @JsonProperty("whitespace") + @JsonProperty(value = "whitespace", defaultValue = "lenient") @JsonPropertyDescription("Specifies whether to be lenient or strict with the acceptance of " + "unnecessary white space surrounding the configured value-split sequence. " + "In this case, strict means that whitespace is trimmed and lenient means it is retained in the key name and in the value." + "Default is lenient.") @NotNull - private WhitespaceOption whitespace = DEFAULT_WHITESPACE; + private WhitespaceOption whitespace = WhitespaceOption.LENIENT; - @JsonProperty("skip_duplicate_values") + @JsonProperty(value = "skip_duplicate_values", defaultValue = "false") @JsonPropertyDescription("A Boolean option for removing duplicate key-value pairs. When set to true, " + "only one unique key-value pair will be preserved. Default is false.") @NotNull - private boolean skipDuplicateValues = DEFAULT_SKIP_DUPLICATE_VALUES; + private boolean skipDuplicateValues = false; - @JsonProperty("remove_brackets") + @JsonProperty(value = "remove_brackets", defaultValue = "false") @JsonPropertyDescription("Specifies whether to treat certain grouping characters as wrapping text that should be removed from values." + "When set to true, the following grouping characters will be removed: square brackets, angle brackets, and parentheses. " + "The default configuration is false which retains those grouping characters.") - @NotNull - private boolean removeBrackets = DEFAULT_REMOVE_BRACKETS; + private boolean removeBrackets; @JsonProperty("value_grouping") @JsonPropertyDescription("Specifies whether to group values using predefined grouping delimiters. " + @@ -154,9 +144,9 @@ public class KeyValueProcessorConfig { "{...}, [...], <...>, (...), \"...\", '...', http://... (space), and https:// (space). " + "Default is false. For example, if value_grouping is true, then " + "{\"key1=[a=b,c=d]&key2=value2\"} parses to {\"key1\": \"[a=b,c=d]\", \"key2\": \"value2\"}.") - private boolean valueGrouping = DEFAULT_VALUE_GROUPING; + private boolean valueGrouping = false; - @JsonProperty("recursive") + @JsonProperty(value = "recursive", defaultValue = "false") @JsonPropertyDescription("Specifies whether to recursively obtain additional key-value pairs from values. " + "The extra key-value pairs will be stored as nested objects within the destination object. Default is false. " + "The levels of recursive parsing must be defined by different brackets for each level: " + @@ -166,8 +156,7 @@ public class KeyValueProcessorConfig { "remove_brackets cannot also be true;\n" + "skip_duplicate_values will always be true;\n" + "whitespace will always be \"strict\".") - @NotNull - private boolean recursive = DEFAULT_RECURSIVE; + private boolean recursive = false; @JsonProperty("overwrite_if_destination_exists") @JsonPropertyDescription("Specifies whether to overwrite existing fields if there are key conflicts " + diff --git a/data-prepper-plugins/key-value-processor/src/main/java/org/opensearch/dataprepper/plugins/processor/keyvalue/TransformOption.java b/data-prepper-plugins/key-value-processor/src/main/java/org/opensearch/dataprepper/plugins/processor/keyvalue/TransformOption.java index bf12807666..991d087830 100644 --- a/data-prepper-plugins/key-value-processor/src/main/java/org/opensearch/dataprepper/plugins/processor/keyvalue/TransformOption.java +++ b/data-prepper-plugins/key-value-processor/src/main/java/org/opensearch/dataprepper/plugins/processor/keyvalue/TransformOption.java @@ -10,11 +10,12 @@ import java.util.Arrays; import java.util.Map; +import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; public enum TransformOption { - NONE("", key -> key), + NONE("none", key -> key), LOWERCASE("lowercase", String::toLowerCase), UPPERCASE("uppercase", String::toUpperCase), CAPITALIZE("capitalize", key -> key.substring(0, 1).toUpperCase() + key.substring(1)); @@ -44,6 +45,8 @@ Function getTransformFunction() { @JsonCreator public static TransformOption fromTransformName(final String transformName) { + if (Objects.equals(transformName, "")) + return NONE; return NAMES_MAP.get(transformName); } } diff --git a/data-prepper-plugins/key-value-processor/src/test/java/org/opensearch/dataprepper/plugins/processor/keyvalue/KeyValueProcessorTests.java b/data-prepper-plugins/key-value-processor/src/test/java/org/opensearch/dataprepper/plugins/processor/keyvalue/KeyValueProcessorTests.java index c8fa597697..76ada6d76b 100644 --- a/data-prepper-plugins/key-value-processor/src/test/java/org/opensearch/dataprepper/plugins/processor/keyvalue/KeyValueProcessorTests.java +++ b/data-prepper-plugins/key-value-processor/src/test/java/org/opensearch/dataprepper/plugins/processor/keyvalue/KeyValueProcessorTests.java @@ -57,8 +57,6 @@ public class KeyValueProcessorTests { @Mock private ExpressionEvaluator expressionEvaluator; - private KeyValueProcessor keyValueProcessor; - static Record buildRecordWithEvent(final Map data) { return new Record<>(JacksonEvent.builder() .withData(data) @@ -93,12 +91,9 @@ void setup() { lenient().when(mockConfig.getDropKeysWithNoValue()).thenReturn(false); final String keyValueWhen = UUID.randomUUID().toString(); - when(mockConfig.getKeyValueWhen()).thenReturn(keyValueWhen); - when(expressionEvaluator.isValidExpressionStatement(keyValueWhen)).thenReturn(true); + lenient().when(mockConfig.getKeyValueWhen()).thenReturn(keyValueWhen); + lenient().when(expressionEvaluator.isValidExpressionStatement(keyValueWhen)).thenReturn(true); lenient().when(expressionEvaluator.evaluateConditional(eq(keyValueWhen), any(Event.class))).thenReturn(true); - - - keyValueProcessor = new KeyValueProcessor(pluginMetrics, mockConfig, expressionEvaluator); } private KeyValueProcessor createObjectUnderTest() { @@ -119,7 +114,7 @@ void invalid_expression_statement_throws_InvalidPluginConfigurationException() { @Test void testSingleKvToObjectKeyValueProcessor() { final Record record = getMessage("key1=value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -152,7 +147,7 @@ void testKeyValueProcessorWithoutMessage() { final Map testData = new HashMap(); testData.put("notMessage", "not a message"); final Record record = buildRecordWithEvent(testData); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); assertThat(editedRecords.size(), equalTo(1)); assertThat(editedRecords.get(0), notNullValue()); LinkedHashMap parsed_message = editedRecords.get(0).getData().get("parsed_message", LinkedHashMap.class); @@ -162,7 +157,7 @@ void testKeyValueProcessorWithoutMessage() { @Test void testMultipleKvToObjectKeyValueProcessor() { final Record record = getMessage("key1=value1&key2=value2"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(2)); @@ -174,10 +169,8 @@ void testMultipleKvToObjectKeyValueProcessor() { void testDropKeysWithNoValue() { lenient().when(mockConfig.getDropKeysWithNoValue()).thenReturn(true); - keyValueProcessor = createObjectUnderTest(); - final Record record = getMessage("key1=value1&key2"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -258,8 +251,7 @@ void testValueGroupingWithOutStringLiterals() { lenient().when(mockConfig.getFieldSplitCharacters()).thenReturn(" ,"); lenient().when(mockConfig.getValueGrouping()).thenReturn(true); final Record record = getMessage(message); - keyValueProcessor = createObjectUnderTest(); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final Event event = editedRecords.get(0).getData(); assertThat(event.containsKey("parsed_message"), is(false)); @@ -277,8 +269,7 @@ void testStringLiteralCharacter(String literalString) { lenient().when(mockConfig.getFieldSplitCharacters()).thenReturn(" &"); lenient().when(mockConfig.getValueGrouping()).thenReturn(true); final Record record = getMessage(message); - keyValueProcessor = createObjectUnderTest(); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final Event event = editedRecords.get(0).getData(); assertThat(event.containsKey("parsed_message"), is(false)); @@ -292,7 +283,7 @@ void testStringLiteralCharacter(String literalString) { void testWriteToRoot() { when(mockConfig.getDestination()).thenReturn(null); final Record record = getMessage("key1=value1&key2=value2"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final Event event = editedRecords.get(0).getData(); assertThat(event.containsKey("parsed_message"), is(false)); @@ -308,7 +299,7 @@ void testWriteToRootWithOverwrite() { when(mockConfig.getDestination()).thenReturn(null); final Record record = getMessage("key1=value1&key2=value2"); record.getData().put("key1", "value to be overwritten"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final Event event = editedRecords.get(0).getData(); @@ -322,7 +313,7 @@ void testWriteToRootWithOverwrite() { void testWriteToDestinationWithOverwrite() { final Record record = getMessage("key1=value1&key2=value2"); record.getData().put("parsed_message", "value to be overwritten"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(2)); @@ -336,7 +327,7 @@ void testWriteToRootWithOverwriteDisabled() { when(mockConfig.getOverwriteIfDestinationExists()).thenReturn(false); final Record record = getMessage("key1=value1&key2=value2"); record.getData().put("key1", "value will not be overwritten"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final Event event = editedRecords.get(0).getData(); @@ -351,7 +342,7 @@ void testWriteToDestinationWithOverwriteDisabled() { when(mockConfig.getOverwriteIfDestinationExists()).thenReturn(false); final Record record = getMessage("key1=value1&key2=value2"); record.getData().put("parsed_message", "value will not be overwritten"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final Event event = editedRecords.get(0).getData(); assertThat(event.containsKey("parsed_message"), is(true)); @@ -363,10 +354,8 @@ void testSingleRegexFieldDelimiterKvToObjectKeyValueProcessor() { when(mockConfig.getFieldDelimiterRegex()).thenReturn(":_*:"); when(mockConfig.getFieldSplitCharacters()).thenReturn(null); - keyValueProcessor = createObjectUnderTest(); - final Record record = getMessage("key1=value1:_____:key2=value2"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); LOG.info("parsedMessage={}", parsed_message); @@ -394,10 +383,8 @@ void testSingleRegexKvDelimiterKvToObjectKeyValueProcessor() { when(mockConfig.getKeyValueDelimiterRegex()).thenReturn(":\\+*:"); when(mockConfig.getValueSplitCharacters()).thenReturn(null); - keyValueProcessor = createObjectUnderTest(); - final Record record = getMessage("key1:++:value1&key2:+:value2"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(2)); @@ -440,7 +427,7 @@ void testBadDeleteValueRegexKeyValueProcessor() { @Test void testDuplicateKeyToArrayValueProcessor() { final Record record = getMessage("key1=value1&key1=value2&key1=value3"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); final ArrayList expectedValue = new ArrayList<>(); @@ -454,7 +441,7 @@ void testDuplicateKeyToArrayValueProcessor() { @Test void testDuplicateKeyToArrayWithNonMatchValueProcessor() { final Record record = getMessage("key1=value1&key1=value2&key1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); final ArrayList expectedValue = new ArrayList(); @@ -468,10 +455,9 @@ void testDuplicateKeyToArrayWithNonMatchValueProcessor() { @Test void testFieldSplitCharactersKeyValueProcessor() { when(mockConfig.getFieldSplitCharacters()).thenReturn("&!"); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("key1=value1&key1=value2!key1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); final ArrayList expectedValue = new ArrayList(); @@ -486,10 +472,9 @@ void testFieldSplitCharactersKeyValueProcessor() { void testFieldSplitCharactersDoesntSupercedeDelimiterKeyValueProcessor() { when(mockConfig.getFieldDelimiterRegex()).thenReturn(":d+:"); when(mockConfig.getFieldSplitCharacters()).thenReturn(null); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("key1=value1:d:key1=value2:d:key1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); final ArrayList expectedValue = new ArrayList(); @@ -504,10 +489,9 @@ void testFieldSplitCharactersDoesntSupercedeDelimiterKeyValueProcessor() { void testIncludeKeysKeyValueProcessor() { final List includeKeys = List.of("key2", "key3"); when(mockConfig.getIncludeKeys()).thenReturn(includeKeys); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("key1=value1&key2=value2&key3=value3"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(2)); @@ -519,10 +503,9 @@ void testIncludeKeysKeyValueProcessor() { void testIncludeKeysNoMatchKeyValueProcessor() { final List includeKeys = Collections.singletonList("noMatch"); when(mockConfig.getIncludeKeys()).thenReturn(includeKeys); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("key1=value1&key2=value2"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(0)); @@ -531,10 +514,9 @@ void testIncludeKeysNoMatchKeyValueProcessor() { @Test void testIncludeKeysAsDefaultKeyValueProcessor() { when(mockConfig.getIncludeKeys()).thenReturn(List.of()); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("key1=value1&key2=value2"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(2)); @@ -546,10 +528,9 @@ void testIncludeKeysAsDefaultKeyValueProcessor() { void testExcludeKeysKeyValueProcessor() { final List excludeKeys = List.of("key2"); when(mockConfig.getExcludeKeys()).thenReturn(excludeKeys); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("key1=value1&key2=value2"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -559,10 +540,9 @@ void testExcludeKeysKeyValueProcessor() { @Test void testExcludeKeysAsDefaultKeyValueProcessor() { when(mockConfig.getExcludeKeys()).thenReturn(List.of()); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("key1=value1&key2=value2"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(2)); @@ -584,10 +564,9 @@ void testIncludeExcludeKeysOverlapKeyValueProcessor() { void testDefaultKeysNoOverlapsBetweenEventKvProcessor() { final Map defaultMap = Map.of("dKey", "dValue"); when(mockConfig.getDefaultValues()).thenReturn(defaultMap); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("key1=value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(2)); @@ -601,10 +580,9 @@ void testDefaultKeysAlreadyInMessageKvProcessor(boolean skipDuplicateValues) { final Map defaultMap = Map.of("dKey", "dValue"); when(mockConfig.getDefaultValues()).thenReturn(defaultMap); when(mockConfig.getSkipDuplicateValues()).thenReturn(skipDuplicateValues); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("key1=value1&dKey=abc"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(2)); @@ -620,10 +598,9 @@ void testDefaultIncludeKeysOverlapKvProcessor(boolean skipDuplicateValues) { when(mockConfig.getDefaultValues()).thenReturn(defaultMap); when(mockConfig.getIncludeKeys()).thenReturn(includeKeys); when(mockConfig.getSkipDuplicateValues()).thenReturn(skipDuplicateValues); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("key1=value1&key2=value2"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -638,10 +615,9 @@ void testDefaultPrioritizeIncludeKeysKvProcessor(boolean skipDuplicateValues) { when(mockConfig.getDefaultValues()).thenReturn(defaultMap); when(mockConfig.getIncludeKeys()).thenReturn(includeKeys); when(mockConfig.getSkipDuplicateValues()).thenReturn(skipDuplicateValues); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("key1=value1&key2=abc"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(2)); @@ -657,10 +633,9 @@ void testIncludeKeysNotInRecordMessageKvProcessor(boolean skipDuplicateValues) { when(mockConfig.getDefaultValues()).thenReturn(defaultMap); when(mockConfig.getIncludeKeys()).thenReturn(includeKeys); when(mockConfig.getSkipDuplicateValues()).thenReturn(skipDuplicateValues); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("key2=abc"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -682,7 +657,7 @@ void testCustomPrefixKvProcessor() { when(mockConfig.getPrefix()).thenReturn("TEST_"); final Record record = getMessage("key1=value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -692,7 +667,7 @@ void testCustomPrefixKvProcessor() { @Test void testDefaultNonMatchValueKvProcessor() { final Record record = getMessage("key1+value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -704,7 +679,7 @@ void testCustomStringNonMatchValueKvProcessor() { when(mockConfig.getNonMatchValue()).thenReturn("BAD_MATCH"); final Record record = getMessage("key1+value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -716,7 +691,7 @@ void testCustomBoolNonMatchValueKvProcessor() { when(mockConfig.getNonMatchValue()).thenReturn(true); final Record record = getMessage("key1+value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -728,7 +703,7 @@ void testDeleteKeyRegexKvProcessor() { when(mockConfig.getDeleteKeyRegex()).thenReturn("\\s"); final Record record = getMessage("key1 =value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -740,7 +715,7 @@ void testDeleteValueRegexKvProcessor() { when(mockConfig.getDeleteValueRegex()).thenReturn("\\s"); final Record record = getMessage("key1=value1 &key2=value2"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(2)); @@ -754,7 +729,7 @@ void testDeleteValueWithNonStringRegexKvProcessor() { when(mockConfig.getNonMatchValue()).thenReturn(3); final Record record = getMessage("key1&key2=value2"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(2)); @@ -768,7 +743,7 @@ void testDeleteValueAndKeyRegexKvProcessor() { when(mockConfig.getDeleteValueRegex()).thenReturn("\\s"); final Record record = getMessage("key1 =value1 & key2 = value2 "); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(2)); @@ -781,7 +756,7 @@ void testLowercaseTransformKvProcessor() { when(mockConfig.getTransformKey()).thenReturn(TransformOption.LOWERCASE); final Record record = getMessage("Key1=value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -793,7 +768,7 @@ void testUppercaseTransformKvProcessor() { when(mockConfig.getTransformKey()).thenReturn(TransformOption.UPPERCASE); final Record record = getMessage("key1=value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -805,7 +780,7 @@ void testCapitalizeTransformKvProcessor() { when(mockConfig.getTransformKey()).thenReturn(TransformOption.CAPITALIZE); final Record record = getMessage("key1=value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsedMessage = getLinkedHashMap(editedRecords); assertThat(parsedMessage.size(), equalTo(1)); @@ -817,7 +792,7 @@ void testStrictWhitespaceKvProcessor() { when(mockConfig.getWhitespace()).thenReturn(WhitespaceOption.STRICT); final Record record = getMessage("key1 = value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -827,7 +802,7 @@ void testStrictWhitespaceKvProcessor() { @Test void testFalseSkipDuplicateValuesKvProcessor() { final Record record = getMessage("key1=value1&key1=value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); final ArrayList expectedValue = new ArrayList(); @@ -843,7 +818,7 @@ void testTrueSkipDuplicateValuesKvProcessor() { when(mockConfig.getSkipDuplicateValues()).thenReturn(true); final Record record = getMessage("key1=value1&key1=value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(1)); @@ -855,7 +830,7 @@ void testTrueThreeInputsDuplicateValuesKvProcessor() { when(mockConfig.getSkipDuplicateValues()).thenReturn(true); final Record record = getMessage("key1=value1&key1=value2&key1=value1"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); final ArrayList expectedValue = new ArrayList(); @@ -871,7 +846,7 @@ void testTrueRemoveBracketsKvProcessor() { when(mockConfig.getRemoveBrackets()).thenReturn(true); final Record record = getMessage("key1=(value1)&key2=[value2]&key3="); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(3)); @@ -885,7 +860,7 @@ void testTrueRemoveMultipleBracketsKvProcessor() { when(mockConfig.getRemoveBrackets()).thenReturn(true); final Record record = getMessage("key1=((value1)&key2=[value1][value2]"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(2)); @@ -898,7 +873,7 @@ void testBasicRecursiveKvProcessor() { when(mockConfig.getRecursive()).thenReturn(true); final Record record = getMessage("item1=[item1-subitem1=item1-subitem1-value&item1-subitem2=item1-subitem2-value]&item2=item2-value"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); final Map expectedValueMap = new HashMap<>(); @@ -915,7 +890,7 @@ void testMultiRecursiveKvProcessor() { when(mockConfig.getRecursive()).thenReturn(true); final Record record = getMessage("item1=[item1-subitem1=(inner1=abc&inner2=xyz)&item1-subitem2=item1-subitem2-value]&item2=item2-value"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); final Map expectedValueMap = new HashMap<>(); @@ -937,7 +912,7 @@ void testTransformKeyRecursiveKvProcessor() { when(mockConfig.getTransformKey()).thenReturn(TransformOption.CAPITALIZE); final Record record = getMessage("item1=[item1-subitem1=item1-subitem1-value&item1-subitem2=item1-subitem2-value]&item2=item2-value"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); final Map expectedValueMap = new HashMap<>(); @@ -954,10 +929,9 @@ void testIncludeInnerKeyRecursiveKvProcessor() { final List includeKeys = List.of("item1-subitem1"); when(mockConfig.getRecursive()).thenReturn(true); when(mockConfig.getIncludeKeys()).thenReturn(includeKeys); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("item1=[item1-subitem1=item1-subitem1-value&item1-subitem2=item1-subitem2-value]&item2=item2-value"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(0)); @@ -968,10 +942,9 @@ void testExcludeInnerKeyRecursiveKvProcessor() { final List excludeKeys = List.of("item1-subitem1"); when(mockConfig.getRecursive()).thenReturn(true); when(mockConfig.getExcludeKeys()).thenReturn(excludeKeys); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("item1=[item1-subitem1=item1-subitem1-value&item1-subitem2=item1-subitem2-value]&item2=item2-value"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); final Map expectedValueMap = new HashMap<>(); @@ -988,10 +961,9 @@ void testDefaultInnerKeyRecursiveKvProcessor() { final Map defaultMap = Map.of("item1-subitem1", "default"); when(mockConfig.getRecursive()).thenReturn(true); when(mockConfig.getDefaultValues()).thenReturn(defaultMap); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("item1=[item1-subitem1=item1-subitem1-value&item1-subitem2=item1-subitem2-value]&item2=item2-value"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); final Map expectedValueMap = new HashMap<>(); @@ -1008,10 +980,9 @@ void testDefaultInnerKeyRecursiveKvProcessor() { void testTagsAddedWhenParsingFails() { when(mockConfig.getRecursive()).thenReturn(true); when(mockConfig.getTagsOnFailure()).thenReturn(List.of("tag1", "tag2")); - keyValueProcessor = createObjectUnderTest(); final Record record = getMessage("item1=[]"); - final List> editedRecords = (List>) keyValueProcessor.doExecute(Collections.singletonList(record)); + final List> editedRecords = (List>) createObjectUnderTest().doExecute(Collections.singletonList(record)); final LinkedHashMap parsed_message = getLinkedHashMap(editedRecords); assertThat(parsed_message.size(), equalTo(0)); @@ -1020,7 +991,7 @@ void testTagsAddedWhenParsingFails() { @Test void testShutdownIsReady() { - assertThat(keyValueProcessor.isReadyForShutdown(), is(true)); + assertThat(createObjectUnderTest().isReadyForShutdown(), is(true)); } private Record getMessage(String message) { diff --git a/data-prepper-plugins/key-value-processor/src/test/java/org/opensearch/dataprepper/plugins/processor/keyvalue/TransformOptionTest.java b/data-prepper-plugins/key-value-processor/src/test/java/org/opensearch/dataprepper/plugins/processor/keyvalue/TransformOptionTest.java index 53d3b13164..a39ea8dbc3 100644 --- a/data-prepper-plugins/key-value-processor/src/test/java/org/opensearch/dataprepper/plugins/processor/keyvalue/TransformOptionTest.java +++ b/data-prepper-plugins/key-value-processor/src/test/java/org/opensearch/dataprepper/plugins/processor/keyvalue/TransformOptionTest.java @@ -5,6 +5,7 @@ package org.opensearch.dataprepper.plugins.processor.keyvalue; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -28,6 +29,11 @@ void fromTransformName_returns_expected_value(final TransformOption transformOpt assertThat(TransformOption.fromTransformName(transformOption.getTransformName()), equalTo(transformOption)); } + @Test + void fromTransformName_returns_none_if_empty_string() { + assertThat(TransformOption.fromTransformName(""), equalTo(TransformOption.NONE)); + } + @ParameterizedTest @EnumSource(TransformOption.class) void getTransformName_returns_non_empty_null_for_all_types(final TransformOption transformOption) { @@ -35,7 +41,7 @@ void getTransformName_returns_non_empty_null_for_all_types(final TransformOption } @ParameterizedTest - @EnumSource(value = TransformOption.class, mode = EnumSource.Mode.EXCLUDE, names = {"NONE"}) + @EnumSource(value = TransformOption.class) void getTransformName_returns_non_empty_string_for_all_types_except_none(final TransformOption transformOption) { assertThat(transformOption.getTransformName(), notNullValue()); assertThat(transformOption.getTransformName(), not(emptyString())); @@ -51,7 +57,7 @@ static class TransformOptionToKnownName implements ArgumentsProvider { @Override public Stream provideArguments(final ExtensionContext extensionContext) { return Stream.of( - arguments(TransformOption.NONE, ""), + arguments(TransformOption.NONE, "none"), arguments(TransformOption.UPPERCASE, "uppercase"), arguments(TransformOption.LOWERCASE, "lowercase"), arguments(TransformOption.CAPITALIZE, "capitalize")