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

[Index management] Client-side NP ready #57295

Merged
merged 42 commits into from
Feb 17, 2020

Conversation

sebelga
Copy link
Contributor

@sebelga sebelga commented Feb 11, 2020

This PR adds the client-side migration of index management to the new platform.

As there are many changes and 3 dependent apps, I added both of you @cjcenizal and @alisonelizabeth to review this PR and make sure all the extensions keep on working.

The 3 app that have extensions are:

  • rollup
  • ILM
  • Cross cluster replication

ILM summary tab extension

Screen Shot 2020-02-11 at 11 12 20

ILM actions menu extension

Screen Shot 2020-02-11 at 11 38 02

Screen Shot 2020-02-11 at 12 05 27

Screen Shot 2020-02-11 at 15 29 50

ILM filters extensions

Screen Shot 2020-02-11 at 12 06 34

CCR badge extension

Screen Shot 2020-02-11 at 11 56 12

@sebelga sebelga added Feature:Index Management Index and index templates UI Team:Kibana Management Dev Tools, Index Management, Upgrade Assistant, ILM, Ingest Node Pipelines, and more v7.7.0 v8.0.0 labels Feb 11, 2020
@elasticmachine
Copy link
Contributor

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

import { setExtensionsService } from '../../../public/application/store/selectors';

/* eslint-disable @kbn/eslint/no-restricted-paths */
import { notificationServiceMock } from '../../../../../../../src/core/public/notifications/notifications_service.mock';
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: all core mocks should be available via src/core/public/mocks

httpService.setup(mockHttpClient);
breadcrumbService.setup(() => undefined);
documentationService.setup(docLinksServiceMock.createStartContract());
notificationService.setup(notificationServiceMock.createStartContract());
Copy link
Contributor

Choose a reason for hiding this comment

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

should this be notificationServiceMock.createSetupContract()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They are both the same, but for consistency let's use the createSetupContract () 👍

@sebelga
Copy link
Contributor Author

sebelga commented Feb 13, 2020

Thanks for the review @alisonelizabeth ! I uncommented the tests and they pass now. Mistery of life! 😄 I address your feedback and made a comment about not using axios.

Copy link
Contributor

@cjcenizal cjcenizal left a comment

Choose a reason for hiding this comment

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

Great work @sebelga! I tested ILM, Rollups, CCR, and UI metric telemetry and everything worked as expected. Here's a screenshot verifying CCR follower indices had the correct badge:

image

And rollup indices:

image

I do feel pretty strongly that we're adding friction to the DX by renaming init to setup in our services, but I don't think it's worth blocking on because it would be simple to change later.

import { BASE_PATH } from '../../../../../../../common/constants';
import { UIM_EDIT_CLICK } from '../../../../constants';
import { getIndexListUri } from '../../../../../../../../index_management/public/application/services/navigation';
import { BASE_PATH, UIM_EDIT_CLICK } from '../../../../../../../common/constants';
Copy link
Contributor

@cjcenizal cjcenizal Feb 13, 2020

Choose a reason for hiding this comment

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

Why did UIM_EDIT_CLICK get moved to common? If these constants aren't being consumed by both public and server code, then I think they belong in public.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is probably from the merge conflict resolution. There are no UIM_EDIT_CLICK in the common folder so importing it is probably undefined.. Will revert that change. 👍

import { IndexMgmtMetricsType } from '../../types';

// Temporary hack to provide the uiMetricService instance to this file.
// TODO: Refactor and export an ApiService instance through the app dependencies context
Copy link
Contributor

Choose a reason for hiding this comment

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

When do you plan to address this TODO?

import { getToggleExtensions } from '../../../index_management_extensions';

// Temporary hack to provide the extensionsService instance to this file.
// TODO: Refactor and export all the app selectors through the app dependencies context
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm happy to see this note here because it did surprise me to see this function available from this module. When do you plan to address this TODO?

import { ShowJson } from './show_json';
import { Summary } from './summary';
import { EditSettingsJson } from './edit_settings_json';
import { useServices } from '../../../../app_context';
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Personally I find grouping imports by how distant they are from the file makes it easier to reason about relationships between the imports and the file importing them. For example, I know ShowJson, Summary, and EditSettingsJson are local to this file so I expect to be able to refactor them more easily because they probably aren't meant for external consumptions. So I'd put this import on line 32.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I also like that structure of ordering importing and I've already updated the imports order whenever I bump into them. I've seen in places in our code absolute path coming after relative ones.

