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

Implements getStartServices on server-side #55156

Merged

Conversation

pgayvallet
Copy link
Contributor

@pgayvallet pgayvallet commented Jan 17, 2020

Summary

Fix #54886
Required to migrate plugin's calls for #52071

This adds a new getStartServices to the server-side CoreSetup type for accessing start contracts. This is intended to be used when registering handler during setup phase that will needs to accept start APIs and for which the usages of contexts is overly complicated.

Widely inspired server-side counter part of #50231

Checklist

Use strikethroughs to remove checklist items you don't feel are applicable to this PR.

- [ ] This was checked for cross-browser compatibility, including a check against IE11
- [ ] Any text added follows EUI's writing guidelines, uses sentence case text and includes i18n support

For maintainers

- [ ] This was checked for breaking API changes and was labeled appropriately
- [ ] This includes a feature addition or change that requires a release note and was labeled appropriately

Dev Docs

Adds a new API to be able to access start dependencies when registering handlers in setup phase.

class MyPlugin implements Plugin {
  setup(core: CoreSetup, plugins: PluginDeps) {
    plugins.usageCollection.registerCollector({
      type: 'MY_TYPE',
      fetch: async () => {
        const [coreStart] = await core.getStartServices();
        const internalRepo = coreStart.savedObjects.createInternalRepository();
        // ...
      },
    });
  }
  start() {}
}

@pgayvallet pgayvallet requested review from a team as code owners January 17, 2020 09:50
@pgayvallet pgayvallet added v7.7.0 v8.0.0 Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc labels Jan 17, 2020
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-platform (Team:Platform)

@pgayvallet pgayvallet added Feature:New Platform release_note:plugin_api_changes Contains a Plugin API changes section for the breaking plugin API changes section. labels Jan 17, 2020
@pgayvallet pgayvallet added this to Code review in kibana-core [DEPRECATED] via automation Jan 17, 2020
@pgayvallet
Copy link
Contributor Author

@elastic/kibana-security I changed the type of the CoreStart mock and had to adapt one of your type in some test. That's the only change impacting your owned codebase.

Comment on lines +89 to +90
type CoreSetupMockType = MockedKeys<CoreSetup> & jest.Mocked<Pick<CoreSetup, 'getStartServices'>>;

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 had a hard time adding getStartServices to the CoreSetup mock. MockedKeys does not properly handles functions and resulted in the mock not being compatible with the concrete implementation. Using jest.Mocked or DeeplyMockedKeys both resulted on errors on tests that were overriding read-only properties (that seems to be preserved by both but not by MockedKeys), such as

const coreSetup = coreMock.createSetup();
coreSetup.elasticsearch.dataClient = dataClient;

So I had to compose this custom type instead.

Copy link
Contributor

@mshustov mshustov Jan 17, 2020

Choose a reason for hiding this comment

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

It sounds like something we will face in the future again when marking more API points as readonly. We need to define a common pattern for configuring mocks at any deep level. Re-writing a property is the most obvious way, but create this incompatibility. Options:

  • a mock factory accepts an object configuring mocks at any deep coreMock.createSetup({ elasticsearch: { dataClient: ... } }); That would quick grow with the number of nested objects.
  • provide configurable mock factory (as a builder pattern, for example) coreMock.get().withElasticsearchDataClient(...).withSomethingElse().build()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After a quick look, this is not the first time this occurs (the exemple is actually the root cause if this specific issue)

type MockedElasticSearchServiceSetup = jest.Mocked<
ElasticsearchServiceSetup & {
adminClient: jest.Mocked<IClusterClient>;
dataClient: jest.Mocked<IClusterClient>;
}
>;

We are also inconsistent in the types we actually return from mocks. Some are explicitly mock instance, some are not

