Skip to content

fix(eventbridge): boolean/numeric pattern values are matched correctly#1889

Open
usmanzaheer1995 wants to merge 3 commits into
floci-io:mainfrom
usmanzaheer1995:feat/eventbridge-boolean-numeric-pattern-matching-for-string-values
Open

fix(eventbridge): boolean/numeric pattern values are matched correctly#1889
usmanzaheer1995 wants to merge 3 commits into
floci-io:mainfrom
usmanzaheer1995:feat/eventbridge-boolean-numeric-pattern-matching-for-string-values

Conversation

@usmanzaheer1995

@usmanzaheer1995 usmanzaheer1995 commented Jul 16, 2026

Copy link
Copy Markdown

Summary

Fixes #1888

Problem

EventBridge pattern matching inverted AWS's type semantics for boolean and numeric values in detail:

  • {"detail": {"enabled": ["true"]}} (string pattern) wrongly matched the JSON boolean true
  • {"detail": {"enabled": [true]}} (boolean pattern) could never match anything
  • Same for numbers: ["5"] matched the number 5, while [5] matched nothing

Two defects in EventBridgeService:

  1. matchesDetailNode collapsed the event's detail value to a String via asText() before comparison, destroying type information so "true".equals("true") succeeded for the string pattern.
  2. matchesSingleElement had no isBoolean()/isNumber() branches, so non-textual pattern literals fell through to return false.

Fix

  • The detail-matching pipeline now passes the actual JsonNode end-to-end (matchesArrayField(JsonNode pattern, JsonNode actual)); envelope fields (source, detail-type, account, region, resources), which are inherently strings, delegate through a thin TextNode-wrapping overload.
  • Exact matching is type-aware via a new matchesExactValue: strings match strings, booleans match booleans by value, numbers match numbers by normalized numeric value (verified against real AWS: [3.0e2] matches 300.0).
  • String operators (prefix, suffix, equals-ignore-case) now only apply when the event value is actually a string, matching AWS behavior.
  • exists checks key presence regardless of value type; a key carrying the JSON literal null counts as present (exists: true matches it, exists: false does not). The pre-existing code treated null-valued keys as absent (NullNode.asText(defaultValue) returns the default, so the old stringified value was Java null).
  • The [null] literal pattern requires the key to be present with a null value; a missing key does not match (verified against real AWS).
  • anything-but reuses matchesExactValue, which also fixes a latent bug: numeric anything-but: [5] previously excluded nothing because only textual elements were checked.

Both TestEventPattern and real rule dispatch funnel through the same matchesDetailNode, so one fix covers both paths.

Type of change

  • Bug fix (fix:)
  • New feature (feat:)
  • Breaking change (feat!: or fix!:)
  • Docs / chore

Checklist

  • ./mvnw test passes locally
  • New or updated integration test added
  • Commit messages follow Conventional Commits

Copilot AI review requested due to automatic review settings July 16, 2026 14:15

Copilot AI left a comment

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.

Pull request overview

Fixes EventBridge event-pattern matching for detail fields so exact matches are type-aware (booleans and numbers no longer compare against stringified event values), aligning Floci behavior with AWS semantics and the AWS CLI TestEventPattern behavior.

Changes:

  • Update EventBridgeService detail matching to carry JsonNode values end-to-end and apply type-aware exact matching for strings/booleans/numbers.
  • Restrict string-only operators (prefix, suffix, equals-ignore-case) to apply only when the event value is actually a JSON string.
  • Add integration tests covering boolean/numeric literal matching, string-vs-primitive mismatches, numeric string-representation equality, exists, and anything-but behavior for numbers.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/main/java/io/github/hectorvent/floci/services/eventbridge/EventBridgeService.java Makes detail pattern matching type-aware by comparing JsonNode values (fixing boolean/numeric semantics and improving anything-but).
src/test/java/io/github/hectorvent/floci/services/eventbridge/EventBridgeTestEventPatternIntegrationTest.java Adds integration tests validating AWS-compatible matching for boolean/numeric detail values and related operators.

@greptile-apps

greptile-apps Bot commented Jul 16, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes type-aware pattern matching in the EventBridge emulation layer: the detail matching pipeline now propagates the full JsonNode instead of collapsing every value to a string via asText(), and a new matchesExactValue helper enforces strict type checks for string, boolean, number, and null literals. The anything-but filter is also fixed to use the same type-aware comparison, and the exists check correctly treats a field carrying JSON null as present.

  • matchesArrayField gains a JsonNode overload used by the detail path; envelope fields (source, detail-type, account, region, resources) still flow through the String overload, which wraps via TextNode.valueOf to keep the same code path.
  • matchesSingleElement now delegates non-object pattern elements to matchesExactValue, enabling boolean and numeric literal patterns to match for the first time.
  • Twenty new integration tests cover all the corrected cases including NullNode exists semantics and numeric equality via BigDecimal.compareTo.

Confidence Score: 5/5

Safe to merge — the change is a self-contained bug fix to the EventBridge pattern-matching pipeline with comprehensive integration-test coverage for all affected code paths.

The refactored matchesDetailNode → matchesArrayField → matchesSingleElement → matchesExactValue chain is internally consistent, the envelope-field String overload is correctly preserved, and the exists/anything-but/null-literal edge cases are all exercised by the new tests. The only discrepancy found is a stale sentence in the PR description about numeric equality that was not updated when the implementation was corrected.

No files require special attention.

Important Files Changed

Filename Overview
src/main/java/io/github/hectorvent/floci/services/eventbridge/EventBridgeService.java Core fix: passes JsonNode end-to-end through matchesDetailNode/matchesArrayField/matchesSingleElement; adds type-aware matchesExactValue for string/boolean/number/null; fixes anything-but to use matchesExactValue; exists correctly treats NullNode as present. Logic is sound.
src/test/java/io/github/hectorvent/floci/services/eventbridge/EventBridgeTestEventPatternIntegrationTest.java Adds 20 integration tests covering boolean literal match/mismatch, numeric literal match/mismatch, type cross-contamination, exists with null/missing fields, null literal matching, anything-but with numbers, and scientific-notation equality. Coverage is thorough.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[matchesDetailNode] -->|envelope: source/detail-type/account/region| B[matchesArrayField - String overload]
    B --> C[TextNode.valueOf wrap]
    C --> D[matchesArrayField - JsonNode overload]
    A -->|detail field| D
    D --> E{for each pattern element}
    E --> F[matchesSingleElement]
    F -->|element.isObject| G{filter type}
    G -->|prefix/suffix/equals-ignore-case| H[value != null and string op - text only]
    G -->|anything-but array| I[matchesExactValue each exclusion]
    G -->|anything-but prefix| J[string prefix check]
    G -->|exists| K[present = actual != null - NullNode = present]
    F -->|literal element| L[matchesExactValue]
    L -->|null| M[actual.isNull]
    L -->|string| N[actual.isTextual and equals]
    L -->|boolean| O[actual.isBoolean and value equals]
    L -->|number| P[actual.isNumber and decimalValue compareTo == 0]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[matchesDetailNode] -->|envelope: source/detail-type/account/region| B[matchesArrayField - String overload]
    B --> C[TextNode.valueOf wrap]
    C --> D[matchesArrayField - JsonNode overload]
    A -->|detail field| D
    D --> E{for each pattern element}
    E --> F[matchesSingleElement]
    F -->|element.isObject| G{filter type}
    G -->|prefix/suffix/equals-ignore-case| H[value != null and string op - text only]
    G -->|anything-but array| I[matchesExactValue each exclusion]
    G -->|anything-but prefix| J[string prefix check]
    G -->|exists| K[present = actual != null - NullNode = present]
    F -->|literal element| L[matchesExactValue]
    L -->|null| M[actual.isNull]
    L -->|string| N[actual.isTextual and equals]
    L -->|boolean| O[actual.isBoolean and value equals]
    L -->|number| P[actual.isNumber and decimalValue compareTo == 0]
Loading

Reviews (3): Last reviewed commit: "fix(eventbridge): make null checks tight..." | Re-trigger Greptile

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@hectorvent hectorvent added bug Something isn't working eventbridge Amazon EventBridge labels Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working eventbridge Amazon EventBridge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] EventBridge: boolean/numeric pattern values are matched against stringified event values (inverted from AWS)

3 participants