Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Whitespace #3004

Merged
merged 24 commits into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4c3e807
implement transform_key feature
shenkw1 Jul 3, 2023
e7918bd
fix unit tests
shenkw1 Jul 3, 2023
a89d64a
fix unit tests
shenkw1 Jul 4, 2023
72cc32f
remove bin files
shenkw1 Jul 5, 2023
204817b
add static final variable for string comparison
shenkw1 Jul 5, 2023
8bd192d
Merge branch 'opensearch-project:main' into transform-key
shenkw1 Jul 5, 2023
18cac16
modify validoptionsset to contain new private static variables
shenkw1 Jul 5, 2023
ff6b6e2
Merge branch 'transform-key' of https://github.com/shenkw1/data-prepp…
shenkw1 Jul 5, 2023
fb65a19
Merge branch 'opensearch-project:main' into transform-key
shenkw1 Jul 6, 2023
1702423
add whitespace description to readme, add configs
shenkw1 Jul 6, 2023
89071cc
writing whitespace impl
shenkw1 Jul 6, 2023
626ddd7
Merge branch 'opensearch-project:main' into main
shenkw1 Jul 10, 2023
1aca2b1
add whitespace impl
shenkw1 Jul 10, 2023
2166022
fix impl, writing tests
shenkw1 Jul 11, 2023
d8657db
write whitespace test
shenkw1 Jul 11, 2023
1a656b8
Merge branch 'main' of https://github.com/shenkw1/data-prepper into w…
shenkw1 Jul 11, 2023
4cba22d
Merge branch 'opensearch-project:main' into main
shenkw1 Jul 11, 2023
00c2d74
Merge branch 'main' of https://github.com/shenkw1/data-prepper into w…
shenkw1 Jul 11, 2023
452ae77
fix formatting, whitespace() -> trimWhitespace()
shenkw1 Jul 11, 2023
2f8f921
update logic to valid values set
shenkw1 Jul 12, 2023
e5e97f3
Merge branch 'opensearch-project:main' into main
shenkw1 Jul 12, 2023
e01db27
Merge branch 'main' of https://github.com/shenkw1/data-prepper into w…
shenkw1 Jul 12, 2023
65bc8e4
update variables to static
shenkw1 Jul 12, 2023
4f238e8
correct convention for private variables
shenkw1 Jul 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions data-prepper-plugins/key-value-processor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ When run, the processor will parse the message into the following output:
* Example: `transform_key` is `lowercase`. `{"Key1=value1"}` will parse into `{"key1": "value1"}`
* Example: `transform_key` is `uppercase`. `{"key1=value1"}` will parse into `{"Key1": "value1"}`
* Example: `transform_key` is `capitalize`. `{"key1=value1"}` will parse into `{"KEY1": "value1"}`
* `whitespace` - Specify whether to be lenient or strict with the acceptance of unnecessary whitespace surrounding the configured value-split sequence.
* Default: `lenient`
* Example: `whitespace` is `"lenient"`. `{"key1 = value1"}` will parse into `{"key1 ": " value1"}`
* Example: `whitespace` is `"strict"`. `{"key1 = value1"}` will parse into `{"key1": "value1"}`

## Developer Guide
This plugin is compatible with Java 14. See
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ public class KeyValueProcessor extends AbstractProcessor<Record<Event>, Record<E
private final Pattern fieldDelimiterPattern;
private final Pattern keyValueDelimiterPattern;
private final Set<String> includeKeysSet = new HashSet<String>();
private final String LOWERCASE_KEY = "lowercase";
private final String UPPERCASE_KEY = "uppercase";
private final String CAPITALIZE_KEY = "capitalize";
private final Set<String> validTransformOptionSet = Set.of("", LOWERCASE_KEY, UPPERCASE_KEY, CAPITALIZE_KEY);
private final String lowercaseKey = "lowercase";
private final String uppercaseKey = "uppercase";
private final String capitalizeKey = "capitalize";
private final Set<String> validTransformOptionSet = Set.of("", lowercaseKey, uppercaseKey, capitalizeKey);
private final String whitespaceStrict = "strict";
private final String whitespaceLenient = "lenient";
private final Set<String> validWhitespaceSet = Set.of(whitespaceLenient, whitespaceStrict);

@DataPrepperPluginConstructor
public KeyValueProcessor(final PluginMetrics pluginMetrics, final KeyValueProcessorConfig keyValueProcessorConfig) {
Expand Down Expand Up @@ -87,21 +90,25 @@ public KeyValueProcessor(final PluginMetrics pluginMetrics, final KeyValueProces
keyValueDelimiterPattern = Pattern.compile(regex);
}

if(!validateRegex(keyValueProcessorConfig.getDeleteKeyRegex())) {
if (!validateRegex(keyValueProcessorConfig.getDeleteKeyRegex())) {
throw new PatternSyntaxException("delete_key_regex is not a valid regex string", keyValueProcessorConfig.getDeleteKeyRegex(), -1);
}

if(!validateRegex(keyValueProcessorConfig.getDeleteValueRegex())) {
if (!validateRegex(keyValueProcessorConfig.getDeleteValueRegex())) {
throw new PatternSyntaxException("delete_value_regex is not a valid regex string", keyValueProcessorConfig.getDeleteValueRegex(), -1);
}

if(keyValueProcessorConfig.getIncludeKeys() != null) {
if (keyValueProcessorConfig.getIncludeKeys() != null) {
includeKeysSet.addAll(keyValueProcessorConfig.getIncludeKeys());
}

if(!validTransformOptionSet.contains(keyValueProcessorConfig.getTransformKey())) {
if (!validTransformOptionSet.contains(keyValueProcessorConfig.getTransformKey())) {
throw new IllegalArgumentException(String.format("The transform_key value: %s is not a valid option", keyValueProcessorConfig.getTransformKey()));
}

if (!(validWhitespaceSet.contains(keyValueProcessorConfig.getWhitespace()))) {
throw new IllegalArgumentException(String.format("The whitespace value: %s is not a valid option", keyValueProcessorConfig.getWhitespace()));
}
}

private String buildRegexFromCharacters(String s) {
Expand Down Expand Up @@ -170,7 +177,13 @@ public Collection<Record<Event>> doExecute(final Collection<Record<Event>> recor
value = ((String)value).replaceAll(keyValueProcessorConfig.getDeleteValueRegex(), "");
}

if(keyValueProcessorConfig.getTransformKey() != null
if (keyValueProcessorConfig.getWhitespace().equals(whitespaceStrict)) {
String[] whitespace_arr = trimWhitespace(key, value);
key = whitespace_arr[0];
value = whitespace_arr[1];
}

if (keyValueProcessorConfig.getTransformKey() != null
&& !keyValueProcessorConfig.getTransformKey().isEmpty()) {
key = transformKey(key);
}
Expand All @@ -184,12 +197,17 @@ public Collection<Record<Event>> doExecute(final Collection<Record<Event>> recor
return records;
}

private String[] trimWhitespace(String key, Object value) {
String[] arr = {key.stripTrailing(), value.toString().stripLeading()};
chenqi0805 marked this conversation as resolved.
Show resolved Hide resolved
return arr;
}

private String transformKey(String key) {
if(keyValueProcessorConfig.getTransformKey().equals(LOWERCASE_KEY)) {
if (keyValueProcessorConfig.getTransformKey().equals(lowercaseKey)) {
key = key.toLowerCase();
} else if(keyValueProcessorConfig.getTransformKey().equals(UPPERCASE_KEY)) {
} else if (keyValueProcessorConfig.getTransformKey().equals(uppercaseKey)) {
key = key.substring(0, 1).toUpperCase() + key.substring(1);
} else if(keyValueProcessorConfig.getTransformKey().equals(CAPITALIZE_KEY)) {
} else if (keyValueProcessorConfig.getTransformKey().equals(capitalizeKey)) {
key = key.toUpperCase();
}
return key;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class KeyValueProcessorConfig {
static final String DEFAULT_DELETE_KEY_REGEX = "";
static final String DEFAULT_DELETE_VALUE_REGEX = "";
static final String DEFAULT_TRANSFORM_KEY = "";
static final String DEFAULT_WHITESPACE = "lenient";

@NotEmpty
private String source = DEFAULT_SOURCE;
Expand Down Expand Up @@ -65,6 +66,10 @@ public class KeyValueProcessorConfig {
@NotNull
private String transformKey = DEFAULT_TRANSFORM_KEY;

@JsonProperty("whitespace")
@NotNull
private String whitespace = DEFAULT_WHITESPACE;

public String getSource() {
return source;
}
Expand Down Expand Up @@ -112,4 +117,8 @@ public String getDeleteValueRegex() {
public String getTransformKey() {
return transformKey;
}

public String getWhitespace() {
return whitespace;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void setup() {
lenient().when(mockConfig.getDeleteKeyRegex()).thenReturn(defaultConfig.getDeleteKeyRegex());
lenient().when(mockConfig.getDeleteValueRegex()).thenReturn(defaultConfig.getDeleteValueRegex());
lenient().when(mockConfig.getTransformKey()).thenReturn(defaultConfig.getTransformKey());
lenient().when(mockConfig.getWhitespace()).thenReturn(defaultConfig.getWhitespace());

keyValueProcessor = new KeyValueProcessor(pluginMetrics, mockConfig);
}
Expand Down Expand Up @@ -408,6 +409,18 @@ void testCapitalizeTransformKvProcessor() {
assertThatKeyEquals(parsed_message, "KEY1", "value1");
}

@Test
void testStrictWhitespaceKvProcessor() {
when(mockConfig.getWhitespace()).thenReturn("strict");

final Record<Event> record = getMessage("key1 = value1");
final List<Record<Event>> editedRecords = (List<Record<Event>>) keyValueProcessor.doExecute(Collections.singletonList(record));
final LinkedHashMap<String, Object> parsed_message = getLinkedHashMap(editedRecords);

assertThat(parsed_message.size(), equalTo(1));
assertThatKeyEquals(parsed_message, "key1", "value1");
}

@Test
void testShutdownIsReady() {
assertThat(keyValueProcessor.isReadyForShutdown(), is(true));
Expand All @@ -431,4 +444,4 @@ private void assertThatKeyEquals(final LinkedHashMap<String, Object> parsed_mess
assertThat(parsed_message.containsKey(key), is(true));
assertThat(parsed_message.get(key), equalTo(value));
}
}
}
Loading