Skip to content

Add support for parent event field access during iterate_on processing in add_entries processor#6713

Open
yavmanis wants to merge 3 commits intoopensearch-project:mainfrom
yavmanis:add_entries_enhancements
Open

Add support for parent event field access during iterate_on processing in add_entries processor#6713
yavmanis wants to merge 3 commits intoopensearch-project:mainfrom
yavmanis:add_entries_enhancements

Conversation

@yavmanis
Copy link
Copy Markdown

@yavmanis yavmanis commented Apr 2, 2026

Description

This PR addresses two limitations in the add_entries processor when using iterate_on:

Problem 1: No root-level field access during array iteration
When iterate_on is configured, value_expression and format resolve against the individual array element context. There is no way to reference root-level fields from the event, so expressions like /alert_title return null if alert_title exists only at the root.

Problem 2: add_to_element_when evaluates against root event
The add_to_element_when condition is evaluated against the root event, not the individual array element. This makes per-element conditional logic impossible — e.g., you cannot add a key only to elements where severity == "critical".

Solution

Fix 1: disable_root_keys (default: true)
When set to false with iterate_on, resolves value_expression and format against the root event instead of the array element. This allows injecting root-level fields into each element during iteration.

Fix 2: evaluate_when_on_element (default: false)
When set to true with iterate_on and add_to_element_when, evaluates the add_to_element_when condition against each individual array element instead of the root event.

Example

Input:

{
  "alert_title": "SQL Injection Detected",
  "vulns": [
    {"cve": "CVE-2024-001", "severity": "critical"},
    {"cve": "CVE-2024-002", "severity": "low"},
    {"cve": "CVE-2024-003", "severity": "critical"}
  ]
}

Config:

processor:
  - add_entries:
      entries:
        - key: "title"
          value_expression: "/alert_title"
          iterate_on: "vulns"
          disable_root_keys: false
          add_to_element_when: '/severity == "critical"'
          evaluate_when_on_element: true

Output:

{
  "alert_title": "SQL Injection Detected",
  "vulns": [
    {"cve": "CVE-2024-001", "severity": "critical", "title": "SQL Injection Detected"},
    {"cve": "CVE-2024-002", "severity": "low"},
    {"cve": "CVE-2024-003", "severity": "critical", "title": "SQL Injection Detected"}
  ]
}

Backward Compatibility

Both flags default to values that preserve existing behavior. No existing constructors, tests, or functionality are modified.
Default values for the flags:

disable_root_keys: true
evaluate_when_on_element: false

Issues Resolved

Resolves #6609

Check List

  • New functionality includes testing
  • New functionality has been documented
  • Commits are signed per the DCO using --signoff

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

…ries processor

Signed-off-by: Manisha Yadav <yavmanis@amazon.com>
@yavmanis yavmanis force-pushed the add_entries_enhancements branch from 1390a5d to 0ba2de5 Compare April 2, 2026 14:37
return !evaluateWhenOnElement || (iterateOn != null && addToElementWhen != null);
}

public Entry(final String key,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

issue (non-blocking): Massive constructor duplication

  • Problem: The new 13-parameter constructor duplicates all the validation logic from the existing 11-parameter constructor. There are now four constructors in Entry, three of which contain nearly identical validation blocks (null checks, mutualexclusion checks, etc.).
  • Impact: Any future validation change must be replicated across all constructors. This is a maintenance burden.
  • Fix: Have the shorter constructors delegate to the longest one with default values for the new parameters:
public Entry(String key, String metadataKey, Object value, String format,
                 String valueExpression, boolean overwriteIfKeyExists, boolean appendIfKeyExists,
                 String addWhen, String iterateOn, boolean flattenKey, String addToElementWhen) {
        this(key, metadataKey, value, format, valueExpression, overwriteIfKeyExists,
             appendIfKeyExists, addWhen, iterateOn, flattenKey, true, false, addToElementWhen);
    }

This eliminates all duplicated validation.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Removed the duplication in the constructor as suggested.

@AlsoRequired(values = {
@AlsoRequired.Required(name="iterate_on")
})
private boolean disableRootKeys = true;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion: Confusing double-negative naming for disable_root_keys

  • Problem: To enable root-level field access, users must set disable_root_keys: false. The double-negative (!disableRootKeys in the processor code) is hard to reason about. The issue discussion originally proposed use_root_context: true which reads more
    naturally.
  • Impact: User confusion in configuration. However, @dlvenable explicitly requested this name in this comment ([FEATURE] Support parent event field access during iterate_on processing #6609 (comment)), so this is intentional.
  • Fix: No change needed — this follows the maintainer's direction. Noting for awareness only.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Noted!!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I would suggest using a positive field name as well, like resolve_from_root, use_root_context, etc. so that: 1) the default value would be false; 2) it's easier for users to comprehend and use

Signed-off-by: Manisha Yadav <yavmanis@amazon.com>
@yavmanis yavmanis requested a review from bagmarnikhil April 7, 2026 09:10
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 9, 2026

✅ License Header Check Passed

All newly added files have proper license headers. Great work! 🎉

Signed-off-by: Manisha Yadav <yavmanis@amazon.com>
@yavmanis
Copy link
Copy Markdown
Author

⚠️ License Header Violations Found

The following newly added files are missing required license headers:

  • data-prepper-plugins/mutate-event-processors/src/test/resources/org/opensearch/dataprepper/plugins/processor/mutateevent/iterate_on_with_both_flags.yaml
  • data-prepper-plugins/mutate-event-processors/src/test/resources/org/opensearch/dataprepper/plugins/processor/mutateevent/iterate_on_with_disable_root_keys.yaml
  • data-prepper-plugins/mutate-event-processors/src/test/resources/org/opensearch/dataprepper/plugins/processor/mutateevent/iterate_on_with_evaluate_when_on_element.yaml

Please add the appropriate license header to each file and push your changes.

See the license header requirements: https://github.com/opensearch-project/data-prepper/blob/main/CONTRIBUTING.md#license-headers

Fixed License header violations by adding the headers in the yaml files

@yavmanis
Copy link
Copy Markdown
Author

As per the discussion with the David during the call, he will revisit the issue details for the add_entries processor enhancement and analyze Problem 2 and its corresponding Fix 2. He will then advise on how he would like to proceed with this enhancement, after which we will move forward with the PR.

cc: @bagmarnikhil @nishantKadivar

@AlsoRequired(values = {
@AlsoRequired.Required(name="iterate_on")
})
private boolean disableRootKeys = true;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I would suggest using a positive field name as well, like resolve_from_root, use_root_context, etc. so that: 1) the default value would be false; 2) it's easier for users to comprehend and use

import org.opensearch.dataprepper.test.plugins.PluginConfigurationFile;
import org.opensearch.dataprepper.test.plugins.junit.BaseDataPrepperPluginStandardTestSuite;

import java.util.*;
Copy link
Copy Markdown
Collaborator

@oeyh oeyh Apr 15, 2026

Choose a reason for hiding this comment

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

Star import may result in checkstyle failures. I triggered the checks, please check that gradle builds are OK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Support parent event field access during iterate_on processing

3 participants