Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ILM] Migrate Hot phase to Form Lib #80012

Merged
merged 33 commits into from
Oct 19, 2020

Conversation

jloleysens
Copy link
Contributor

@jloleysens jloleysens commented Oct 8, 2020

Summary

Migrate the hot phase in the ILM form to use the form lib.?

  • Duplicated the SetPriority and Forcemerge components for now to create the form lib versions that will be used elsewhere
  • Added serialisation test coverage for hot phase to client integration tests
  • Removed hot phase serialisation/deserialization for hot phase from x-pack/plugins/index_lifecycle_management/public/application/services

How to review

  1. Regression test that Index Lifecycle Management enables setting hot phase for new and existing policies
  2. Serialisation and deserialisation code has been moved to the serialization.ts and deserialization.ts files that are used in the form that lives in edit_policy.ts.
  3. For now, the setWarmPhaseOnRollover function is still being passed to the HotPhase component since the warm phase is not be handled by the form yet and it is used in the legacy serialization of the warm phase. This will be addressed in the next PR for this work.

New JSON policy flyout behaviour

Note: error states are not ideal, those three fields are all connected and so are correctly erroring out together. But the UX of this should probably be revisited @mdefazio

flyout-validation

Checklist

Delete any items that are not applicable to this PR.

- tests are now broken
- need to break up the hot_phase file in to meaningful parts
- duplicated set_priority and forcemerge components
- moved a lot of files around
- removed the need for the state to track whether rollover is set
@jloleysens jloleysens added chore Feature:ILM v8.0.0 Team:Kibana Management Dev Tools, Index Management, Upgrade Assistant, ILM, Ingest Node Pipelines, and more release_note:skip Skip the PR/issue when compiling release notes v7.11.0 labels Oct 8, 2020
@jloleysens
Copy link
Contributor Author

@elasticmachine merge upstream

kibanamachine and others added 11 commits October 12, 2020 05:56
- refactor serializePolicy -> legacySerializePolicy
- updated serialization of form lib to factor in pre-existing
  policy values. These should be interacted with in a non-lossy
  way.
…otphase-to-formlib

* 'master' of github.com:elastic/kibana: (59 commits)
  [Security Solution][Resolver] Replace copy-to-clipboard with native navigator.clipboard (elastic#80193)
  [Security Solution] Reduce initial bundle size (elastic#78992)
  [Security Solution][Resolver] Fix Resize node box-shadow bug (elastic#80223)
  Move observability content (elastic#79978)
  skip flaky suite (elastic#79389)
  removing kibana_datatable` in favor of `datatable` (elastic#75184)
  [ML] Fixes for anomaly swim lane  (elastic#80299)
  [Lens] Smokescreen lens test unskip (elastic#80190)
  Improved AlertsClient tests structure by splitting a huge alerts_client.tests.ts file into a specific files defined by its responsibility. (elastic#80088)
  [APM] React key warning when opening popover with external resources (elastic#80328)
  [Step 1] use Observables on server search API (elastic#79874)
  Apply back pressure in Task Manager whenever Elasticsearch responds with a 429 (elastic#75666)
  [Lens] Leverage original http request error (elastic#79831)
  [Security Solution][Case] Improve ServiceConnectorCaseParams type (elastic#80109)
  [SECURITY_SOLUTION] Fix query on alert histogram (elastic#80219)
  [DOCS] Update ingest node pipelines doc (elastic#79187)
  [Ingest Manager] Split up OpenAPI spec file  (elastic#80107)
  [SECURITY_SOLUTION][ENDPOINT] Fix label on Trusted App create name field (elastic#80001)
  [Ingest Manager] Fix agent policy bump revision to create only one POLICY_CHANGE action (elastic#80081)
  Grid layout fixes (elastic#80305)
  ...

# Conflicts:
#	x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared/data_tier_allocation_field.tsx
#	x-pack/plugins/index_lifecycle_management/public/shared_imports.ts
@jloleysens
Copy link
Contributor Author

@elasticmachine merge upstream

@jloleysens jloleysens marked this pull request as ready for review October 14, 2020 07:26
@jloleysens jloleysens requested a review from a team as a code owner October 14, 2020 07:26
@elasticmachine
Copy link
Contributor

Pinging @elastic/es-ui (Team:Elasticsearch UI)

Copy link
Contributor

@sebelga sebelga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work @jloleysens ! Overall everything works great! I did notice one small bug: when I click the submit button without giving a name I get the validation error. Then I give the policy a name but the error is still there.

Screenshot 2020-10-15 at 17 38 21

The only potential bug I've noticed is about the request JSON in the flyout, I've added a comment. We can discuss it over zoom.

I would also like to weigh in with you the benefit of having a schema for the policy form, a central place to declare the field configurations. Let's talk about it tomorrow ok? Cheers!

describedByIds={rest.idAria ? [rest.idAria] : undefined}
{...rest}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! 👍 Can we make this change to all the components?

}
type SetupReturn = ReturnType<typeof setup>;

export type EditPolicyTestBed = SetupReturn extends Promise<infer U> ? U : SetupReturn;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice trick! I guess we'll never hit the right part of the ternary right? But this is a way to extract U? Interesting... 😊

@@ -21,6 +26,83 @@ describe('<EditPolicy />', () => {
server.restore();
});

describe('hot phase', () => {
describe('serialization', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome to have the serialization test here! 👍

await act(async () => {
maxSizeInput.simulate('change', { target: { value: '-1' } });
});
waitForFormLibValidation();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind adding a comment explaining why in this case we need to wait for the validations? That is because there is a 300ms delay before displaying field error message?

@@ -142,12 +139,38 @@ const setPhaseIndexPriority = (
priorityInput.simulate('change', { target: { value: priority } });
rendered.update();
};
const save = (rendered: ReactWrapper) => {
const setPhaseIndexPriorityFormLib = async (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to not add the "FormLib" suffix and add a "Legacy" suffix to the other method. As we plan on migrating the rest of the test file right?

@@ -3,6 +3,12 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

/**
* PLEASE NOTE: This component is currently duplicated. A version of this component wired up with
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the "Please", that's very thoughtful 😊

import { FormInternal } from './components/phases/types';

export const deserializer = (policy: SerializedPolicy): FormInternal =>
produce<FormInternal>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great to see immer in action! 👍 I will have to use it too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is indeed very convenient! I would caution against using it on massive+nested objects. On lower memory environments it can blow the stack because it recurses :(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know!

}

if (rest.phases.hot) {
rest.phases.hot.min_age = originalPolicy?.phases.hot?.min_age ?? '0ms';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the rest.phases.hot.min_age cannot be set in the form? It is simply copied over the originalPolicy or given a default value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it is a bit of a weird one. This is what current serialisation behaviour gives us:

export const serializedPhaseInitialization: SerializedPhase = {

but with a bit more indirection

@@ -85,30 +127,57 @@ export const EditPolicy: React.FunctionComponent<Props> = ({
history.push('/policies');
};

const setWarmPhaseOnRollover = useCallback(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to get rid of this indirection in future PR! 😊


<EuiSpacer />

<HotPhase setWarmPhaseOnRollover={setWarmPhaseOnRollover} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice and clean 👍

@jloleysens
Copy link
Contributor Author

@elasticmachine merge upstream

@jloleysens
Copy link
Contributor Author

@elasticmachine merge upstream

@@ -165,6 +165,11 @@ describe('edit policy', () => {
jest.useRealTimers();
});

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

const form = useFormContext();

useEffect(() => {
const subscription = form.subscribe(async (formUpdate) => {
Copy link
Contributor

@sebelga sebelga Oct 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will deprecate the form.subscribe in favor of the useFormData. Can we use it instead here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! I think in this particular case, the solution was less verbose with the use of form.subscribe because form.validate lives in a different context. However, I can see that useFormData should be the primary mechanism for hooking into updates for most cases.

@jloleysens
Copy link
Contributor Author

@sebelga I addressed your latest round of feedback, would you mind taking another look?

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

@kbn/optimizer bundle module count

id before after diff
indexLifecycleManagement 208 220 +12

async chunks size

id before after diff
indexLifecycleManagement 234.8KB 268.7KB +33.9KB

page load bundle size

id before after diff
esUiShared 304.3KB 304.2KB -131.0B
indexLifecycleManagement 89.9KB 90.6KB +688.0B
total +557.0B

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

*/
const [policy, setPolicy] = useState<undefined | null | SerializedPolicy>(undefined);

const form = useFormContext();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit, we don't need to validate on each form change if isValid is not undefined.

const form = useFormContext();
const [formData, getFormData] = useFormData();
const { isValid, validate } = form;

useEffect(() => {
  (async function checkPolicy() {
    const isFormValid = isValid ?? (await validate());

    if (isFormValid) {
      const p = getFormData() as SerializedPolicy;
      setPolicy({
        ...legacyPolicy,
        phases: {
          ...legacyPolicy.phases,
          hot: p.phases.hot,
        },
      });
    } else {
      setPolicy(null);
    }
  })();
  // eslint-disable-next-line react-hooks/exhaustive-deps
}, [isValid, validate, legacyPolicy, formData]);

Copy link
Contributor

@sebelga sebelga Oct 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also in f5edadc (#80842) I've fixed the problem that you faced when you had to add the eslint override.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, we should incorporate that into a following PR.

Copy link
Contributor

@sebelga sebelga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making all the changes @jloleysens! I tested locally and I'm happy with your solution regarding the validation for the request in the flyout. 👍

@jloleysens jloleysens merged commit 30fc4be into elastic:master Oct 19, 2020
@jloleysens jloleysens deleted the ilm/migrate-hotphase-to-formlib branch October 19, 2020 15:34
jloleysens added a commit to jloleysens/kibana that referenced this pull request Oct 19, 2020
* wip

* added missing shared_imports file to index

* initial migration of hot phase to form lib

- tests are now broken
- need to break up the hot_phase file in to meaningful parts
- duplicated set_priority and forcemerge components

* Big refactor

- moved a lot of files around
- removed the need for the state to track whether rollover is set

* Integrate form lib serialization with existing serialization

- refactor serializePolicy -> legacySerializePolicy
- updated serialization of form lib to factor in pre-existing
  policy values. These should be interacted with in a non-lossy
  way.

* wip on fixing jest tests and some other refactors

* fix jest tests and other refactors

* delete existing hot phase serialization and tests

* beginning of serializer test for hot phase

* added serialization tests for form lib components

* fix some i18n issues

* fixed delete phase integration test

* move hot phase serialization test to pre-existing test location

* fix another jest test issue

* fix ui metric tracking for setting input priority in hot phase

* refactor use rollover switch to form lib component and update validation for number segments in force merge

* readded missing validation 🤦🏼‍♂️

* fix type check issues and setting of rollover enabled 🙄

* migrate all form lib components to spreading all rest props in EuiFormRow

* added comment to test helper function

* refactor test helper setPhaseIndexPriorityFormLib -> setPhaseIndexPriority

* refactor to use form schema

* Removed use of UseMultiFields component

- also fix missing "key" on react component in unrelated file
- fixed ordering of JSON in test file
- also removed default value from form schema so that when a
  value is not set for max size, max docs or max age it will
  remain unset in future policies

* update json flyout behaviour

* fix json policy serialization

* Fix type and i18n issues

* do not use form.subscribe

* add missing key value in cells

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
jloleysens added a commit that referenced this pull request Oct 20, 2020
* wip

* added missing shared_imports file to index

* initial migration of hot phase to form lib

- tests are now broken
- need to break up the hot_phase file in to meaningful parts
- duplicated set_priority and forcemerge components

* Big refactor

- moved a lot of files around
- removed the need for the state to track whether rollover is set

* Integrate form lib serialization with existing serialization

- refactor serializePolicy -> legacySerializePolicy
- updated serialization of form lib to factor in pre-existing
  policy values. These should be interacted with in a non-lossy
  way.

* wip on fixing jest tests and some other refactors

* fix jest tests and other refactors

* delete existing hot phase serialization and tests

* beginning of serializer test for hot phase

* added serialization tests for form lib components

* fix some i18n issues

* fixed delete phase integration test

* move hot phase serialization test to pre-existing test location

* fix another jest test issue

* fix ui metric tracking for setting input priority in hot phase

* refactor use rollover switch to form lib component and update validation for number segments in force merge

* readded missing validation 🤦🏼‍♂️

* fix type check issues and setting of rollover enabled 🙄

* migrate all form lib components to spreading all rest props in EuiFormRow

* added comment to test helper function

* refactor test helper setPhaseIndexPriorityFormLib -> setPhaseIndexPriority

* refactor to use form schema

* Removed use of UseMultiFields component

- also fix missing "key" on react component in unrelated file
- fixed ordering of JSON in test file
- also removed default value from form schema so that when a
  value is not set for max size, max docs or max age it will
  remain unset in future policies

* update json flyout behaviour

* fix json policy serialization

* Fix type and i18n issues

* do not use form.subscribe

* add missing key value in cells

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chore Feature:ILM release_note:skip Skip the PR/issue when compiling release notes Team:Kibana Management Dev Tools, Index Management, Upgrade Assistant, ILM, Ingest Node Pipelines, and more v7.11.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants