Skip to content

Commit 14ebd03

Browse files
update create detector page and detector detail page to add custom result index lifecycle management settings (#770) (#771)
* add custom result index lifecycle management conditions Signed-off-by: Jackie Han <jkhanjob@gmail.com> * update create detector page and detector detail page to add custom result index lifecycle management settings Signed-off-by: Jackie Han <jkhanjob@gmail.com> * code formatting update Signed-off-by: Jackie Han <jkhanjob@gmail.com> * add more tests Signed-off-by: Jackie Han <jkhanjob@gmail.com> --------- Signed-off-by: Jackie Han <jkhanjob@gmail.com> (cherry picked from commit 1080d60) Co-authored-by: Jackie Han <jkhanjob@gmail.com>
1 parent 0611bf9 commit 14ebd03

File tree

14 files changed

+792
-4
lines changed

14 files changed

+792
-4
lines changed

public/models/interfaces.ts

+3
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ export type Detector = {
187187
timeField: string;
188188
indices: string[];
189189
resultIndex?: string;
190+
resultIndexMinAge?: number;
191+
resultIndexMinSize?: number;
192+
resultIndexTtl?: number;
190193
filterQuery: { [key: string]: any };
191194
featureAttributes: FeatureAttributes[];
192195
windowDelay: { period: Schedule };

public/pages/DefineDetector/components/CustomResultIndex/CustomResultIndex.tsx

+119-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
EuiFormRow,
2222
EuiCheckbox,
2323
EuiIcon,
24+
EuiFieldNumber,
2425
} from '@elastic/eui';
2526
import { Field, FieldProps } from 'formik';
2627
import React, { useState } from 'react';
@@ -31,7 +32,9 @@ import {
3132
isInvalid,
3233
getError,
3334
validateCustomResultIndex,
35+
validatePositiveInteger,
3436
} from '../../../../utils/utils';
37+
import { FormattedFormRow } from '../../../../components/FormattedFormRow/FormattedFormRow';
3538

3639
interface CustomResultIndexProps {
3740
isEdit: boolean;
@@ -86,7 +89,7 @@ function CustomResultIndex(props: CustomResultIndexProps) {
8689
<EuiFlexItem>
8790
<EuiCallOut
8891
data-test-subj="cannotEditResultIndexCallout"
89-
title="You can't change the custom result index after you create the detector. You can manage the result index with the Index Management plugin."
92+
title="You can't change the custom result index after creating the detector. You can manage the result index using the following three settings inside Anomaly Detection plugin or with the Index Management plugin."
9093
color="warning"
9194
iconType="alert"
9295
size="s"
@@ -115,6 +118,121 @@ function CustomResultIndex(props: CustomResultIndexProps) {
115118
</EuiFlexGroup>
116119
)}
117120
</Field>
121+
122+
{enabled ? (<Field
123+
name="resultIndexMinAge"
124+
validate={enabled ? validatePositiveInteger : null}
125+
>
126+
{({ field, form }: FieldProps) => (
127+
<EuiFlexGroup>
128+
<EuiFlexItem style={{ maxWidth: '70%' }}>
129+
<FormattedFormRow
130+
fullWidth
131+
title="Max Index Age"
132+
hint={[
133+
`This setting would define a specific threshold for the age of an index. When this threshold is surpassed, a rollover will be triggered automatically.`,
134+
]}
135+
isInvalid={isInvalid(field.name, form)}
136+
error={getError(field.name, form)}
137+
>
138+
<EuiFlexGroup gutterSize="s" alignItems="center">
139+
<EuiFlexItem grow={false}>
140+
<EuiFieldNumber
141+
name="resultIndexMinAge"
142+
id="resultIndexMinAge"
143+
data-test-subj="resultIndexMinAge"
144+
min={1}
145+
{...field}
146+
/>
147+
</EuiFlexItem>
148+
<EuiFlexItem>
149+
<EuiText>
150+
<p className="minutes">days</p>
151+
</EuiText>
152+
</EuiFlexItem>
153+
</EuiFlexGroup>
154+
</FormattedFormRow>
155+
</EuiFlexItem>
156+
</EuiFlexGroup>
157+
)}
158+
</Field>) : null}
159+
160+
{enabled ? (<Field
161+
name="resultIndexMinSize"
162+
validate={enabled ? validatePositiveInteger : null}
163+
>
164+
{({ field, form }: FieldProps) => (
165+
<EuiFlexGroup>
166+
<EuiFlexItem style={{ maxWidth: '70%' }}>
167+
<FormattedFormRow
168+
fullWidth
169+
title="Max Index Size"
170+
hint={[
171+
`This setting would define a specific threshold for the size of an index. When this threshold is surpassed, a rollover will be triggered automatically.`,
172+
]}
173+
isInvalid={isInvalid(field.name, form)}
174+
error={getError(field.name, form)}
175+
>
176+
<EuiFlexGroup gutterSize="s" alignItems="center">
177+
<EuiFlexItem grow={false}>
178+
<EuiFieldNumber
179+
name="resultIndexMinSize"
180+
id="resultIndexMinSize"
181+
placeholder="Max index size"
182+
data-test-subj="resultIndexMinSize"
183+
min={1000}
184+
{...field}
185+
/>
186+
</EuiFlexItem>
187+
<EuiFlexItem>
188+
<EuiText>
189+
<p className="minutes">MB</p>
190+
</EuiText>
191+
</EuiFlexItem>
192+
</EuiFlexGroup>
193+
</FormattedFormRow>
194+
</EuiFlexItem>
195+
</EuiFlexGroup>
196+
)}
197+
</Field>) : null}
198+
199+
{enabled ? (<Field
200+
name="resultIndexTtl"
201+
validate={enabled ? validatePositiveInteger : null}
202+
>
203+
{({ field, form }: FieldProps) => (
204+
<EuiFlexGroup>
205+
<EuiFlexItem style={{ maxWidth: '70%' }}>
206+
<FormattedFormRow
207+
fullWidth
208+
title="Index TTL"
209+
hint={[
210+
`This setting would define the duration after which an index is considered expired and eligible for deletion.`,
211+
]}
212+
isInvalid={isInvalid(field.name, form)}
213+
error={getError(field.name, form)}
214+
>
215+
<EuiFlexGroup gutterSize="s" alignItems="center">
216+
<EuiFlexItem grow={false}>
217+
<EuiFieldNumber
218+
name="resultIndexTtl"
219+
id="resultIndexTtl"
220+
data-test-subj="resultIndexTtl"
221+
min={1}
222+
{...field}
223+
/>
224+
</EuiFlexItem>
225+
<EuiFlexItem>
226+
<EuiText>
227+
<p className="minutes">days</p>
228+
</EuiText>
229+
</EuiFlexItem>
230+
</EuiFlexGroup>
231+
</FormattedFormRow>
232+
</EuiFlexItem>
233+
</EuiFlexGroup>
234+
)}
235+
</Field>) : null}
118236
</ContentPanel>
119237
);
120238
}