public init(chrome: ChromeStart, managementBreadcrumb: any): void {
this.chrome = chrome;
this.breadcrumbs.management = [managementBreadcrumb];
public setup(setBreadcrumbsHandler: SetBreadcrumbs): void {
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the benefit of using the name setup in these services? I'm finding it confusing because one core aspect of the NP mental model is that of the lifecycle, defined by setup, start, and stop. These terms are associated with plugins and how they work, but as far as I can tell these services have no knowledge of the plugin lifecycle. Is there an instance in which we'd need to start or stop a service?

If not, then I think we should avoid using lifecycle terms. This will avoid overloading them, allowing us to grep for calls to setup( with confidence that any hits will be related to the NP lifecycle.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So this change is to align on terms and simplify the mental model. Those setup function are meant to be called.... at plugin setup() lifecycle time. And this method does that: set up the service, passing down any required dependencies to the service.

We could call it: "init", "register", "setup", " it does not really matter. But I like to have 1 standard and stick to it.

These terms are associated with plugins and how they work

If you look at core services, like HttpService, you will see it is not only plugins but also services that align on the setup, start and stop public method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there an instance in which we'd need to start or stop a service?

Well, your question made me see that we might have a memory leak with the current License.ts implementation.

// this is the logic inside its setup() function
licensing.license$.subscribe(license => {
  const { state, message } = license.check(pluginId, minimumLicenseType);
  const hasRequiredLicense = state === LICENSE_CHECK_STATE.Valid;

  if (hasRequiredLicense) {
    this.licenseStatus = { isValid: true };
  } else {
    this.licenseStatus = {
      isValid: false,
      message: message || defaultErrorMessage,
    };
    if (message) {
      logger.info(message);
    }
  }
});

We might have to unsubscribe when the plugin is stopped (and call the stop() method on this service. I will check

@sebelga
Copy link
Contributor Author

sebelga commented Feb 13, 2020

Thanks for the review @cjcenizal ! I reverted the change for the constant import.

Regarding the init vs setup, if you feel strongly we'll revert. I do like to have a convention in place and not have different function names for the same concept (.register() .init() .initialize() .initService()). So my point was: let's use the core team term setup() which defines very well the setting up of a service.

@cjcenizal cjcenizal requested a review from joshdover February 13, 2020 08:28
@cjcenizal
Copy link
Contributor

@sebelga It's your call! I'm happy with whatever you think makes sense.

@sebelga
Copy link
Contributor Author

sebelga commented Feb 14, 2020

@elasticmachine merge upstream

Copy link
Contributor

@mattkime mattkime left a comment

Choose a reason for hiding this comment

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

Approve management changes

@sebelga
Copy link
Contributor Author

sebelga commented Feb 14, 2020

Thanks for the review @mattkime !

@joshdover
Copy link
Contributor

Regarding the init vs setup, if you feel strongly we'll revert. I do like to have a convention in place and not have different function names for the same concept (.register() .init() .initialize() .initService()). So my point was: let's use the core team term setup() which defines very well the setting up of a service.

This is a great change! We find that it makes plugins easier to reason about if they follow the same convention as Core. One of the largest plugins, the data plugin follows this convention as well. This also makes it easier to restructure your plugin later if they all follow the same general lifecycles and which services are available during each lifecycle.

Copy link
Contributor

@joshdover joshdover left a comment

Choose a reason for hiding this comment

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

The general structure here looks great!

const { Context: I18nContext } = i18n;
const { services } = dependencies;

render(
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this application use a router? If so it needs to be configured with appBasePath to ensure it works with the basePath correctly. Once #56705 is merged, you will need to use the history instance that is provided with your react-router.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Setting the basename on the react router does not work as we already add the base path manually on each route like so

<Switch>
  <Route exact path={`${BASE_PATH}create_template`} component={TemplateCreate} />
  <Route exact path={`${BASE_PATH}clone_template/:name*`} component={TemplateClone} />
  <Route exact path={`${BASE_PATH}edit_template/:name*`} component={TemplateEdit} />
  <Route path={`${BASE_PATH}:section(indices|templates)`} component={IndexManagementHome} />
  <Redirect from={`${BASE_PATH}`} to={`${BASE_PATH}indices`} />
</Switch>

Do you recommend to refactor and use the basename prop on the router?

@kibanamachine
Copy link
Contributor

💛 Build succeeded, but was flaky

History

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

@sebelga sebelga merged commit 8e17fda into elastic:master Feb 17, 2020
@sebelga sebelga deleted the np-migration/index-management-public-2 branch February 17, 2020 08:52
jloleysens added a commit to jloleysens/kibana that referenced this pull request Feb 17, 2020
…re/files-and-filetree

* 'master' of github.com:elastic/kibana: (139 commits)
  Move Ace XJSON lexer-rules, worker and utils to es_ui_shared (elastic#57563)
  [Upgrade Assistant] Fix filter deprecations search filter (elastic#57541)
  [ML] New Platform server shim: update indices routes (elastic#57685)
  Bump redux dependencies (elastic#53348)
  [Index management] Client-side NP ready (elastic#57295)
  change id of x-pack event_log plugin to eventLog (elastic#57612)
  [eventLog] get kibana.index name from config instead of hard-coding it (elastic#57607)
  revert
  allow using any path to generate
  fixes ui titles (elastic#57535)
  Fix login redirect for expired sessions (elastic#57157)
  Expose Vis on the contract as it requires visTypes (elastic#56968)
  [SIEM][Detection Engine] Fixes queries to ignore errors when signals index is not present
  [Remote clusters] Migrate client-side code out of legacy (elastic#57365)
  Fix failed test reporter for SIEM Cypress use (elastic#57240)
  skip flaky suite (elastic#45244)
  update chromedriver to 80.0.1 (elastic#57602)
  change slack action to only report on whitelisted host name (elastic#57582)
  [kbn/optimizer] throw errors into stream on invalid completion (elastic#57735)
  moving visualize/utils to new platform (elastic#56650)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Index Management Index and index templates UI Feature:NP Migration 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.7.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants