[Index management] Client-side NP ready#57295
Conversation
|
Pinging @elastic/es-ui (Team:Elasticsearch UI) |
alisonelizabeth
left a comment
There was a problem hiding this comment.
Nice work @sebelga! LGTM. I tested integrations with ILM, CCR and rollups, and everything worked as expected.
I also uncommented out the tests you skipped and they appear to be passing for me locally. Do you think you could take another look?
| export const setupEnvironment = () => { | ||
| // Mock initialization of services | ||
| // @ts-ignore | ||
| httpService.setup(mockHttpClient); |
There was a problem hiding this comment.
Can you import the HttpService and use it instead of axios? Something like this:
const httpServiceSetupMock = new HttpService().setup({
injectedMetadata: injectedMetadataServiceMock.createSetupContract(),
fatalErrors: fatalErrorsServiceMock.createSetupContract(),
});
httpService.setup(httpServiceSetupMock);
There was a problem hiding this comment.
Thanks for the suggestion. I ended up trying with
// httpServiceMock.createSetupContract() returns an HttpSetupMock from core
httpService.setup(httpServiceMock.createSetupContract());but this breaks our tests. Probably because our sinon.fakeServer() requires a real http client like axios`. Will need to be investigated and changed in all our apps later.
There was a problem hiding this comment.
FWIW I did get this working for remote_clusters (PR: #57365). I did have to adjust the timeouts though.
There was a problem hiding this comment.
Cool. Did you try by providing directly the httpServiceMock.createSetupContract()) from core?
| ]); | ||
| testAction(3, done, 1); | ||
| }); | ||
| // server.respondWith(`${API_BASE_PATH}/indices/reload`, [ |
| import { setExtensionsService } from '../../../public/application/store/selectors'; | ||
|
|
||
| /* eslint-disable @kbn/eslint/no-restricted-paths */ | ||
| import { notificationServiceMock } from '../../../../../../../src/core/public/notifications/notifications_service.mock'; |
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
should this be notificationServiceMock.createSetupContract()?
There was a problem hiding this comment.
They are both the same, but for consistency let's use the createSetupContract () 👍
|
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 |
There was a problem hiding this comment.
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:
And rollup indices:
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'; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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'; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
|
Thanks for the review @cjcenizal ! I reverted the change for the constant import. Regarding the |
|
@sebelga It's your call! I'm happy with whatever you think makes sense. |
|
@elasticmachine merge upstream |
mattkime
left a comment
There was a problem hiding this comment.
Approve management changes
|
Thanks for the review @mattkime ! |
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 |
joshdover
left a comment
There was a problem hiding this comment.
The general structure here looks great!
| const { Context: I18nContext } = i18n; | ||
| const { services } = dependencies; | ||
|
|
||
| render( |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
💛 Build succeeded, but was flaky
History
To update your PR or re-run it, just comment with: |
…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) ...



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:
ILM summary tab extension
ILM actions menu extension
ILM filters extensions
CCR badge extension