-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Custom threshold] Fix using data view runtime fields during rule exe…
…cution for the custom threshold rule (#209133) Fixes #200772 ## 🐉 Summary This PR fixes supporting data view runtime fields during rule execution for the custom threshold rule. ## 🧪 How to test 1. Create a runtime field as shown below: |Runtime field| Preview| |---|---| ||| 2. Make sure alerts are generated as expected both for regular and no-data alerts:  ### TODO - [x] Add an API integration test - [x] Test on MKI (cherry picked from commit 8fe5738) # Conflicts: # x-pack/plugins/observability_solution/observability/server/lib/rules/custom_threshold/lib/is_populated_object.test.ts # x-pack/plugins/observability_solution/observability/server/lib/rules/custom_threshold/lib/is_populated_object.ts
- Loading branch information
1 parent
9a0bab9
commit 77d14e7
Showing
12 changed files
with
409 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
..._solution/observability/server/lib/rules/custom_threshold/lib/is_populated_object.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { isPopulatedObject } from './is_populated_object'; | ||
|
||
describe('isPopulatedObject', () => { | ||
it('does not allow numbers', () => { | ||
expect(isPopulatedObject(0)).toBe(false); | ||
}); | ||
it('does not allow strings', () => { | ||
expect(isPopulatedObject('')).toBe(false); | ||
}); | ||
it('does not allow null', () => { | ||
expect(isPopulatedObject(null)).toBe(false); | ||
}); | ||
it('does not allow an empty object', () => { | ||
expect(isPopulatedObject({})).toBe(false); | ||
}); | ||
it('allows an object with an attribute', () => { | ||
expect(isPopulatedObject({ attribute: 'value' })).toBe(true); | ||
}); | ||
it('does not allow an object with a non-existing required attribute', () => { | ||
expect(isPopulatedObject({ attribute: 'value' }, ['otherAttribute'])).toBe(false); | ||
}); | ||
it('allows an object with an existing required attribute', () => { | ||
expect(isPopulatedObject({ attribute: 'value' }, ['attribute'])).toBe(true); | ||
}); | ||
it('allows an object with two existing required attributes', () => { | ||
expect( | ||
isPopulatedObject({ attribute1: 'value1', attribute2: 'value2' }, [ | ||
'attribute1', | ||
'attribute2', | ||
]) | ||
).toBe(true); | ||
}); | ||
it('does not allow an object with two required attributes where one does not exist', () => { | ||
expect( | ||
isPopulatedObject({ attribute1: 'value1', attribute2: 'value2' }, [ | ||
'attribute1', | ||
'otherAttribute', | ||
]) | ||
).toBe(false); | ||
}); | ||
it('does not allow an object with a required attribute in the prototype ', () => { | ||
const testObject = { attribute: 'value', __proto__: { otherAttribute: 'value' } }; | ||
expect(isPopulatedObject(testObject, ['otherAttribute'])).toBe(false); | ||
}); | ||
}); |
35 changes: 35 additions & 0 deletions
35
...ility_solution/observability/server/lib/rules/custom_threshold/lib/is_populated_object.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
/** | ||
* A type guard to check record like object structures. | ||
* | ||
* Examples: | ||
* - `isPopulatedObject({...})` | ||
* Limits type to Record<string, unknown> | ||
* | ||
* - `isPopulatedObject({...}, ['attribute'])` | ||
* Limits type to Record<'attribute', unknown> | ||
* | ||
* - `isPopulatedObject<keyof MyInterface>({...})` | ||
* Limits type to a record with keys of the given interface. | ||
* Note that you might want to add keys from the interface to the | ||
* array of requiredAttributes to satisfy runtime requirements. | ||
* Otherwise you'd just satisfy TS requirements but might still | ||
* run into runtime issues. | ||
*/ | ||
export const isPopulatedObject = <U extends string = string, T extends unknown = unknown>( | ||
arg: unknown, | ||
requiredAttributes: U[] = [] | ||
): arg is Record<U, T> => { | ||
return ( | ||
typeof arg === 'object' && | ||
arg !== null && | ||
Object.keys(arg).length > 0 && | ||
(requiredAttributes.length === 0 || requiredAttributes.every((d) => Object.hasOwn(arg, d))) | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.