Skip to content

Commit

Permalink
[Security Solution] Fix topN grouping when field type is boolean (ela…
Browse files Browse the repository at this point in the history
…stic#131958) (elastic#132273)

* fix grouping

* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'

* fix grouping

* unit tests

* fix types

* update comment

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
(cherry picked from commit 3f5197a)

Co-authored-by: Angela Chuang <6295984+angorayc@users.noreply.github.com>
  • Loading branch information
kibanamachine and angorayc authored May 16, 2022
1 parent ae54add commit 3165cb4
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export interface EventSource {
}

export interface EventsActionGroupData {
key: number;
key: number | string;
events: {
bucket: EventsMatrixHistogramData[];
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
* 2.0.
*/

import { showInitialLoadingSpinner } from './helpers';
import { formatAlertsData, showInitialLoadingSpinner } from './helpers';
import { result, textResult, stackedByBooleanField, stackedByTextField } from './mock_data';

describe('helpers', () => {
describe('showInitialLoadingSpinner', () => {
Expand Down Expand Up @@ -34,3 +35,15 @@ describe('helpers', () => {
});
});
});

describe('formatAlertsData', () => {
test('stack by a boolean field', () => {
const res = formatAlertsData(stackedByBooleanField);
expect(res).toEqual(result);
});

test('stack by a text field', () => {
const res = formatAlertsData(stackedByTextField);
expect(res).toEqual(textResult);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,22 @@ const EMPTY_ALERTS_DATA: HistogramData[] = [];
export const formatAlertsData = (alertsData: AlertSearchResponse<{}, AlertsAggregation> | null) => {
const groupBuckets: AlertsGroupBucket[] =
alertsData?.aggregations?.alertsByGrouping?.buckets ?? [];
return groupBuckets.reduce<HistogramData[]>((acc, { key: group, alerts }) => {
const alertsBucket: AlertsBucket[] = alerts.buckets ?? [];
return groupBuckets.reduce<HistogramData[]>(
(acc, { key_as_string: keyAsString, key: group, alerts }) => {
const alertsBucket: AlertsBucket[] = alerts.buckets ?? [];

return [
...acc,
// eslint-disable-next-line @typescript-eslint/naming-convention
...alertsBucket.map(({ key, doc_count }: AlertsBucket) => ({
x: key,
y: doc_count,
g: group,
})),
];
}, EMPTY_ALERTS_DATA);
return [
...acc,
// eslint-disable-next-line @typescript-eslint/naming-convention
...alertsBucket.map(({ key, doc_count }: AlertsBucket) => ({
x: key,
y: doc_count,
g: keyAsString ?? group.toString(),
})),
];
},
EMPTY_ALERTS_DATA
);
};

export const getAlertsHistogramQuery = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ export const AlertsHistogramPanel = memo<AlertsHistogramPanelProps>(
),
field: selectedStackByOption,
timelineId,
value: bucket.key,
value: bucket?.key_as_string ?? bucket.key,
}))
: NO_LEGEND_DATA,
[
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* 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.
*/
export const stackedByBooleanField = {
took: 1,
timed_out: false,
_shards: { total: 1, successful: 1, skipped: 0, failed: 0 },
hits: {
total: {
value: 3,
relation: 'eq',
},
hits: [],
},
timeout: false,
aggregations: {
alertsByGrouping: {
doc_count_error_upper_bound: 0,
sum_other_doc_count: 0,
buckets: [
{
key: 1,
key_as_string: 'true',
doc_count: 2683,
alerts: {
buckets: [
{ key_as_string: '2022-05-10T15:34:48.075Z', key: 1652196888075, doc_count: 0 },
{ key_as_string: '2022-05-10T16:19:48.074Z', key: 1652199588074, doc_count: 0 },
{ key_as_string: '2022-05-10T17:04:48.073Z', key: 1652202288073, doc_count: 0 },
],
},
},
],
},
},
};

export const result = [
{ x: 1652196888075, y: 0, g: 'true' },
{ x: 1652199588074, y: 0, g: 'true' },
{ x: 1652202288073, y: 0, g: 'true' },
];

export const stackedByTextField = {
took: 1,
timeout: false,
_shards: { total: 1, successful: 1, skipped: 0, failed: 0 },
hits: {
total: {
value: 3,
relation: 'eq',
},
hits: [],
},
aggregations: {
alertsByGrouping: {
doc_count_error_upper_bound: 0,
sum_other_doc_count: 0,
buckets: [
{
key: 'MacBook-Pro.local',
doc_count: 2706,
alerts: {
buckets: [
{ key_as_string: '2022-05-10T15:34:48.075Z', key: 1652196888075, doc_count: 0 },
{ key_as_string: '2022-05-10T16:19:48.074Z', key: 1652199588074, doc_count: 0 },
{ key_as_string: '2022-05-10T17:04:48.073Z', key: 1652202288073, doc_count: 0 },
],
},
},
],
},
},
};

export const textResult = [
{ x: 1652196888075, y: 0, g: 'MacBook-Pro.local' },
{ x: 1652199588074, y: 0, g: 'MacBook-Pro.local' },
{ x: 1652202288073, y: 0, g: 'MacBook-Pro.local' },
];
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ export interface AlertsBucket {
}

export interface AlertsGroupBucket {
key: string;
key: string | number;
key_as_string?: string;
alerts: {
buckets: AlertsBucket[];
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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 { MatrixHistogramType } from '../../../../../common/search_strategy';
import { getGenericData } from './helpers';
import { stackedByBooleanField, stackedByTextField, result, textResult } from './mock_data';

describe('getGenericData', () => {
test('stack by a boolean field', () => {
const res = getGenericData<MatrixHistogramType.events>(stackedByBooleanField, 'events.bucket');
expect(res).toEqual(result);
});

test('stack by a text field', () => {
const res = getGenericData<MatrixHistogramType.events>(stackedByTextField, 'events.bucket');
expect(res).toEqual(textResult);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export const getGenericData = <T>(
): MatrixHistogramData[] => {
let result: MatrixHistogramData[] = [];
data.forEach((bucketData: unknown) => {
const group = get('key', bucketData);
// if key_as_string is present use it, else default to the existing key
const group = get('key_as_string', bucketData) ?? get('key', bucketData);
const histData = getOr([], keyBucket, bucketData).map(
// eslint-disable-next-line @typescript-eslint/naming-convention
({ key, doc_count }: MatrixHistogramBucket) => ({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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.
*/

export const stackedByBooleanField = [
{
key: 1,
key_as_string: 'true',
doc_count: 7125,
events: {
bucket: [
{ key_as_string: '2022-05-10T15:34:48.075Z', key: 1652196888075, doc_count: 0 },
{ key_as_string: '2022-05-10T16:19:48.074Z', key: 1652199588074, doc_count: 774 },
{ key_as_string: '2022-05-10T17:04:48.073Z', key: 1652202288073, doc_count: 415 },
],
},
},
];
export const result = [
{ x: 1652196888075, y: 0, g: 'true' },
{ x: 1652199588074, y: 774, g: 'true' },
{ x: 1652202288073, y: 415, g: 'true' },
];

export const stackedByTextField = [
{
key: 'MacBook-Pro.local',
doc_count: 7103,
events: {
bucket: [
{ key_as_string: '2022-05-10T15:34:48.075Z', key: 1652196888075, doc_count: 0 },
{ key_as_string: '2022-05-10T16:19:48.074Z', key: 1652199588074, doc_count: 774 },
{ key_as_string: '2022-05-10T17:04:48.073Z', key: 1652202288073, doc_count: 415 },
],
},
},
];

export const textResult = [
{ x: 1652196888075, y: 0, g: 'MacBook-Pro.local' },
{ x: 1652199588074, y: 774, g: 'MacBook-Pro.local' },
{ x: 1652202288073, y: 415, g: 'MacBook-Pro.local' },
];

0 comments on commit 3165cb4

Please sign in to comment.