function createCoreStartMock() {
const mock: MockedKeys<CoreStart> = {

vs

function createInternalCoreSetupMock() {
const setupDeps: InternalCoreSetup = {

That would quick grow with the number of nested objects.

It does. however the (manually coded) factory pattern present the same (if not bigger) problem in term of maintenance. I'm not the biggest TS expert, but can't we have an utility type that would remove readonly from the mock definition while preserving compatibility with the concrete type?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hum, I was trying things and was not understanding why I couldnt override core.elasticsearch.dataClient from inside core... And I just saw that the MockedKeys type is not the same between src and x-pack... This explain why this is possible in the licensing plugin tests:

type MockedKeys<T> = { [P in keyof T]: jest.Mocked<T[P]> };

type MockedKeys<T> = { [P in keyof T]: jest.Mocked<Writable<T[P]>> };

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 outside of the scope of this PR. Created #55189 to continue the discussion

Comment on lines +20 to +22
import { mockPackage, mockDiscover } from './plugins_service.test.mocks';

import { join } from 'path';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are very similar to the service's unit test. However the difference is that in this file, we do not mock the underlying plugin system, and call the service's setup and start with actual mocked dependencies.

Comment on lines -96 to +100
return await this.instance.setup(setupContext, plugins);
return this.instance.setup(setupContext, plugins);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The method is async, awaiting the returning promise was unnecessary.

Copy link
Contributor

Choose a reason for hiding this comment

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

You are right. We use await excessively, even when it's not necessary async () => await do(). It's a matter of convention. Although it's not mentioned in core/conventions.md, so discussable.

Copy link
Contributor Author

@pgayvallet pgayvallet Jan 17, 2020

Choose a reason for hiding this comment

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

The only subtle difference will be the actual place it would throw from if the promise is rejected (I think?)

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see the difference. I have the same output

UNHANDLED PROMISE REJECTION Error: not found
    at mostInner (/Users/mikhailshustov/work/kibana/src.js:21:9)
    at inner (/Users/mikhailshustov/work/kibana/src.js:25:16)
    at outer (/Users/mikhailshustov/work/kibana/src.js:29:16)

for

async function mostInner() {
  throw new Error('not found');
}

async function inner() {
  return await mostInner();
}

async function outer() {
  return await inner();
}

outer();
process.on('unhandledRejection', error => {
  console.error('UNHANDLED PROMISE REJECTION', error);
});

and

function mostInner() {
  new Error('not found');
}

async function inner() {
  return mostInner();
}

async function outer() {
  return await inner();
}

outer();
process.on('unhandledRejection', error => {
  console.error('UNHANDLED PROMISE REJECTION', error);
});

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea you are right, tried it too this weekend. This is catched at the higher level anyway and gets the full stack in any case

Copy link
Member

@azasypkin azasypkin left a comment

Choose a reason for hiding this comment

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

Security related changes LGTM

const startDeps = coreMock.createInternalStart();
await pluginsService.start(startDeps);

expect(startDependenciesResolved).toBe(true);
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be worth verifying that the resolved dependencies are the objects you expect them to be.

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

History

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

@pgayvallet pgayvallet merged commit 2d10350 into elastic:master Jan 20, 2020
kibana-core [DEPRECATED] automation moved this from Code review to Needs Backport Jan 20, 2020
pgayvallet added a commit to pgayvallet/kibana that referenced this pull request Jan 20, 2020
* implements server-side getStartServices

* add unit test

* add integration test

* update generated doc

* improve test
pgayvallet added a commit that referenced this pull request Jan 20, 2020
* implements server-side getStartServices

* add unit test

* add integration test

* update generated doc

* improve test
@pgayvallet pgayvallet moved this from Needs Backport to Done (7.7) in kibana-core [DEPRECATED] Jan 20, 2020
gmmorris added a commit to gmmorris/kibana that referenced this pull request Jan 20, 2020
* upstream/master: (24 commits)
  Show error page when accessing unavailable app (elastic#54656)
  [ML] Improving job wizards with datafeed aggregations (elastic#55180)
  remove flaly assetion. a license presence tested anyway (elastic#55289)
  fix commonly used ranges uptime (elastic#54930)
  [SIEM] Use proper icons on Detections view (elastic#55215)
  Fix: invalid translation referenced (elastic#54901)
  [State Management] Remove AppState from edit_index_pattern page (elastic#54104)
  Implements `getStartServices` on server-side (elastic#55156)
  Move vis_vega_type/data_model tests to jest (elastic#55186)
  [SIEM] [Detection Engine] Update status on rule details page (elastic#55201)
  Fix KQL value suggestions for nested fields (elastic#54820)
  Enforce camelCase format for a plugin id (elastic#53759)
  [SIEM] Detection engine cleanup for rule details/creation/edit page (elastic#55069)
  Remove nested root from index pattern (elastic#54978)
  [Reporting/Migration] ReportingSetup, LegacySetup (elastic#54198)
  [SIEM] [Detection Engine] Fixes duplicate rule action (elastic#55252)
  [SIEM] Detections add alert & signal tab (elastic#55127)
  Management API - redirect on disabled app path (elastic#55136)
  [SIEM][Detection Engine] Fixes critical regression on the backend with immutable and tags
  update local (elastic#55177)
  ...
gmmorris added a commit to gmmorris/kibana that referenced this pull request Jan 20, 2020
* master: (108 commits)
  [ML] Single Metric Viewer: Fix job check. (elastic#55191)
  Show error page when accessing unavailable app (elastic#54656)
  [ML] Improving job wizards with datafeed aggregations (elastic#55180)
  remove flaly assetion. a license presence tested anyway (elastic#55289)
  fix commonly used ranges uptime (elastic#54930)
  [SIEM] Use proper icons on Detections view (elastic#55215)
  Fix: invalid translation referenced (elastic#54901)
  [State Management] Remove AppState from edit_index_pattern page (elastic#54104)
  Implements `getStartServices` on server-side (elastic#55156)
  Move vis_vega_type/data_model tests to jest (elastic#55186)
  [SIEM] [Detection Engine] Update status on rule details page (elastic#55201)
  Fix KQL value suggestions for nested fields (elastic#54820)
  Enforce camelCase format for a plugin id (elastic#53759)
  [SIEM] Detection engine cleanup for rule details/creation/edit page (elastic#55069)
  Remove nested root from index pattern (elastic#54978)
  [Reporting/Migration] ReportingSetup, LegacySetup (elastic#54198)
  [SIEM] [Detection Engine] Fixes duplicate rule action (elastic#55252)
  [SIEM] Detections add alert & signal tab (elastic#55127)
  Management API - redirect on disabled app path (elastic#55136)
  [SIEM][Detection Engine] Fixes critical regression on the backend with immutable and tags
  ...
oatkiller pushed a commit to oatkiller/kibana that referenced this pull request Feb 18, 2020
This was already backported, but changes to endpoint app could not be
backported, since endpoint app itself hadn't been backported. Now that
the endpoint app is backported, reapply the endpoint specific changes
from the original commit.
oatkiller pushed a commit that referenced this pull request Feb 18, 2020
* Add Endpoint plugin and Resolver embeddable (#51994)

* Add functional tests for plugins to x-pack (so we can do a functional test of the Resolver embeddable)
* Add Endpoint plugin
* Add Resolver embeddable
* Test that Resolver embeddable can be rendered

 Conflicts:
	x-pack/.i18nrc.json
	x-pack/test/api_integration/apis/index.js

* [Endpoint] Register endpoint app (#53527)

* register app, create functional test

* formatting

* update tests

* adjust test data for endpoint

* add endpoint tests for testing spaces, app enabled, disabled, etc

* linting

* add read privileges to endpoint

* rename variable since its used now

* remove deprecated context

* remove unused variable

* fix type check

* correct test suite message

Co-Authored-By: Larry Gregory <lgregorydev@gmail.com>

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Larry Gregory <lgregorydev@gmail.com>

* [Endpoint] add react router to endpoint app (#53808)

* add react router to endpoint app

* linting

* linting

* linting

* correct tests

* change history from hash to browser, add new test util

* remove default values in helper functions

* fix type check, use FunctionComponent as oppsed to FC

* use BrowserRouter component

* use BrowserRouter component lin

* add comments to test framework, change function name to include browserHistory

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

* EMT-issue-65: add endpoint list api (#53861)

add endpoint list api

* EMT-65:always return accurate endpoint count (#54423)

EMT-65:always return accurate endpoint count, independent of paging properties

* Resolver component w/ sample data (#53619)

Resolver is a map. It shows processes that ran on a computer. The processes are drawn as nodes and lines connect processes with their parents.

Resolver is not yet implemented in Kibana. This PR adds a 'map' type UX. The user can click and drag to pan the map and zoom using trackpad pinching (or ctrl and mousewheel.)

There is no code providing actual data. Sample data is included. The sample data is used to draw a map. The fundamental info needed is:

process names
the parent of a process
With this info we can topologically lay out the processes. The sample data isn't yet in a realistic format. We'll be fixing that soon.

Related issue: elastic/endpoint-app-team#30

* Resolver test plugin not using mount context. (#54933)

Mount context was deprecated. Use core.getStartServices() instead.

* Resolver nonlinear zoom (#54936)

* [Endpoint] add Redux saga Middleware and app Store (#53906)

* Added saga library
* Initialize endpoint app redux store

* Resolver is overflow: hidden to prevent obscured elements from showing up (#55076)

* [Endpoint] Fix saga to start only after store is created and stopped on app unmount (#55245)

- added `stop()`/`start()` methods to the Saga Middleware creator factory
- adjust tests based on changes
- changed application `renderApp` to stop sagas when react app is unmounted

* Resolver zoom, pan, and center controls (#55221)

* Resolver zoom, pan, and center controls

* add tests, fix north panning

* fix type issue

* update west and east panning to behave like google maps

* [Endpoint] FIX: Increase tests `sleep` default duration back to 100ms (#55492)

Revert `sleep()` default duration, in the saga tests, back to 100ms in order to prevent intermittent failures during CI runs.

Fixes #55464
Fixes #55465

* [Endpoint] EMT-65: make endpoint data types common, restructure (#54772)

[Endpoint] EMT-65: make endpoint data types common, use schema changes

* Basic Functionality Alert List (#55800)

* sets up initial grid and data type

* data feeds in from backend but doesnt update

* sample data feeding in correctly

* Fix combineReducers issue by importing Redux type from 'redux' package

* Add usePageId hook that fires action when user navigates to page

* Strict typing for middleware

* addresses comments and uses better types

* move types to common/types.ts

* Move types to endpoint/types.ts, address PR comments

blah 2

Co-authored-by: Pedro Jaramillo <peluja1012@gmail.com>

* [Endpoint] Add Endpoint Details route (#55746)

* Add Endpoint Details route

* add Endpoint Details tests

* sacrifices to the Type gods

* update to latest endpoint schema

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

* [Endpoint] EMT-67: add kql support for endpoint list (#56328)

[Endpoint] EMT-67: add kql support for endpoint list

* [Endpoint] ERT-82 ERT-83 ERT-84: Alert list API with pagination (#56538)

* ERT-82 ERT-83 ERT-84 (partial): Add Alert List API with pagination

* Better type safety for alert list API

* Add Test to Verify Endpoint App Landing Page (#57129)

 Conflicts:
	x-pack/test/functional/page_objects/index.ts

* fixes render bug in alert list (#57152)

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

* Resolver: Animate camera, add sidebar (#55590)

This PR adds a sidebar navigation. clicking the icons in the nav will focus the camera on the different nodes. There is an animation effect when the camera moves.

 Conflicts:
	yarn.lock

* [Endpoint] Task/basic endpoint list (#55623)

* Adds host management list to endpoint security plugin

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

* [Endpoint] Policy List UI route and initial view (#56918)

* Initial Policy List view

* Add `endpoint/policy` route and displays Policy List
* test cases (both unit and functional)

Does not yet interact with API (Ingest).

* Add ApplicationService app status management (#50223)

This was already backported, but changes to endpoint app could not be
backported, since endpoint app itself hadn't been backported. Now that
the endpoint app is backported, reapply the endpoint specific changes
from the original commit.

* Implements `getStartServices` on server-side (#55156)

This was already backported, but changes to endpoint app could not be
backported, since endpoint app itself hadn't been backported. Now that
the endpoint app is backported, reapply the endpoint specific changes
from the original commit.

* [ui/utils/query_string]: Remove unused methods & migrate apps to querystring lib (#56957)

This was already backported, but changes to endpoint app could not be
backported, since endpoint app itself hadn't been backported. Now that
the endpoint app is backported, reapply the endpoint specific changes
from the original commit.

Co-authored-by: Kevin Logan <56395104+kevinlog@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Larry Gregory <lgregorydev@gmail.com>
Co-authored-by: nnamdifrankie <56440728+nnamdifrankie@users.noreply.github.com>
Co-authored-by: Davis Plumlee <56367316+dplumlee@users.noreply.github.com>
Co-authored-by: Paul Tavares <56442535+paul-tavares@users.noreply.github.com>
Co-authored-by: Pedro Jaramillo <peluja1012@gmail.com>
Co-authored-by: Dan Panzarella <pzl@users.noreply.github.com>
Co-authored-by: Madison Caldwell <madison.rey.caldwell@gmail.com>
Co-authored-by: Charlie Pichette <56399229+charlie-pichette@users.noreply.github.com>
Co-authored-by: Candace Park <56409205+parkiino@users.noreply.github.com>
Co-authored-by: Pierre Gayvallet <pierre.gayvallet@gmail.com>
Co-authored-by: Alexey Antonov <alexwizp@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:New Platform release_note:plugin_api_changes Contains a Plugin API changes section for the breaking plugin API changes section. Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.7.0 v8.0.0
Projects
Development

Successfully merging this pull request may close these issues.

NP server setup APIs requiring access to start APIs
6 participants