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

ENH: backfill @AlsoRequired annotation to processor attributes #5086

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

/**
* Annotation used in schema generation to define the names and corresponding values of other required
* configurations if the configuration represented by the annotated field/method is present.
* configurations if the configuration represented by the annotated field/method takes non-null or true value.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import com.fasterxml.jackson.annotation.JsonClassDescription;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import org.opensearch.dataprepper.model.annotations.AlsoRequired;
import org.opensearch.dataprepper.model.annotations.UsesDataPrepperPlugin;
import org.opensearch.dataprepper.model.configuration.PluginModel;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
Expand All @@ -23,6 +24,7 @@
"Then, the processor performs an action on each group, helping reduce unnecessary log volume and " +
"creating aggregated logs over time.")
public class AggregateProcessorConfig {
static final String AGGREGATED_EVENTS_TAG_KEY = "aggregated_events_tag";
static final int DEFAULT_GROUP_DURATION_SECONDS = 180;

@JsonPropertyDescription("An unordered list by which to group events. Events with the same values as these keys are put into the same group. " +
Expand All @@ -49,10 +51,13 @@ public class AggregateProcessorConfig {

@JsonPropertyDescription("A boolean indicating if the unaggregated events should be forwarded to the next processor or sink in the chain.")
@JsonProperty("output_unaggregated_events")
@AlsoRequired(values = {
@AlsoRequired.Required(name = AGGREGATED_EVENTS_TAG_KEY)
})
private Boolean outputUnaggregatedEvents = false;

@JsonPropertyDescription("Tag to be used for aggregated events to distinguish aggregated events from unaggregated events.")
@JsonProperty("aggregated_events_tag")
@JsonProperty(AGGREGATED_EVENTS_TAG_KEY)
private String aggregatedEventsTag;

@JsonPropertyDescription("A <a href=\"https://opensearch.org/docs/latest/data-prepper/pipelines/expression-syntax/\">conditional expression</a>, such as <code>/some-key == \"test\"</code>, that will be evaluated to determine whether the processor will be run on the event.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import jakarta.validation.constraints.AssertTrue;
import org.opensearch.dataprepper.model.annotations.AlsoRequired;

import java.time.ZoneId;
import java.util.List;
Expand All @@ -22,6 +23,8 @@
"and converts timestamp information to the International Organization for Standardization (ISO) 8601 format. " +
"This timestamp information can be used as an event timestamp.")
public class DateProcessorConfig {
static final String MATCH_KEY = "match";
static final String FROM_TIME_RECEIVED_KEY = "from_time_received";
static final Boolean DEFAULT_FROM_TIME_RECEIVED = false;
static final Boolean DEFAULT_TO_ORIGINATION_METADATA = false;
static final String DEFAULT_DESTINATION = "@timestamp";
Expand Down Expand Up @@ -104,13 +107,19 @@ public static boolean isValidPattern(final String pattern) {
@JsonPropertyDescription("When <code>true</code>, the timestamp from the event metadata, " +
"which is the time at which the source receives the event, is added to the event data. " +
"This option cannot be defined at the same time as <code>match</code>. Default is <code>false</code>.")
@AlsoRequired(values = {
@AlsoRequired.Required(name = MATCH_KEY, allowedValues = {"null"})
})
private Boolean fromTimeReceived = DEFAULT_FROM_TIME_RECEIVED;

@JsonProperty("match")
@JsonPropertyDescription("The date match configuration. " +
"This option cannot be defined at the same time as <code>from_time_received</code>. " +
"The date processor will use the first pattern that matches each event's timestamp field. " +
"You must provide at least one pattern unless you have <code>from_time_received</code>.")
@AlsoRequired(values = {
@AlsoRequired.Required(name = FROM_TIME_RECEIVED_KEY, allowedValues = {"null", "false"})
})
private List<DateMatch> match;

@JsonProperty("destination")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.NotNull;
import org.opensearch.dataprepper.model.annotations.AlsoRequired;

import java.util.ArrayList;
import java.util.List;

@JsonPropertyOrder
@JsonClassDescription("The <code>flatten</code> processor transforms nested objects inside of events into flattened structures.")
public class FlattenProcessorConfig {
static final String REMOVE_LIST_INDICES_KEY = "remove_list_indices";

private static final List<String> DEFAULT_EXCLUDE_KEYS = new ArrayList<>();

Expand All @@ -39,14 +41,17 @@ public class FlattenProcessorConfig {
"The default is <code>false</code> which leaves the source fields.")
private boolean removeProcessedFields = false;

@JsonProperty("remove_list_indices")
@JsonProperty(REMOVE_LIST_INDICES_KEY)
@JsonPropertyDescription("When <code>true</code>, the processor converts the fields from the source map into lists and " +
"puts the lists into the target field. Default is <code>false</code>.")
private boolean removeListIndices = false;

@JsonProperty("remove_brackets")
@JsonPropertyDescription("When <code>true</code>, the processor also removes brackets around the indices. Can only be " +
"set to <code>true</code> when <code>remove_list_indices</code> is <code>true</code>.")
@AlsoRequired(values = {
@AlsoRequired.Required(name = REMOVE_LIST_INDICES_KEY, allowedValues = {"true"})
})
private boolean removeBrackets = false;

@JsonProperty("exclude_keys")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.Size;
import org.opensearch.dataprepper.model.annotations.AlsoRequired;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -21,6 +22,14 @@
@JsonPropertyOrder
@JsonClassDescription("You can use the <code>key_value</code> processor to create structured data by parsing key-value pairs from strings.")
public class KeyValueProcessorConfig {
static final String VALUE_GROUPING_KEY = "value_grouping";
static final String FIELD_DELIMITER_REGEX_KEY = "field_delimiter_regex";
static final String FIELD_SPLIT_CHARACTERS_KEY = "field_split_characters";
static final String VALUE_SPLIT_CHARACTERS_KEY = "value_split_characters";
static final String KEY_VALUE_DELIMITER_REGEX_KEY = "key_value_delimiter_regex";
static final String REMOVE_BRACKETS_KEY = "remove_brackets";
static final String SKIP_DUPLICATE_VALUES_KEY = "skip_duplicate_values";
static final String WHITESPACE_KEY = "whitespace";
static final String DEFAULT_SOURCE = "message";
static final String DEFAULT_DESTINATION = "parsed_message";
public static final String DEFAULT_FIELD_SPLIT_CHARACTERS = "&";
Expand All @@ -41,34 +50,47 @@ public class KeyValueProcessorConfig {
"The default value is <code>parsed_message</code>.")
private String destination = DEFAULT_DESTINATION;

@JsonProperty(value = "field_split_characters", defaultValue = DEFAULT_FIELD_SPLIT_CHARACTERS)
@JsonProperty(value = FIELD_SPLIT_CHARACTERS_KEY, defaultValue = DEFAULT_FIELD_SPLIT_CHARACTERS)
@JsonPropertyDescription("A string of characters specifying the delimiter that separates key-value pairs. " +
"Special regular expression characters such as <code>[</code> and <code>]</code> must be escaped with <code>\\\\</code>. " +
"This field cannot be defined along with <code>field_delimiter_regex</code>. " +
"The default value is <code>&amp;</code>.")
@AlsoRequired(values = {
@AlsoRequired.Required(name = FIELD_DELIMITER_REGEX_KEY, allowedValues = {"null"}),
})
private String fieldSplitCharacters = DEFAULT_FIELD_SPLIT_CHARACTERS;

@JsonProperty("field_delimiter_regex")
@JsonProperty(FIELD_DELIMITER_REGEX_KEY)
@JsonPropertyDescription("A regular expression specifying the delimiter that separates key-value pairs. " +
"For example, to split on multiple <code>&amp;</code> characters use <code>&amp;+</code>. " +
"Special regular expression characters such as <code>[</code> and <code>]</code> must be escaped with <code>\\\\</code>. " +
"This field cannot be defined along with <code>field_split_characters</code>. " +
"If this option is not defined, the <code>key_value</code> processor will parse the source using <code>field_split_characters</code>.")
@AlsoRequired(values = {
@AlsoRequired.Required(name = VALUE_GROUPING_KEY, allowedValues = {"false"}),
@AlsoRequired.Required(name = FIELD_SPLIT_CHARACTERS_KEY, allowedValues = {"null"})
})
private String fieldDelimiterRegex;

@JsonProperty(value = "value_split_characters", defaultValue = DEFAULT_VALUE_SPLIT_CHARACTERS)
@JsonProperty(value = VALUE_SPLIT_CHARACTERS_KEY, defaultValue = DEFAULT_VALUE_SPLIT_CHARACTERS)
@JsonPropertyDescription("A string of characters specifying the delimiter that separates keys from their values within a key-value pair. " +
"Special regular expression characters such as <code>[</code> and <code>]</code> must be escaped with <code>\\\\</code>. " +
"This field cannot be defined along with <code>key_value_delimiter_regex</code>. " +
"The default value is <code>=</code>.")
@AlsoRequired(values = {
@AlsoRequired.Required(name = KEY_VALUE_DELIMITER_REGEX_KEY, allowedValues = {"null"})
})
private String valueSplitCharacters = DEFAULT_VALUE_SPLIT_CHARACTERS;

@JsonProperty("key_value_delimiter_regex")
@JsonProperty(KEY_VALUE_DELIMITER_REGEX_KEY)
@JsonPropertyDescription("A regular expression specifying the delimiter that separates keys from their values within a key-value pair. " +
"For example, to split on multiple <code>=</code> characters use <code>=+</code>. " +
"Special regular expression characters such as <code>[</code> and <code>]</code> must be escaped with <code>\\\\</code>. " +
"This field cannot be defined along with <code>value_split_characters</code>. " +
"If this option is not defined, the <code>key_value</code> processor will parse the source using <code>value_split_characters</code>.")
@AlsoRequired(values = {
@AlsoRequired.Required(name = VALUE_SPLIT_CHARACTERS_KEY, allowedValues = {"null"})
})
private String keyValueDelimiterRegex;

@JsonProperty(value = "default_values", defaultValue = "{}")
Expand Down Expand Up @@ -118,33 +140,36 @@ public class KeyValueProcessorConfig {
@JsonPropertyDescription("Allows transforming the key's name such as making the name all lowercase.")
private TransformOption transformKey = TransformOption.NONE;

@JsonProperty(value = "whitespace", defaultValue = "lenient")
@JsonProperty(value = WHITESPACE_KEY, 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 <code>lenient</code>.")
@NotNull
private WhitespaceOption whitespace = WhitespaceOption.LENIENT;

@JsonProperty(value = "skip_duplicate_values", defaultValue = "false")
@JsonProperty(value = SKIP_DUPLICATE_VALUES_KEY, defaultValue = "false")
@JsonPropertyDescription("A Boolean option for removing duplicate key-value pairs. When set to <code>true</code>, " +
"only one unique key-value pair will be preserved. Default is <code>false</code>.")
@NotNull
private boolean skipDuplicateValues = false;

@JsonProperty(value = "remove_brackets", defaultValue = "false")
@JsonProperty(value = REMOVE_BRACKETS_KEY, defaultValue = "false")
@JsonPropertyDescription("Specifies whether to treat certain grouping characters as wrapping text that should be removed from values." +
"When set to <code>true</code>, the following grouping characters will be removed: square brackets, angle brackets, and parentheses. " +
"The default configuration is <code>false</code> which retains those grouping characters.")
private boolean removeBrackets;

@JsonProperty(value = "value_grouping", defaultValue = "false")
@JsonProperty(value = VALUE_GROUPING_KEY, defaultValue = "false")
@JsonPropertyDescription("Specifies whether to group values using predefined grouping delimiters. " +
"If this flag is enabled, then the content between the delimiters is considered to be one entity and " +
"they are not parsed as key-value pairs. The following characters are used a group delimiters: " +
"<code>{...}</code>, <code>[...]</code>, <code>&lt;...&gt;</code>, <code>(...)</code>, <code>\"...\"</code>, <code>'...'</code>, <code>http://... (space)</code>, and <code>https:// (space)</code>. " +
"Default is <code>false</code>. For example, if <code>value_grouping</code> is <code>true</code>, then " +
"<code>{\"key1=[a=b,c=d]&amp;key2=value2\"}</code> parses to <code>{\"key1\": \"[a=b,c=d]\", \"key2\": \"value2\"}</code>.")
@AlsoRequired(values = {
@AlsoRequired.Required(name = FIELD_DELIMITER_REGEX_KEY, allowedValues = {"null"})
})
private boolean valueGrouping = false;

@JsonProperty(value = "recursive", defaultValue = "false")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

recursive config has a restriction where remove_brackets must be false, skip_duplicate_values is always true, and whitespace is always strict

Expand All @@ -157,6 +182,11 @@ public class KeyValueProcessorConfig {
"<code>remove_brackets</code> cannot also be <code>true</code>;\n" +
"<code>skip_duplicate_values</code> will always be <code>true</code>;\n" +
"<code>whitespace</code> will always be <code>\"strict\"</code>.")
@AlsoRequired(values = {
@AlsoRequired.Required(name = REMOVE_BRACKETS_KEY, allowedValues = {"false"}),
@AlsoRequired.Required(name = SKIP_DUPLICATE_VALUES_KEY, allowedValues = {"true"}),
@AlsoRequired.Required(name = WHITESPACE_KEY, allowedValues = {"strict"})
})
private boolean recursive = false;

@JsonProperty(value = "overwrite_if_destination_exists", defaultValue = "true")
Expand All @@ -183,6 +213,9 @@ public class KeyValueProcessorConfig {
"Can be set to either a single quotation mark (<code>'</code>) or a double quotation mark (<code>\"</code>). " +
"Default is <code>null</code>.")
@Size(min = 0, max = 1, message = "string_literal_character may only have character")
@AlsoRequired(values = {
@AlsoRequired.Required(name = VALUE_GROUPING_KEY, allowedValues = {"true"})
})
private String stringLiteralCharacter = null;

@JsonProperty("tags_on_failure")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,80 @@
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import org.opensearch.dataprepper.model.annotations.AlsoRequired;

import java.util.List;
import java.util.stream.Stream;

@JsonPropertyOrder
@JsonClassDescription("The <code>add_entries</code> processor adds entries to an event.")
public class AddEntryProcessorConfig {
static final String VALUE_EXPRESSION_KEY = "value_expression";
static final String METADATA_KEY_KEY = "metadata_key";
static final String APPEND_IF_KEY_EXISTS_KEY = "append_if_key_exists";
static final String OVERWRITE_IF_KEY_EXISTS_KEY = "overwrite_if_key_exists";

@JsonPropertyOrder
public static class Entry {
@JsonPropertyDescription("The key of the new entry to be added. Some examples of keys include <code>my_key</code>, " +
"<code>myKey</code>, and <code>object/sub_Key</code>. The key can also be a format expression, for example, <code>${/key1}</code> to " +
"use the value of field <code>key1</code> as the key.")
@AlsoRequired(values = {
@AlsoRequired.Required(name=METADATA_KEY_KEY, allowedValues = {"null"})
})
private String key;

@JsonProperty("metadata_key")
@JsonProperty(METADATA_KEY_KEY)
@JsonPropertyDescription("The key for the new metadata attribute. The argument must be a literal string key " +
"and not a JSON Pointer. Either one of <code>key</code> or <code>metadata_key</code> is required.")
@AlsoRequired(values = {
@AlsoRequired.Required(name="key", allowedValues = {"null"})
})
private String metadataKey;

@JsonPropertyDescription("The value of the new entry to be added, which can be used with any of the " +
"following data types: strings, Booleans, numbers, null, nested objects, and arrays.")
@AlsoRequired(values = {
@AlsoRequired.Required(name="format", allowedValues = {"null"}),
@AlsoRequired.Required(name=VALUE_EXPRESSION_KEY, allowedValues = {"null"})
})
private Object value;

@JsonPropertyDescription("A format string to use as the value of the new entry, for example, " +
"<code>${key1}-${key2}</code>, where <code>key1</code> and <code>key2</code> are existing keys in the event. Required if neither" +
"<code>value</code> nor <code>value_expression</code> is specified.")
@AlsoRequired(values = {
@AlsoRequired.Required(name="value", allowedValues = {"null"}),
@AlsoRequired.Required(name=VALUE_EXPRESSION_KEY, allowedValues = {"null"})
})
private String format;

@JsonProperty("value_expression")
@JsonProperty(VALUE_EXPRESSION_KEY)
@JsonPropertyDescription("An expression string to use as the value of the new entry. For example, <code>/key</code> " +
"is an existing key in the event with a type of either a number, a string, or a Boolean. " +
"Expressions can also contain functions returning number/string/integer. For example, " +
"<code>length(/key)</code> will return the length of the key in the event when the key is a string. For more " +
"information about keys, see <a href=\"https://opensearch.org/docs/latest/data-prepper/pipelines/expression-syntax/\">Expression syntax</a>.")
@AlsoRequired(values = {
@AlsoRequired.Required(name="value", allowedValues = {"null"}),
@AlsoRequired.Required(name="format", allowedValues = {"null"})
})
private String valueExpression;

@JsonProperty("overwrite_if_key_exists")
@JsonProperty(OVERWRITE_IF_KEY_EXISTS_KEY)
@JsonPropertyDescription("When set to <code>true</code>, the existing value is overwritten if <code>key</code> already exists " +
"in the event. The default value is <code>false</code>.")
@AlsoRequired(values = {
@AlsoRequired.Required(name=APPEND_IF_KEY_EXISTS_KEY, allowedValues = {"false"})
})
private boolean overwriteIfKeyExists = false;

@JsonProperty("append_if_key_exists")
@JsonProperty(APPEND_IF_KEY_EXISTS_KEY)
@JsonPropertyDescription("When set to <code>true</code>, the existing value will be appended if a <code>key</code> already " +
"exists in the event. An array will be created if the existing value is not an array. Default is <code>false</code>.")
@AlsoRequired(values = {
@AlsoRequired.Required(name=OVERWRITE_IF_KEY_EXISTS_KEY, allowedValues = {"false"})
})
private boolean appendIfKeyExists = false;

@JsonProperty("add_when")
Expand Down
Loading
Loading