[ILM] Add shrink field to hot phase (#84087)

* moved shrink field to shared_fields and added it to the hot phase

* updated test

* update legacy jest test

* removed configuration context for now

* remove unused i18n and remove duplicated isRolloverEnabled check;

* fixed shrink field to use new described field component

* added test for removing shrink field in serialization and re-ordered fields in hot phase advanced
This commit is contained in:
Jean-Louis Leysens 2020-12-10 10:50:31 +01:00 committed by GitHub
parent 8cdcae200c
commit dbd14ad39f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 140 additions and 81 deletions

View file

@ -187,12 +187,12 @@ export const setup = async (arg?: { appServicesContext: Partial<AppServicesConte
await createFormSetValueAction(`${phase}-selectedReplicaCount`)(value);
};
const setShrink = async (value: string) => {
await createFormToggleAction('shrinkSwitch')(true);
await createFormSetValueAction('warm-selectedPrimaryShardCount')(value);
const setShrink = (phase: Phases) => async (value: string) => {
await createFormToggleAction(`${phase}-shrinkSwitch`)(true);
await createFormSetValueAction(`${phase}-selectedPrimaryShardCount`)(value);
};
const shrinkExists = () => exists('shrinkSwitch');
const shrinkExists = (phase: Phases) => () => exists(`${phase}-shrinkSwitch`);
const setFreeze = createFormToggleAction('freezeSwitch');
const freezeExists = () => exists('freezeSwitch');
@ -237,6 +237,8 @@ export const setup = async (arg?: { appServicesContext: Partial<AppServicesConte
toggleRollover,
...createForceMergeActions('hot'),
setIndexPriority: setIndexPriority('hot'),
setShrink: setShrink('hot'),
shrinkExists: shrinkExists('hot'),
...createSearchableSnapshotActions('hot'),
},
warm: {
@ -247,8 +249,8 @@ export const setup = async (arg?: { appServicesContext: Partial<AppServicesConte
setDataAllocation: setDataAllocation('warm'),
setSelectedNodeAttribute: setSelectedNodeAttribute('warm'),
setReplicas: setReplicas('warm'),
setShrink,
shrinkExists,
setShrink: setShrink('warm'),
shrinkExists: shrinkExists('warm'),
...createForceMergeActions('warm'),
setIndexPriority: setIndexPriority('warm'),
},

View file

@ -125,6 +125,7 @@ describe('<EditPolicy />', () => {
await actions.hot.toggleForceMerge(true);
await actions.hot.setForcemergeSegmentsCount('123');
await actions.hot.setBestCompression(true);
await actions.hot.setShrink('2');
await actions.hot.setIndexPriority('123');
await actions.savePolicy();
@ -148,6 +149,9 @@ describe('<EditPolicy />', () => {
"set_priority": Object {
"priority": 123,
},
"shrink": Object {
"number_of_shards": 2,
},
},
"min_age": "0ms",
},

View file

@ -487,7 +487,7 @@ describe('edit policy', () => {
await setPolicyName(rendered, 'mypolicy');
await activatePhase(rendered, 'warm');
act(() => {
findTestSubject(rendered, 'shrinkSwitch').simulate('click');
findTestSubject(rendered, 'warm-shrinkSwitch').simulate('click');
});
rendered.update();
await setPhaseAfter(rendered, 'warm', '1');
@ -505,7 +505,7 @@ describe('edit policy', () => {
await activatePhase(rendered, 'warm');
await setPhaseAfter(rendered, 'warm', '1');
act(() => {
findTestSubject(rendered, 'shrinkSwitch').simulate('click');
findTestSubject(rendered, 'warm-shrinkSwitch').simulate('click');
});
rendered.update();
const shrinkInput = findTestSubject(rendered, 'warm-selectedPrimaryShardCount');

View file

@ -65,6 +65,7 @@ export interface SerializedHotPhase extends SerializedPhase {
max_docs?: number;
};
forcemerge?: ForcemergeAction;
shrink?: ShrinkAction;
set_priority?: {
priority: number | null;
};
@ -78,9 +79,7 @@ export interface SerializedHotPhase extends SerializedPhase {
export interface SerializedWarmPhase extends SerializedPhase {
actions: {
allocate?: AllocateAction;
shrink?: {
number_of_shards: number;
};
shrink?: ShrinkAction;
forcemerge?: ForcemergeAction;
set_priority?: {
priority: number | null;
@ -124,6 +123,10 @@ export interface AllocateAction {
};
}
export interface ShrinkAction {
number_of_shards: number;
}
export interface ForcemergeAction {
max_num_segments: number;
// only accepted value for index_codec

View file

@ -37,6 +37,7 @@ import {
SetPriorityInputField,
SearchableSnapshotField,
useRolloverPath,
ShrinkField,
} from '../shared_fields';
import { maxSizeStoredUnits, maxAgeUnits } from './constants';
@ -235,6 +236,7 @@ export const HotPhase: FunctionComponent = () => {
{isRolloverEnabled && (
<>
{<ForcemergeField phase="hot" />}
<ShrinkField phase="hot" />
{license.canUseSearchableSnapshot() && <SearchableSnapshotField phase="hot" />}
</>
)}

View file

@ -16,4 +16,6 @@ export { MinAgeInputField } from './min_age_input_field';
export { SnapshotPoliciesField } from './snapshot_policies_field';
export { ShrinkField } from './shrink_field';
export { SearchableSnapshotField } from './searchable_snapshot_field';

View file

@ -0,0 +1,73 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTextColor } from '@elastic/eui';
import React, { FunctionComponent } from 'react';
import { UseField, NumericField } from '../../../../../../shared_imports';
import { useEditPolicyContext } from '../../../edit_policy_context';
import { i18nTexts } from '../../../i18n_texts';
import { LearnMoreLink, DescribedFormRow } from '../../';
interface Props {
phase: 'hot' | 'warm';
}
export const ShrinkField: FunctionComponent<Props> = ({ phase }) => {
const path = `phases.${phase}.actions.shrink.number_of_shards`;
const { policy } = useEditPolicyContext();
return (
<DescribedFormRow
title={
<h3>
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.shrinkText"
defaultMessage="Shrink"
/>
</h3>
}
description={
<EuiTextColor color="subdued">
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.shrinkIndexExplanationText"
defaultMessage="Shrink the index into a new index with fewer primary shards."
/>{' '}
<LearnMoreLink docPath="indices-shrink-index.html#indices-shrink-index" />
</EuiTextColor>
}
titleSize="xs"
switchProps={{
'aria-controls': 'shrinkContent',
'data-test-subj': `${phase}-shrinkSwitch`,
label: i18nTexts.editPolicy.shrinkLabel,
'aria-label': i18nTexts.editPolicy.shrinkLabel,
initialValue: Boolean(policy.phases[phase]?.actions?.shrink),
}}
fullWidth
>
<div id="shrinkContent" aria-live="polite" role="region">
<EuiFlexGroup>
<EuiFlexItem>
<UseField
path={path}
component={NumericField}
componentProps={{
fullWidth: false,
euiFieldProps: {
'data-test-subj': `${phase}-selectedPrimaryShardCount`,
min: 1,
},
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer />
</div>
</DescribedFormRow>
);
};

View file

@ -9,14 +9,7 @@ import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import { get } from 'lodash';
import {
EuiTextColor,
EuiFlexGroup,
EuiFlexItem,
EuiSpacer,
EuiDescribedFormGroup,
EuiAccordion,
} from '@elastic/eui';
import { EuiSpacer, EuiDescribedFormGroup, EuiAccordion } from '@elastic/eui';
import { useFormData, UseField, ToggleField, NumericField } from '../../../../../../shared_imports';
@ -25,7 +18,7 @@ import { Phases } from '../../../../../../../common/types';
import { useEditPolicyContext } from '../../../edit_policy_context';
import { useConfigurationIssues } from '../../../form';
import { LearnMoreLink, ActiveBadge, DescribedFormRow } from '../../';
import { ActiveBadge, DescribedFormRow } from '../../';
import {
useRolloverPath,
@ -33,12 +26,10 @@ import {
ForcemergeField,
SetPriorityInputField,
DataTierAllocationField,
ShrinkField,
} from '../shared_fields';
const i18nTexts = {
shrinkLabel: i18n.translate('xpack.indexLifecycleMgmt.warmPhase.shrinkIndexLabel', {
defaultMessage: 'Shrink index',
}),
dataTierAllocation: {
description: i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.description', {
defaultMessage: 'Move data to nodes optimized for less-frequent, read-only access.',
@ -178,55 +169,8 @@ export const WarmPhase: FunctionComponent = () => {
}}
/>
</DescribedFormRow>
{!isUsingSearchableSnapshotInHotPhase && (
<DescribedFormRow
title={
<h3>
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.warmPhase.shrinkText"
defaultMessage="Shrink"
/>
</h3>
}
description={
<EuiTextColor color="subdued">
<FormattedMessage
id="xpack.indexLifecycleMgmt.editPolicy.warmPhase.shrinkIndexExplanationText"
defaultMessage="Shrink the index into a new index with fewer primary shards."
/>{' '}
<LearnMoreLink docPath="indices-shrink-index.html#indices-shrink-index" />
</EuiTextColor>
}
titleSize="xs"
switchProps={{
'aria-controls': 'shrinkContent',
'data-test-subj': 'shrinkSwitch',
label: i18nTexts.shrinkLabel,
'aria-label': i18nTexts.shrinkLabel,
initialValue: policy.phases.warm?.actions?.shrink != null,
}}
fullWidth
>
<div id="shrinkContent" aria-live="polite" role="region">
<EuiSpacer />
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<UseField
path="phases.warm.actions.shrink.number_of_shards"
component={NumericField}
componentProps={{
euiFieldProps: {
'data-test-subj': `${warmProperty}-selectedPrimaryShardCount`,
min: 1,
},
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer />
</div>
</DescribedFormRow>
)}
{!isUsingSearchableSnapshotInHotPhase && <ShrinkField phase="warm" />}
{!isUsingSearchableSnapshotInHotPhase && <ForcemergeField phase="warm" />}
{/* Data tier allocation section */}

View file

@ -48,6 +48,7 @@ import {
import { schema, deserializer, createSerializer, createPolicyNameValidations, Form } from './form';
import { useEditPolicyContext } from './edit_policy_context';
import { FormInternal } from './types';
export interface Props {

View file

@ -290,4 +290,14 @@ describe('deserializer and serializer', () => {
enabled: false,
});
});
it('removes shrink from hot and warm when unset', () => {
delete formInternal.phases.hot!.actions!.shrink;
delete formInternal.phases.warm!.actions!.shrink;
const result = serializer(formInternal);
expect(result.phases.hot!.actions.shrink).toBeUndefined();
expect(result.phases.warm!.actions.shrink).toBeUndefined();
});
});

View file

@ -181,6 +181,25 @@ export const schema: FormSchema<FormInternal> = {
serializer: serializers.stringToNumber,
},
},
shrink: {
number_of_shards: {
label: i18n.translate('xpack.indexLifecycleMgmt.shrink.numberOfPrimaryShardsLabel', {
defaultMessage: 'Number of primary shards',
}),
validations: [
{
validator: emptyField(i18nTexts.editPolicy.errors.numberRequired),
},
{
validator: numberGreaterThanField({
message: i18nTexts.editPolicy.errors.numberGreatThan0Required,
than: 0,
}),
},
],
serializer: serializers.stringToNumber,
},
},
set_priority: {
priority: {
defaultValue: defaultSetPriority as any,
@ -216,7 +235,7 @@ export const schema: FormSchema<FormInternal> = {
},
shrink: {
number_of_shards: {
label: i18n.translate('xpack.indexLifecycleMgmt.warmPhase.numberOfPrimaryShardsLabel', {
label: i18n.translate('xpack.indexLifecycleMgmt.shrink.numberOfPrimaryShardsLabel', {
defaultMessage: 'Number of primary shards',
}),
validations: [

View file

@ -69,6 +69,10 @@ export const createSerializer = (originalPolicy?: SerializedPolicy) => (
delete hotPhaseActions.set_priority;
}
if (!updatedPolicy.phases.hot?.actions?.shrink) {
delete hotPhaseActions.shrink;
}
if (!updatedPolicy.phases.hot!.actions?.searchable_snapshot) {
delete hotPhaseActions.searchable_snapshot;
}

View file

@ -8,6 +8,9 @@ import { i18n } from '@kbn/i18n';
export const i18nTexts = {
editPolicy: {
shrinkLabel: i18n.translate('xpack.indexLifecycleMgmt.shrink.indexFieldLabel', {
defaultMessage: 'Shrink index',
}),
searchableSnapshotInHotPhase: {
searchableSnapshotDisallowed: {
calloutTitle: i18n.translate(

View file

@ -9032,8 +9032,6 @@
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.activateWarmPhaseSwitchLabel": "ウォームフェーズを有効にする",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.indexPriorityExplanationText": "ノードの再起動後にインデックスを復元する優先順位を設定します。優先順位の高いインデックスは優先順位の低いインデックスよりも先に復元されます。",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.numberOfReplicas.switchLabel": "レプリカを設定",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.shrinkIndexExplanationText": "インデックス情報をプライマリシャードの少ない新規インデックスに縮小します。",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.shrinkText": "縮小",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.warmPhaseDescriptionMessage": "まだインデックスにクエリを実行中ですが、読み取り専用です。性能の低いハードウェアにシャードを割り当てることができます。検索を高速化するために、シャードの数を減らしセグメントを結合することができます。",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.warmPhaseLabel": "ウォームフェーズ",
"xpack.indexLifecycleMgmt.featureCatalogueDescription": "ライフサイクルポリシーを定義し、インデックス年齢として自動的に処理を実行します。",
@ -9164,11 +9162,9 @@
"xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm.title": "ウォームティアに割り当てられているノードがありません",
"xpack.indexLifecycleMgmt.warmPhase.dataTier.description": "頻度が低い読み取り専用アクセス用に最適化されたノードにデータを移動します。",
"xpack.indexLifecycleMgmt.warmPhase.moveToWarmPhaseOnRolloverLabel": "ロールオーバー時にウォームフェーズに変更",
"xpack.indexLifecycleMgmt.warmPhase.numberOfPrimaryShardsLabel": "プライマリシャードの数",
"xpack.indexLifecycleMgmt.warmPhase.numberOfReplicasDescription": "レプリカの数を設定します。デフォルトでは前のフェーズと同じです。",
"xpack.indexLifecycleMgmt.warmPhase.numberOfReplicasLabel": "レプリカの数",
"xpack.indexLifecycleMgmt.warmPhase.replicasTitle": "レプリカ",
"xpack.indexLifecycleMgmt.warmPhase.shrinkIndexLabel": "インデックスを縮小",
"xpack.infra.alerting.alertFlyout.groupBy.placeholder": "なし(グループなし)",
"xpack.infra.alerting.alertFlyout.groupByLabel": "グループ分けの条件",
"xpack.infra.alerting.alertsButton": "アラート",

View file

@ -9041,8 +9041,6 @@
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.activateWarmPhaseSwitchLabel": "激活温阶段",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.indexPriorityExplanationText": "设置在节点重新启动后恢复索引的优先级。较高优先级的索引会在较低优先级的索引之前恢复。",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.numberOfReplicas.switchLabel": "设置副本",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.shrinkIndexExplanationText": "将索引缩小成具有较少主分片的新索引。",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.shrinkText": "缩小",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.warmPhaseDescriptionMessage": "您仍在查询自己的索引,但其为只读。您可以将分片分配给效率较低的硬件。为了获取更快的搜索,您可以减少分片数目并强制合并段。",
"xpack.indexLifecycleMgmt.editPolicy.warmPhase.warmPhaseLabel": "温阶段",
"xpack.indexLifecycleMgmt.featureCatalogueDescription": "定义生命周期策略,以随着索引老化自动执行操作。",
@ -9173,11 +9171,9 @@
"xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm.title": "没有分配到温层的节点",
"xpack.indexLifecycleMgmt.warmPhase.dataTier.description": "将数据移到针对不太频繁的只读访问优化的节点。",
"xpack.indexLifecycleMgmt.warmPhase.moveToWarmPhaseOnRolloverLabel": "滚动更新时移到温阶段",
"xpack.indexLifecycleMgmt.warmPhase.numberOfPrimaryShardsLabel": "主分片数目",
"xpack.indexLifecycleMgmt.warmPhase.numberOfReplicasDescription": "设置副本数目。默认情况下与上一阶段相同。",
"xpack.indexLifecycleMgmt.warmPhase.numberOfReplicasLabel": "副本分片数目",
"xpack.indexLifecycleMgmt.warmPhase.replicasTitle": "副本",
"xpack.indexLifecycleMgmt.warmPhase.shrinkIndexLabel": "缩小索引",
"xpack.infra.alerting.alertFlyout.groupBy.placeholder": "无内容(未分组)",
"xpack.infra.alerting.alertFlyout.groupByLabel": "分组依据",
"xpack.infra.alerting.alertsButton": "告警",