Bucket level multi-tenant trigger#2098
Conversation
6f13e7d to
d82f8ad
Compare
| * Extracts include/exclude regex patterns from [IncludeExclude]. | ||
| * Uses reflection to access private fields since no public API exposes the raw patterns. | ||
| */ | ||
| private fun extractPatterns(includeExclude: IncludeExclude): Pair<Pattern?, Pattern?> { |
There was a problem hiding this comment.
Reflection is an anti-pattern and won't be supported in some environments. Is there a way to take a dependency on the IncludeExclude object or recreate it in a way that we can access the fields without reflection?
There was a problem hiding this comment.
changed to parse the json
| } | ||
| } | ||
| if (found == null) { | ||
| throw IllegalArgumentException("ParentBucketPath: $parentBucketPath not found in query aggregations") |
There was a problem hiding this comment.
Throwing the exception here would only allow one iteration of the for loop right? I'm wondering if that's the intended behavior or if we are looking for the parentAgg in any of the available pathElements
There was a problem hiding this comment.
There are two nested loops:
- Outer loop: iterates over pathElements (e.g., for agg1>agg2, it walks agg1 then agg2)
- Inner loop: searches the current level's agg builders for the matching name
The throw is inside the outer loop but outside the inner loop. If agg1 is found, the outer loop continues to look for agg2 inside agg1's sub-aggregations. The exception only fires if a path element isn't found at its expected level — which is correct behavior imo.
| * since the field is private with no public getter in the commons library. | ||
| */ | ||
| @Suppress("UNCHECKED_CAST") | ||
| private fun extractBucketsPathsMap(selector: BucketSelectorExtAggregationBuilder): Map<String, String> { |
There was a problem hiding this comment.
Same comment on reflection
| } | ||
| } | ||
|
|
||
| private fun isIndexNotFoundException(e: Throwable): Boolean { |
There was a problem hiding this comment.
Was this from another PR? It looks familiar and doesn't appear to be used anywhere
…ard bucket_selector Replace the custom BucketSelectorExt aggregation with standard bucket_selector for bucket-level trigger evaluation when multi_tenant_trigger_eval_enabled is true. This enables trigger evaluation on user clusters that do not have the alerting plugin installed. When the flag is on, bucket-level monitors are limited to 1 trigger. The standard bucket_selector is injected directly into the monitor's search query so a single search call performs both data collection and trigger evaluation. Include/exclude filtering from BucketSelectorExtFilter is replicated post-response by BucketKeyFilter. The existing BucketSelectorExt path is completely unchanged when the flag is off (the default). New files: - BucketSelectorQueryBuilder: injects standard bucket_selector sub-agg - BucketKeyFilter: post-response include/exclude bucket filtering - TriggerService.runBucketLevelTriggerFromFilteredResponse(): reads remaining buckets from filtered response Modified files: - BucketLevelMonitorRunner: flag-gated single-query path - InputService: useStandardBucketSelector parameter - TransportIndexMonitorAction: 1-trigger validation for bucket-level monitors when flag is on - AggregationQueryRewriter: skipBucketSelectorInjection parameter Integration tests: - RemoteBucketLevelTriggerIT: 13 tests covering composite/terms agg, alert lifecycle, dry run, nested parent path, include/exclude filter, validation of 1-trigger limit, Painless script in query - RemoteBucketLevelTriggerRegressionIT: 5 tests verifying flag=false preserves existing BucketSelectorExt behavior Signed-off-by: Surya Sashank Nistala <snistala@amazon.com>
- Remove collectInputResultsForTrigger() from InputService (dead code from per-trigger query approach) - Remove skipAllBucketSelectorInjection parameter from collectInputResults and getSearchRequest (no longer used) - Collapse identical triggerCtx if/else branches in BucketLevelMonitorRunner - Restore .gitignore to original state Signed-off-by: Surya Sashank Nistala <snistala@amazon.com>
…dation - BucketSelectorQueryBuilder: use public bucketsPathsMap getter from common-utils instead of reflection (opensearch-project/common-utils#949) - BucketKeyFilter: use IncludeExclude.convertToStringFilter() instead of reflection on private fields - TriggerService: replace blanket @Suppress(UNCHECKED_CAST) with runtime type checks using require() - BucketLevelMonitorRunner: add 1-trigger validation at execution time to cover the _execute API path (in addition to create/update validation) Signed-off-by: Surya Sashank Nistala <snistala@amazon.com>
d82f8ad to
31f8028
Compare
Replace the custom BucketSelectorExt aggregation with standard
bucket_selector for bucket-level trigger evaluation when
multi_tenant_trigger_eval_enabled is true. This enables trigger
evaluation on user clusters that do not have the alerting plugin
installed.
When the flag is on, bucket-level monitors are limited to 1 trigger.
The standard bucket_selector is injected directly into the monitor's
search query so a single search call performs both data collection and
trigger evaluation. Include/exclude filtering from BucketSelectorExtFilter
is replicated post-response by BucketKeyFilter.
The existing BucketSelectorExt path is completely unchanged when the
flag is off (the default).