public/pages/DefineDetector/containers/DefineDetector.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ export const DefineDetector = (props: DefineDetectorProps) => {
225225
formikProps.setFieldTouched('timeField');
226226
formikProps.setFieldTouched('interval');
227227
formikProps.setFieldTouched('windowDelay');
228+
formikProps.setFieldTouched('resultIndexMinAge');
229+
formikProps.setFieldTouched('resultIndexMinSize');
230+
formikProps.setFieldTouched('resultIndexTtl');
228231
formikProps.validateForm().then((errors) => {
229232
if (isEmpty(errors)) {
230233
if (props.isEdit) {

public/pages/DefineDetector/models/interfaces.ts

+3
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,7 @@ export interface DetectorDefinitionFormikValues {
2222
timeField: string;
2323
interval: number;
2424
windowDelay: number;
25+
resultIndexMinAge?: number;
26+
resultIndexMinSize?: number;
27+
resultIndexTtl?:number;
2528
}

public/pages/DefineDetector/utils/__tests__/helpers.test.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ describe('detectorDefinitionToFormik', () => {
4040
timeField: randomDetector.timeField,
4141
interval: randomDetector.detectionInterval.period.interval,
4242
windowDelay: randomDetector.windowDelay.period.interval,
43+
resultIndex: randomDetector.resultIndex,
44+
resultIndexMinAge: randomDetector.resultIndexMinAge,
45+
resultIndexMinSize: randomDetector.resultIndexMinSize,
46+
resultIndexTtl: randomDetector.resultIndexTtl,
4347
});
4448
});
4549
test('should return if detector does not have metadata', () => {
@@ -56,6 +60,10 @@ describe('detectorDefinitionToFormik', () => {
5660
timeField: randomDetector.timeField,
5761
interval: randomDetector.detectionInterval.period.interval,
5862
windowDelay: randomDetector.windowDelay.period.interval,
63+
resultIndex: randomDetector.resultIndex,
64+
resultIndexMinAge: randomDetector.resultIndexMinAge,
65+
resultIndexMinSize: randomDetector.resultIndexMinSize,
66+
resultIndexTtl: randomDetector.resultIndexTtl,
5967
});
6068
});
6169
test("upgrade old detector's filters to include filter type", () => {

public/pages/DefineDetector/utils/constants.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,7 @@ export const INITIAL_DETECTOR_DEFINITION_VALUES: DetectorDefinitionFormikValues
4444
interval: 10,
4545
windowDelay: 1,
4646
resultIndex: undefined,
47+
resultIndexMinAge: 7,
48+
resultIndexMinSize: 51200,
49+
resultIndexTtl: 60,
4750
};

public/pages/DefineDetector/utils/helpers.ts

+6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ export function detectorDefinitionToFormik(
4545
timeField: ad.timeField,
4646
interval: get(ad, 'detectionInterval.period.interval', 10),
4747
windowDelay: get(ad, 'windowDelay.period.interval', 0),
48+
resultIndexMinAge: get(ad, 'resultIndexMinAge', 7),
49+
resultIndexMinSize:get(ad, 'resultIndexMinSize', 51200),
50+
resultIndexTtl: get(ad, 'resultIndexTtl', 60),
4851
};
4952
}
5053

@@ -119,6 +122,9 @@ export function formikToDetectorDefinition(
119122
windowDelay: {
120123
period: { interval: values.windowDelay, unit: UNITS.MINUTES },
121124
},
125+
resultIndexMinAge: values.resultIndexMinAge,
126+
resultIndexMinSize: values.resultIndexMinSize,
127+
resultIndexTtl: values.resultIndexTtl,
122128
} as Detector;
123129

124130
return detectorBody;

0 commit comments

Comments
 (0)