From 4f271c0cbb8d33f2982ff8c3312bf65434c84b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Casper=20H=C3=BCbertz?= Date: Thu, 18 Jun 2020 15:32:26 +0200 Subject: [PATCH 1/5] [APM] Change the unsaved changes text color (#69493) Fixes dark mode issue where the text would render dark on a dark background. --- .../AgentConfigurationCreateEdit/SettingsPage/SettingsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/SettingsPage/SettingsPage.tsx b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/SettingsPage/SettingsPage.tsx index bbf3921b383fd..e2609f893dfa0 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/SettingsPage/SettingsPage.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/SettingsPage/SettingsPage.tsx @@ -223,7 +223,7 @@ export function SettingsPage({ }} > - + {i18n.translate('xpack.apm.unsavedChanges', { defaultMessage: '{unsavedChangesCount, plural, =0{0 unsaved changes} one {1 unsaved change} other {# unsaved changes}} ', From f33192d35f9d491b17ca364b84d02865f8d1beeb Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Thu, 18 Jun 2020 15:35:22 +0200 Subject: [PATCH 2/5] [refactor] remove drilldown plugin, move components to uiActionsEnhanced (#69403) * refactor: remove drilldown plugin by moving components to uiActionsEnhanced * fix * fix mistake in test * fix i18n --- src/dev/storybook/aliases.ts | 1 - .../lib/panel/panel_header/panel_header.tsx | 2 +- x-pack/.i18nrc.json | 1 - x-pack/plugins/dashboard_enhanced/kibana.json | 2 +- .../dashboard_enhanced/public/plugin.ts | 3 - .../flyout_create_drilldown.test.tsx | 6 +- .../flyout_create_drilldown.tsx | 4 +- .../flyout_edit_drilldown.test.tsx | 4 +- .../flyout_edit_drilldown.tsx | 4 +- x-pack/plugins/drilldowns/README.md | 3 - x-pack/plugins/drilldowns/kibana.json | 8 --- .../public/components/flyout_frame/i18n.ts | 15 ----- x-pack/plugins/drilldowns/public/index.ts | 18 ------ x-pack/plugins/drilldowns/public/mocks.ts | 30 ---------- x-pack/plugins/drilldowns/public/plugin.ts | 48 ---------------- .../translations/translations/ja-JP.json | 42 +++++++------- .../translations/translations/zh-CN.json | 42 +++++++------- ...nnected_flyout_manage_drilldowns.story.tsx | 29 ++++------ ...onnected_flyout_manage_drilldowns.test.tsx | 34 +++++------- .../connected_flyout_manage_drilldowns.tsx | 55 ++++++++----------- .../i18n.ts | 31 ++++++----- .../index.ts | 0 .../test_data.ts | 6 +- .../drilldown_hello_bar.story.tsx | 2 +- .../drilldown_hello_bar.tsx | 0 .../components/drilldown_hello_bar/i18n.ts | 6 +- .../components/drilldown_hello_bar/index.tsx | 0 .../flyout_drilldown_wizard.story.tsx | 6 +- .../flyout_drilldown_wizard.tsx | 2 +- .../flyout_drilldown_wizard/i18n.ts | 10 ++-- .../flyout_drilldown_wizard/index.ts | 0 .../flyout_frame/flyout_frame.story.tsx | 2 +- .../flyout_frame/flyout_frame.test.tsx | 2 +- .../components/flyout_frame/flyout_frame.tsx | 0 .../components/flyout_frame/i18n.ts | 21 +++++++ .../components/flyout_frame/index.tsx | 0 .../flyout_list_manage_drilldowns.story.tsx | 0 .../flyout_list_manage_drilldowns.tsx | 0 .../flyout_list_manage_drilldowns/i18n.ts | 2 +- .../flyout_list_manage_drilldowns/index.ts | 0 .../form_drilldown_wizard.story.tsx | 2 +- .../form_drilldown_wizard.test.tsx | 0 .../form_drilldown_wizard.tsx | 6 +- .../components/form_drilldown_wizard/i18n.ts | 6 +- .../form_drilldown_wizard/index.tsx | 0 .../public/drilldowns/components/index.ts} | 8 +-- .../components/list_manage_drilldowns/i18n.ts | 21 ++++--- .../list_manage_drilldowns/index.tsx | 0 .../list_manage_drilldowns.story.tsx | 0 .../list_manage_drilldowns.test.tsx | 0 .../list_manage_drilldowns.tsx | 0 .../public/drilldowns/index.ts | 1 + .../ui_actions_enhanced/public/mocks.ts | 1 + .../ui_actions_enhanced/public/plugin.ts | 13 ++++- .../ui_actions_enhanced/scripts/storybook.js | 5 +- 55 files changed, 194 insertions(+), 310 deletions(-) delete mode 100644 x-pack/plugins/drilldowns/README.md delete mode 100644 x-pack/plugins/drilldowns/kibana.json delete mode 100644 x-pack/plugins/drilldowns/public/components/flyout_frame/i18n.ts delete mode 100644 x-pack/plugins/drilldowns/public/index.ts delete mode 100644 x-pack/plugins/drilldowns/public/mocks.ts delete mode 100644 x-pack/plugins/drilldowns/public/plugin.ts rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx (62%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx (89%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx (86%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/connected_flyout_manage_drilldowns/i18n.ts (61%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/connected_flyout_manage_drilldowns/index.ts (100%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/connected_flyout_manage_drilldowns/test_data.ts (90%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/drilldown_hello_bar/drilldown_hello_bar.story.tsx (93%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/drilldown_hello_bar/drilldown_hello_bar.tsx (100%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/drilldown_hello_bar/i18n.ts (73%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/drilldown_hello_bar/index.tsx (100%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx (90%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx (98%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/flyout_drilldown_wizard/i18n.ts (62%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/flyout_drilldown_wizard/index.ts (100%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/flyout_frame/flyout_frame.story.tsx (97%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/flyout_frame/flyout_frame.test.tsx (98%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/flyout_frame/flyout_frame.tsx (100%) create mode 100644 x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/i18n.ts rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/flyout_frame/index.tsx (100%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/flyout_list_manage_drilldowns/flyout_list_manage_drilldowns.story.tsx (100%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/flyout_list_manage_drilldowns/flyout_list_manage_drilldowns.tsx (100%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/flyout_list_manage_drilldowns/i18n.ts (79%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/flyout_list_manage_drilldowns/index.ts (100%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/form_drilldown_wizard/form_drilldown_wizard.story.tsx (94%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/form_drilldown_wizard/form_drilldown_wizard.test.tsx (100%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/form_drilldown_wizard/form_drilldown_wizard.tsx (94%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/form_drilldown_wizard/i18n.ts (68%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/form_drilldown_wizard/index.tsx (100%) rename x-pack/plugins/{drilldowns/scripts/storybook.js => ui_actions_enhanced/public/drilldowns/components/index.ts} (53%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/list_manage_drilldowns/i18n.ts (54%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/list_manage_drilldowns/index.tsx (100%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/list_manage_drilldowns/list_manage_drilldowns.story.tsx (100%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/list_manage_drilldowns/list_manage_drilldowns.test.tsx (100%) rename x-pack/plugins/{drilldowns/public => ui_actions_enhanced/public/drilldowns}/components/list_manage_drilldowns/list_manage_drilldowns.tsx (100%) diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts index 2f785896da8d5..85bfd4a7a4d26 100644 --- a/src/dev/storybook/aliases.ts +++ b/src/dev/storybook/aliases.ts @@ -22,7 +22,6 @@ export const storybookAliases = { canvas: 'x-pack/plugins/canvas/scripts/storybook_new.js', codeeditor: 'src/plugins/kibana_react/public/code_editor/scripts/storybook.ts', dashboard_enhanced: 'x-pack/plugins/dashboard_enhanced/scripts/storybook.js', - drilldowns: 'x-pack/plugins/drilldowns/scripts/storybook.js', embeddable: 'src/plugins/embeddable/scripts/storybook.js', infra: 'x-pack/legacy/plugins/infra/scripts/storybook.js', security_solution: 'x-pack/plugins/security_solution/scripts/storybook.js', diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_header.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_header.tsx index 8ba7be7880a7b..7b66f29cc2726 100644 --- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_header.tsx +++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_header.tsx @@ -81,7 +81,7 @@ function renderNotifications( if (tooltip) { badge = ( - + {badge} ); diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index 21b2df3ba12f8..278968cb47231 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -13,7 +13,6 @@ "xpack.crossClusterReplication": "plugins/cross_cluster_replication", "xpack.dashboardMode": "legacy/plugins/dashboard_mode", "xpack.data": "plugins/data_enhanced", - "xpack.drilldowns": "plugins/drilldowns", "xpack.embeddableEnhanced": "plugins/embeddable_enhanced", "xpack.endpoint": "plugins/endpoint", "xpack.features": "plugins/features", diff --git a/x-pack/plugins/dashboard_enhanced/kibana.json b/x-pack/plugins/dashboard_enhanced/kibana.json index 37211ea537179..3a95419d2f2fe 100644 --- a/x-pack/plugins/dashboard_enhanced/kibana.json +++ b/x-pack/plugins/dashboard_enhanced/kibana.json @@ -3,6 +3,6 @@ "version": "kibana", "server": false, "ui": true, - "requiredPlugins": ["data", "uiActionsEnhanced", "drilldowns", "embeddable", "dashboard", "share"], + "requiredPlugins": ["data", "uiActionsEnhanced", "embeddable", "dashboard", "share"], "configPath": ["xpack", "dashboardEnhanced"] } diff --git a/x-pack/plugins/dashboard_enhanced/public/plugin.ts b/x-pack/plugins/dashboard_enhanced/public/plugin.ts index 413f5a7afe356..854a4964ffe15 100644 --- a/x-pack/plugins/dashboard_enhanced/public/plugin.ts +++ b/x-pack/plugins/dashboard_enhanced/public/plugin.ts @@ -10,12 +10,10 @@ import { EmbeddableSetup, EmbeddableStart } from '../../../../src/plugins/embedd import { DashboardDrilldownsService } from './services'; import { DataPublicPluginStart } from '../../../../src/plugins/data/public'; import { AdvancedUiActionsSetup, AdvancedUiActionsStart } from '../../ui_actions_enhanced/public'; -import { DrilldownsSetup, DrilldownsStart } from '../../drilldowns/public'; import { DashboardStart } from '../../../../src/plugins/dashboard/public'; export interface SetupDependencies { uiActionsEnhanced: AdvancedUiActionsSetup; - drilldowns: DrilldownsSetup; embeddable: EmbeddableSetup; share: SharePluginSetup; } @@ -23,7 +21,6 @@ export interface SetupDependencies { export interface StartDependencies { uiActionsEnhanced: AdvancedUiActionsStart; data: DataPublicPluginStart; - drilldowns: DrilldownsStart; embeddable: EmbeddableStart; share: SharePluginStart; dashboard: DashboardStart; diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.test.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.test.tsx index 5ec1b881317d6..712a46dc32e08 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.test.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.test.tsx @@ -9,13 +9,13 @@ import { OpenFlyoutAddDrilldownParams, } from './flyout_create_drilldown'; import { coreMock } from '../../../../../../../../src/core/public/mocks'; -import { drilldownsPluginMock } from '../../../../../../drilldowns/public/mocks'; import { ViewMode } from '../../../../../../../../src/plugins/embeddable/public'; import { TriggerContextMapping } from '../../../../../../../../src/plugins/ui_actions/public'; import { MockEmbeddable, enhanceEmbeddable } from '../test_helpers'; +import { uiActionsEnhancedPluginMock } from '../../../../../../ui_actions_enhanced/public/mocks'; const overlays = coreMock.createStart().overlays; -const drilldowns = drilldownsPluginMock.createStartContract(); +const uiActionsEnhanced = uiActionsEnhancedPluginMock.createStartContract(); const actionParams: OpenFlyoutAddDrilldownParams = { start: () => ({ @@ -23,7 +23,7 @@ const actionParams: OpenFlyoutAddDrilldownParams = { overlays, } as any, plugins: { - drilldowns, + uiActionsEnhanced, }, self: {}, }), diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.tsx index 326cd551c7f84..4804a700c6cff 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.tsx @@ -16,7 +16,7 @@ import { StartServicesGetter } from '../../../../../../../../src/plugins/kibana_ export const OPEN_FLYOUT_ADD_DRILLDOWN = 'OPEN_FLYOUT_ADD_DRILLDOWN'; export interface OpenFlyoutAddDrilldownParams { - start: StartServicesGetter>; + start: StartServicesGetter>; } export class FlyoutCreateDrilldownAction implements ActionByType { @@ -62,7 +62,7 @@ export class FlyoutCreateDrilldownAction implements ActionByType handle.close()} viewMode={'create'} dynamicActionManager={embeddable.enhancements.dynamicActions} diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.test.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.test.tsx index 309e6cbf53a3d..b9ae45c2853c3 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.test.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.test.tsx @@ -6,14 +6,12 @@ import { FlyoutEditDrilldownAction, FlyoutEditDrilldownParams } from './flyout_edit_drilldown'; import { coreMock } from '../../../../../../../../src/core/public/mocks'; -import { drilldownsPluginMock } from '../../../../../../drilldowns/public/mocks'; import { ViewMode } from '../../../../../../../../src/plugins/embeddable/public'; import { uiActionsEnhancedPluginMock } from '../../../../../../ui_actions_enhanced/public/mocks'; import { EnhancedEmbeddable } from '../../../../../../embeddable_enhanced/public'; import { MockEmbeddable, enhanceEmbeddable } from '../test_helpers'; const overlays = coreMock.createStart().overlays; -const drilldowns = drilldownsPluginMock.createStartContract(); const uiActionsPlugin = uiActionsEnhancedPluginMock.createPlugin(); const uiActions = uiActionsPlugin.doStart(); @@ -32,7 +30,7 @@ const actionParams: FlyoutEditDrilldownParams = { overlays, } as any, plugins: { - drilldowns, + uiActionsEnhanced: uiActions, }, self: {}, }), diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.tsx index 5d2a90fdaff08..af1ae67454463 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.tsx @@ -20,7 +20,7 @@ import { StartServicesGetter } from '../../../../../../../../src/plugins/kibana_ export const OPEN_FLYOUT_EDIT_DRILLDOWN = 'OPEN_FLYOUT_EDIT_DRILLDOWN'; export interface FlyoutEditDrilldownParams { - start: StartServicesGetter>; + start: StartServicesGetter>; } export class FlyoutEditDrilldownAction implements ActionByType { @@ -58,7 +58,7 @@ export class FlyoutEditDrilldownAction implements ActionByType handle.close()} viewMode={'manage'} dynamicActionManager={embeddable.enhancements.dynamicActions} diff --git a/x-pack/plugins/drilldowns/README.md b/x-pack/plugins/drilldowns/README.md deleted file mode 100644 index 701b6082d4985..0000000000000 --- a/x-pack/plugins/drilldowns/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Drilldowns - -Provides functionality to navigate between Kibana apps with context information. diff --git a/x-pack/plugins/drilldowns/kibana.json b/x-pack/plugins/drilldowns/kibana.json deleted file mode 100644 index 1614f94b488fd..0000000000000 --- a/x-pack/plugins/drilldowns/kibana.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "id": "drilldowns", - "version": "kibana", - "server": false, - "ui": true, - "requiredPlugins": ["uiActions", "embeddable", "uiActionsEnhanced"], - "configPath": ["xpack", "drilldowns"] -} diff --git a/x-pack/plugins/drilldowns/public/components/flyout_frame/i18n.ts b/x-pack/plugins/drilldowns/public/components/flyout_frame/i18n.ts deleted file mode 100644 index 23af89ebf9bc7..0000000000000 --- a/x-pack/plugins/drilldowns/public/components/flyout_frame/i18n.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * 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 { i18n } from '@kbn/i18n'; - -export const txtClose = i18n.translate('xpack.drilldowns.components.FlyoutFrame.CloseButtonLabel', { - defaultMessage: 'Close', -}); - -export const txtBack = i18n.translate('xpack.drilldowns.components.FlyoutFrame.BackButtonLabel', { - defaultMessage: 'Back', -}); diff --git a/x-pack/plugins/drilldowns/public/index.ts b/x-pack/plugins/drilldowns/public/index.ts deleted file mode 100644 index f976356822dce..0000000000000 --- a/x-pack/plugins/drilldowns/public/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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 { DrilldownsPlugin } from './plugin'; - -export { - SetupContract as DrilldownsSetup, - SetupDependencies as DrilldownsSetupDependencies, - StartContract as DrilldownsStart, - StartDependencies as DrilldownsStartDependencies, -} from './plugin'; - -export function plugin() { - return new DrilldownsPlugin(); -} diff --git a/x-pack/plugins/drilldowns/public/mocks.ts b/x-pack/plugins/drilldowns/public/mocks.ts deleted file mode 100644 index 18816243a3572..0000000000000 --- a/x-pack/plugins/drilldowns/public/mocks.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 { DrilldownsSetup, DrilldownsStart } from '.'; - -export type Setup = jest.Mocked; -export type Start = jest.Mocked; - -const createSetupContract = (): Setup => { - const setupContract: Setup = { - registerDrilldown: jest.fn(), - }; - return setupContract; -}; - -const createStartContract = (): Start => { - const startContract: Start = { - FlyoutManageDrilldowns: jest.fn(), - }; - - return startContract; -}; - -export const drilldownsPluginMock = { - createSetupContract, - createStartContract, -}; diff --git a/x-pack/plugins/drilldowns/public/plugin.ts b/x-pack/plugins/drilldowns/public/plugin.ts deleted file mode 100644 index 2805e2b747934..0000000000000 --- a/x-pack/plugins/drilldowns/public/plugin.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 { CoreStart, CoreSetup, Plugin } from 'src/core/public'; -import { UiActionsSetup, UiActionsStart } from '../../../../src/plugins/ui_actions/public'; -import { AdvancedUiActionsSetup, AdvancedUiActionsStart } from '../../ui_actions_enhanced/public'; -import { createFlyoutManageDrilldowns } from './components/connected_flyout_manage_drilldowns'; -import { Storage } from '../../../../src/plugins/kibana_utils/public'; - -export interface SetupDependencies { - uiActions: UiActionsSetup; - uiActionsEnhanced: AdvancedUiActionsSetup; -} - -export interface StartDependencies { - uiActions: UiActionsStart; - uiActionsEnhanced: AdvancedUiActionsStart; -} - -// eslint-disable-next-line -export interface SetupContract {} - -export interface StartContract { - FlyoutManageDrilldowns: ReturnType; -} - -export class DrilldownsPlugin - implements Plugin { - public setup(core: CoreSetup, plugins: SetupDependencies): SetupContract { - return {}; - } - - public start(core: CoreStart, plugins: StartDependencies): StartContract { - return { - FlyoutManageDrilldowns: createFlyoutManageDrilldowns({ - uiActionsEnhanced: plugins.uiActionsEnhanced, - storage: new Storage(localStorage), - notifications: core.notifications, - docsLink: core.docLinks.links.dashboard.drilldowns, - }), - }; - } - - public stop() {} -} diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 7b887867b43b8..37cdbf5c0d8a9 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -3970,6 +3970,27 @@ "xpack.uiActionsEnhanced.customizeTimeRangeMenuItem.displayName": "時間範囲のカスタマイズ", "xpack.uiActionsEnhanced.components.DiscoverDrilldownConfig.chooseIndexPattern": "対象インデックスパターンを選択", "xpack.uiActionsEnhanced.drilldown.goToDiscover": "Discoverに移動(例)", + "xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.helpText": "ドロップダウンを使用すると、パネルを操作するときに、新しい動作を定義できます。複数のオプションを追加するか、既定のフィルタリング動作を上書きできます。", + "xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.hideHelpButtonLabel": "非表示", + "xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.viewDocsLinkLabel": "ドキュメントを表示", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.createDrilldownButtonLabel": "ドリルダウンを作成", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.createDrilldownTitle": "ドリルダウンを作成", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.deleteDrilldownButtonLabel": "ドリルダウンを削除", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.editDrilldownButtonLabel": "保存", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.editDrilldownTitle": "ドリルダウンを編集", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedText": "ドリルダウンを削除しました。", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedTitle": "ドリルダウンが削除されました", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsCRUDErrorTitle": "ドリルダウンの保存エラー", + "xpack.uiActionsEnhanced.drilldowns.components.FlyoutFrame.BackButtonLabel": "戻る", + "xpack.uiActionsEnhanced.drilldowns.components.FlyoutFrame.CloseButtonLabel": "閉じる", + "xpack.uiActionsEnhanced.drilldowns.components.FlyoutListManageDrilldowns.manageDrilldownsTitle": "ドリルダウンを管理", + "xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.drilldownAction": "アクション", + "xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.nameOfDrilldown": "名前", + "xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.untitledDrilldown": "無題のドリルダウン", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.createDrilldownButtonLabel": "新規作成...", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.deleteDrilldownsButtonLabel": "削除({count})", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.editDrilldownButtonLabel": "編集", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.selectThisDrilldownCheckboxLabel": "このドリルダウンを選択", "xpack.alerts.alertNavigationRegistry.get.missingNavigationError": "「{consumer}」内のアラートタイプ「{alertType}」のナビゲーションは登録されていません。", "xpack.alerts.alertNavigationRegistry.register.duplicateDefaultError": "「{consumer}」内のデフォルトナビゲーションは既に登録されています。", "xpack.alerts.alertNavigationRegistry.register.duplicateNavigationError": "「{consumer}」内のアラートタイプ「{alertType}」のナビゲーションは既に登録されています。", @@ -6122,27 +6143,6 @@ "xpack.data.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText": "1つ以上の引数", "xpack.data.query.queryBar.cancelLongQuery": "キャンセル", "xpack.data.query.queryBar.runBeyond": "タイムアウトを越えて実行", - "xpack.drilldowns.components.DrilldownHelloBar.helpText": "ドロップダウンを使用すると、パネルを操作するときに、新しい動作を定義できます。複数のオプションを追加するか、既定のフィルタリング動作を上書きできます。", - "xpack.drilldowns.components.DrilldownHelloBar.hideHelpButtonLabel": "非表示", - "xpack.drilldowns.components.DrilldownHelloBar.viewDocsLinkLabel": "ドキュメントを表示", - "xpack.drilldowns.components.flyoutDrilldownWizard.createDrilldownButtonLabel": "ドリルダウンを作成", - "xpack.drilldowns.components.flyoutDrilldownWizard.createDrilldownTitle": "ドリルダウンを作成", - "xpack.drilldowns.components.flyoutDrilldownWizard.deleteDrilldownButtonLabel": "ドリルダウンを削除", - "xpack.drilldowns.components.flyoutDrilldownWizard.editDrilldownButtonLabel": "保存", - "xpack.drilldowns.components.flyoutDrilldownWizard.editDrilldownTitle": "ドリルダウンを編集", - "xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedText": "ドリルダウンを削除しました。", - "xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedTitle": "ドリルダウンが削除されました", - "xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsCRUDErrorTitle": "ドリルダウンの保存エラー", - "xpack.drilldowns.components.FlyoutFrame.BackButtonLabel": "戻る", - "xpack.drilldowns.components.FlyoutFrame.CloseButtonLabel": "閉じる", - "xpack.drilldowns.components.FlyoutListManageDrilldowns.manageDrilldownsTitle": "ドリルダウンを管理", - "xpack.drilldowns.components.FormCreateDrilldown.drilldownAction": "アクション", - "xpack.drilldowns.components.FormCreateDrilldown.nameOfDrilldown": "名前", - "xpack.drilldowns.components.FormCreateDrilldown.untitledDrilldown": "無題のドリルダウン", - "xpack.drilldowns.components.ListManageDrilldowns.createDrilldownButtonLabel": "新規作成...", - "xpack.drilldowns.components.ListManageDrilldowns.deleteDrilldownsButtonLabel": "削除({count})", - "xpack.drilldowns.components.ListManageDrilldowns.editDrilldownButtonLabel": "編集", - "xpack.drilldowns.components.ListManageDrilldowns.selectThisDrilldownCheckboxLabel": "このドリルダウンを選択", "xpack.features.advancedSettingsFeatureName": "高度な設定", "xpack.features.dashboardFeatureName": "ダッシュボード", "xpack.features.devToolsFeatureName": "開発ツール", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index e821c4fb22899..2dfa0d40b9a8a 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -3973,6 +3973,27 @@ "xpack.uiActionsEnhanced.customizeTimeRangeMenuItem.displayName": "定制时间范围", "xpack.uiActionsEnhanced.components.DiscoverDrilldownConfig.chooseIndexPattern": "选择目标索引模式", "xpack.uiActionsEnhanced.drilldown.goToDiscover": "前往 Discover(示例)", + "xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.helpText": "向下钻取可用于定义与面板交互时的新行为。可以添加多个选项或仅覆盖默认筛选行为。", + "xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.hideHelpButtonLabel": "隐藏", + "xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.viewDocsLinkLabel": "查看文档", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.createDrilldownButtonLabel": "创建向下钻取", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.createDrilldownTitle": "创建向下钻取", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.deleteDrilldownButtonLabel": "删除向下钻取", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.editDrilldownButtonLabel": "保存", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.editDrilldownTitle": "编辑向下钻取", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedText": "您已删除向下钻取。", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedTitle": "向下钻取已删除", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsCRUDErrorTitle": "保存向下钻取时出错", + "xpack.uiActionsEnhanced.drilldowns.components.FlyoutFrame.BackButtonLabel": "上一步", + "xpack.uiActionsEnhanced.drilldowns.components.FlyoutFrame.CloseButtonLabel": "关闭", + "xpack.uiActionsEnhanced.drilldowns.components.FlyoutListManageDrilldowns.manageDrilldownsTitle": "管理向下钻取", + "xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.drilldownAction": "操作", + "xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.nameOfDrilldown": "名称", + "xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.untitledDrilldown": "未命名向下钻取", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.createDrilldownButtonLabel": "新建", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.deleteDrilldownsButtonLabel": "删除 ({count})", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.editDrilldownButtonLabel": "编辑", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.selectThisDrilldownCheckboxLabel": "选择此向下钻取", "xpack.alerts.alertNavigationRegistry.get.missingNavigationError": "在“{consumer}”内针对告警类型“{alertType}”的导航未注册。", "xpack.alerts.alertNavigationRegistry.register.duplicateDefaultError": "“{consumer}”内的默认导航已注册。", "xpack.alerts.alertNavigationRegistry.register.duplicateNavigationError": "在“{consumer}”内针对告警类型“{alertType}”的导航已注册。", @@ -6125,27 +6146,6 @@ "xpack.data.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText": "一个或多个参数", "xpack.data.query.queryBar.cancelLongQuery": "取消", "xpack.data.query.queryBar.runBeyond": "运行超时", - "xpack.drilldowns.components.DrilldownHelloBar.helpText": "向下钻取可用于定义与面板交互时的新行为。可以添加多个选项或仅覆盖默认筛选行为。", - "xpack.drilldowns.components.DrilldownHelloBar.hideHelpButtonLabel": "隐藏", - "xpack.drilldowns.components.DrilldownHelloBar.viewDocsLinkLabel": "查看文档", - "xpack.drilldowns.components.flyoutDrilldownWizard.createDrilldownButtonLabel": "创建向下钻取", - "xpack.drilldowns.components.flyoutDrilldownWizard.createDrilldownTitle": "创建向下钻取", - "xpack.drilldowns.components.flyoutDrilldownWizard.deleteDrilldownButtonLabel": "删除向下钻取", - "xpack.drilldowns.components.flyoutDrilldownWizard.editDrilldownButtonLabel": "保存", - "xpack.drilldowns.components.flyoutDrilldownWizard.editDrilldownTitle": "编辑向下钻取", - "xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedText": "您已删除向下钻取。", - "xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedTitle": "向下钻取已删除", - "xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsCRUDErrorTitle": "保存向下钻取时出错", - "xpack.drilldowns.components.FlyoutFrame.BackButtonLabel": "上一步", - "xpack.drilldowns.components.FlyoutFrame.CloseButtonLabel": "关闭", - "xpack.drilldowns.components.FlyoutListManageDrilldowns.manageDrilldownsTitle": "管理向下钻取", - "xpack.drilldowns.components.FormCreateDrilldown.drilldownAction": "操作", - "xpack.drilldowns.components.FormCreateDrilldown.nameOfDrilldown": "名称", - "xpack.drilldowns.components.FormCreateDrilldown.untitledDrilldown": "未命名向下钻取", - "xpack.drilldowns.components.ListManageDrilldowns.createDrilldownButtonLabel": "新建", - "xpack.drilldowns.components.ListManageDrilldowns.deleteDrilldownsButtonLabel": "删除 ({count})", - "xpack.drilldowns.components.ListManageDrilldowns.editDrilldownButtonLabel": "编辑", - "xpack.drilldowns.components.ListManageDrilldowns.selectThisDrilldownCheckboxLabel": "选择此向下钻取", "xpack.features.advancedSettingsFeatureName": "高级设置", "xpack.features.dashboardFeatureName": "仪表板", "xpack.features.devToolsFeatureName": "开发工具", diff --git a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx similarity index 62% rename from x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx index 5fde4fc79e433..cd8452ff74ab4 100644 --- a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx @@ -12,28 +12,23 @@ import { dashboardFactory, urlFactory, // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../ui_actions_enhanced/public/components/action_wizard/test_data'; -import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; -import { StubBrowserStorage } from '../../../../../../src/test_utils/public/stub_browser_storage'; +} from '../../../components/action_wizard/test_data'; +import { Storage } from '../../../../../../../src/plugins/kibana_utils/public'; +import { StubBrowserStorage } from '../../../../../../../src/test_utils/public/stub_browser_storage'; import { mockDynamicActionManager } from './test_data'; +import { ActionFactory } from '../../../dynamic_actions'; const FlyoutManageDrilldowns = createFlyoutManageDrilldowns({ - uiActionsEnhanced: { - getActionFactories() { - return [dashboardFactory, urlFactory]; + actionFactories: [dashboardFactory as ActionFactory, urlFactory as ActionFactory], + storage: new Storage(new StubBrowserStorage()), + toastService: { + addError: (...args: any[]) => { + alert(JSON.stringify(args)); + }, + addSuccess: (...args: any[]) => { + alert(JSON.stringify(args)); }, } as any, - storage: new Storage(new StubBrowserStorage()), - notifications: { - toasts: { - addError: (...args: any[]) => { - alert(JSON.stringify(args)); - }, - addSuccess: (...args: any[]) => { - alert(JSON.stringify(args)); - }, - } as any, - }, }); storiesOf('components/FlyoutManageDrilldowns', module).add('default', () => ( diff --git a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx similarity index 89% rename from x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx index 32cbec795d092..161caa9782f02 100644 --- a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx @@ -8,29 +8,23 @@ import React from 'react'; import { cleanup, fireEvent, render, wait } from '@testing-library/react/pure'; import '@testing-library/jest-dom/extend-expect'; import { createFlyoutManageDrilldowns } from './connected_flyout_manage_drilldowns'; -import { - dashboardFactory, - urlFactory, -} from '../../../../ui_actions_enhanced/public/components/action_wizard/test_data'; -import { StubBrowserStorage } from '../../../../../../src/test_utils/public/stub_browser_storage'; -import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; +import { dashboardFactory, urlFactory } from '../../../components/action_wizard/test_data'; +import { StubBrowserStorage } from '../../../../../../../src/test_utils/public/stub_browser_storage'; +import { Storage } from '../../../../../../../src/plugins/kibana_utils/public'; import { mockDynamicActionManager } from './test_data'; import { TEST_SUBJ_DRILLDOWN_ITEM } from '../list_manage_drilldowns'; import { WELCOME_MESSAGE_TEST_SUBJ } from '../drilldown_hello_bar'; -import { coreMock } from '../../../../../../src/core/public/mocks'; +import { coreMock } from '../../../../../../../src/core/public/mocks'; import { NotificationsStart } from 'kibana/public'; import { toastDrilldownsCRUDError } from './i18n'; +import { ActionFactory } from '../../../dynamic_actions'; const storage = new Storage(new StubBrowserStorage()); -const notifications = coreMock.createStart().notifications; +const toasts = coreMock.createStart().notifications.toasts; const FlyoutManageDrilldowns = createFlyoutManageDrilldowns({ - uiActionsEnhanced: { - getActionFactories() { - return [dashboardFactory, urlFactory]; - }, - } as any, - storage, - notifications, + actionFactories: [dashboardFactory as ActionFactory, urlFactory as ActionFactory], + storage: new Storage(new StubBrowserStorage()), + toastService: toasts, }); // https://github.com/elastic/kibana/issues/59469 @@ -38,8 +32,8 @@ afterEach(cleanup); beforeEach(() => { storage.clear(); - (notifications.toasts as jest.Mocked).addSuccess.mockClear(); - (notifications.toasts as jest.Mocked).addError.mockClear(); + (toasts as jest.Mocked).addSuccess.mockClear(); + (toasts as jest.Mocked).addError.mockClear(); }); test('Allows to manage drilldowns', async () => { @@ -163,7 +157,7 @@ test('Create only mode', async () => { }); fireEvent.click(screen.getAllByText(/Create Drilldown/i)[1]); - await wait(() => expect(notifications.toasts.addSuccess).toBeCalled()); + await wait(() => expect(toasts.addSuccess).toBeCalled()); expect(onClose).toBeCalled(); expect(await mockDynamicActionManager.state.get().events.length).toBe(1); }); @@ -194,7 +188,7 @@ test('After switching between action factories state is restored', async () => { expect(screen.getByLabelText(/name/i)).toHaveValue('test'); fireEvent.click(screen.getAllByText(/Create Drilldown/i)[1]); - await wait(() => expect(notifications.toasts.addSuccess).toBeCalled()); + await wait(() => expect(toasts.addSuccess).toBeCalled()); expect(await (mockDynamicActionManager.state.get().events[0].action.config as any).url).toBe( 'https://elastic.co' ); @@ -220,7 +214,7 @@ test("Error when can't save drilldown changes", async () => { }); fireEvent.click(screen.getAllByText(/Create Drilldown/i)[1]); await wait(() => - expect(notifications.toasts.addError).toBeCalledWith(error, { title: toastDrilldownsCRUDError }) + expect(toasts.addError).toBeCalledWith(error, { title: toastDrilldownsCRUDError }) ); }); diff --git a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx similarity index 86% rename from x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx index e05547741871e..fbc72d0470635 100644 --- a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx @@ -5,24 +5,17 @@ */ import React, { useEffect, useState } from 'react'; +import { ToastsStart } from 'kibana/public'; import useMountedState from 'react-use/lib/useMountedState'; -import { - UiActionsEnhancedActionFactory as ActionFactory, - AdvancedUiActionsStart, - UiActionsEnhancedDynamicActionManager as DynamicActionManager, - UiActionsEnhancedSerializedAction, - UiActionsEnhancedSerializedEvent, -} from '../../../../ui_actions_enhanced/public'; -import { NotificationsStart } from '../../../../../../src/core/public'; import { DrilldownWizardConfig, FlyoutDrilldownWizard } from '../flyout_drilldown_wizard'; import { FlyoutListManageDrilldowns } from '../flyout_list_manage_drilldowns'; -import { IStorageWrapper } from '../../../../../../src/plugins/kibana_utils/public'; +import { IStorageWrapper } from '../../../../../../../src/plugins/kibana_utils/public'; import { VALUE_CLICK_TRIGGER, SELECT_RANGE_TRIGGER, TriggerContextMapping, -} from '../../../../../../src/plugins/ui_actions/public'; -import { useContainerState } from '../../../../../../src/plugins/kibana_utils/public'; +} from '../../../../../../../src/plugins/ui_actions/public'; +import { useContainerState } from '../../../../../../../src/plugins/kibana_utils/public'; import { DrilldownListItem } from '../list_manage_drilldowns'; import { toastDrilldownCreated, @@ -31,6 +24,12 @@ import { toastDrilldownsCRUDError, toastDrilldownsDeleted, } from './i18n'; +import { + ActionFactory, + DynamicActionManager, + SerializedAction, + SerializedEvent, +} from '../../../dynamic_actions'; interface ConnectedFlyoutManageDrilldownsProps { dynamicActionManager: DynamicActionManager; @@ -48,19 +47,16 @@ enum Routes { } export function createFlyoutManageDrilldowns({ - uiActionsEnhanced, + actionFactories: allActionFactories, storage, - notifications, + toastService, docsLink, }: { - uiActionsEnhanced: AdvancedUiActionsStart; + actionFactories: ActionFactory[]; storage: IStorageWrapper; - notifications: NotificationsStart; + toastService: ToastsStart; docsLink?: string; }) { - // fine to assume this is static, - // because all action factories should be registered in setup phase - const allActionFactories = uiActionsEnhanced.getActionFactories(); const allActionFactoriesById = allActionFactories.reduce((acc, next) => { acc[next.id] = next; return acc; @@ -98,7 +94,7 @@ export function createFlyoutManageDrilldowns({ createDrilldown, editDrilldown, deleteDrilldown, - } = useDrilldownsStateManager(props.dynamicActionManager, notifications); + } = useDrilldownsStateManager(props.dynamicActionManager, toastService); /** * isCompatible promise is not yet resolved. @@ -130,9 +126,7 @@ export function createFlyoutManageDrilldowns({ /** * Maps drilldown to list item view model */ - function mapToDrilldownToDrilldownListItem( - drilldown: UiActionsEnhancedSerializedEvent - ): DrilldownListItem { + function mapToDrilldownToDrilldownListItem(drilldown: SerializedEvent): DrilldownListItem { const actionFactory = allActionFactoriesById[drilldown.action.factoryId]; return { id: drilldown.eventId, @@ -260,10 +254,7 @@ function useWelcomeMessage(storage: IStorageWrapper): [boolean, () => void] { ]; } -function useDrilldownsStateManager( - actionManager: DynamicActionManager, - notifications: NotificationsStart -) { +function useDrilldownsStateManager(actionManager: DynamicActionManager, toastService: ToastsStart) { const { events: drilldowns } = useContainerState(actionManager.state); const [isLoading, setIsLoading] = useState(false); const isMounted = useMountedState(); @@ -273,7 +264,7 @@ function useDrilldownsStateManager( try { await op(); } catch (e) { - notifications.toasts.addError(e, { + toastService.addError(e, { title: toastDrilldownsCRUDError, }); if (!isMounted) return; @@ -283,12 +274,12 @@ function useDrilldownsStateManager( } async function createDrilldown( - action: UiActionsEnhancedSerializedAction, + action: SerializedAction, selectedTriggers: Array ) { await run(async () => { await actionManager.createEvent(action, selectedTriggers); - notifications.toasts.addSuccess({ + toastService.addSuccess({ title: toastDrilldownCreated.title(action.name), text: toastDrilldownCreated.text, }); @@ -297,12 +288,12 @@ function useDrilldownsStateManager( async function editDrilldown( drilldownId: string, - action: UiActionsEnhancedSerializedAction, + action: SerializedAction, selectedTriggers: Array ) { await run(async () => { await actionManager.updateEvent(drilldownId, action, selectedTriggers); - notifications.toasts.addSuccess({ + toastService.addSuccess({ title: toastDrilldownEdited.title(action.name), text: toastDrilldownEdited.text, }); @@ -313,7 +304,7 @@ function useDrilldownsStateManager( await run(async () => { drilldownIds = Array.isArray(drilldownIds) ? drilldownIds : [drilldownIds]; await actionManager.deleteEvents(drilldownIds); - notifications.toasts.addSuccess( + toastService.addSuccess( drilldownIds.length === 1 ? { title: toastDrilldownDeleted.title, diff --git a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/i18n.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/i18n.ts similarity index 61% rename from x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/i18n.ts rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/i18n.ts index 851439eccbe7e..e75ee2634aa43 100644 --- a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/i18n.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/i18n.ts @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; export const toastDrilldownCreated = { title: (drilldownName: string) => i18n.translate( - 'xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownCreatedTitle', + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownCreatedTitle', { defaultMessage: 'Drilldown "{drilldownName}" created', values: { @@ -18,7 +18,7 @@ export const toastDrilldownCreated = { } ), text: i18n.translate( - 'xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownCreatedText', + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownCreatedText', { // TODO: remove `Save your dashboard before testing.` part // when drilldowns are used not only in dashboard @@ -30,14 +30,17 @@ export const toastDrilldownCreated = { export const toastDrilldownEdited = { title: (drilldownName: string) => - i18n.translate('xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownEditedTitle', { - defaultMessage: 'Drilldown "{drilldownName}" updated', - values: { - drilldownName, - }, - }), + i18n.translate( + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownEditedTitle', + { + defaultMessage: 'Drilldown "{drilldownName}" updated', + values: { + drilldownName, + }, + } + ), text: i18n.translate( - 'xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownEditedText', + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownEditedText', { defaultMessage: 'Save your dashboard before testing.', } @@ -46,13 +49,13 @@ export const toastDrilldownEdited = { export const toastDrilldownDeleted = { title: i18n.translate( - 'xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedTitle', + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedTitle', { defaultMessage: 'Drilldown deleted', } ), text: i18n.translate( - 'xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedText', + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedText', { defaultMessage: 'Save your dashboard before testing.', } @@ -62,14 +65,14 @@ export const toastDrilldownDeleted = { export const toastDrilldownsDeleted = { title: (n: number) => i18n.translate( - 'xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsDeletedTitle', + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsDeletedTitle', { defaultMessage: '{n} drilldowns deleted', values: { n }, } ), text: i18n.translate( - 'xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsDeletedText', + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsDeletedText', { defaultMessage: 'Save your dashboard before testing.', } @@ -77,7 +80,7 @@ export const toastDrilldownsDeleted = { }; export const toastDrilldownsCRUDError = i18n.translate( - 'xpack.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsCRUDErrorTitle', + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsCRUDErrorTitle', { defaultMessage: 'Error saving drilldown', description: 'Title for generic error toast when persisting drilldown updates failed', diff --git a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/index.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/index.ts similarity index 100% rename from x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/index.ts rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/index.ts diff --git a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/test_data.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/test_data.ts similarity index 90% rename from x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/test_data.ts rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/test_data.ts index d585fa0692e8c..58c36e36481b8 100644 --- a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/test_data.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/connected_flyout_manage_drilldowns/test_data.ts @@ -9,9 +9,9 @@ import { UiActionsEnhancedDynamicActionManager as DynamicActionManager, UiActionsEnhancedDynamicActionManagerState as DynamicActionManagerState, UiActionsEnhancedSerializedAction, -} from '../../../../ui_actions_enhanced/public'; -import { TriggerContextMapping } from '../../../../../../src/plugins/ui_actions/public'; -import { createStateContainer } from '../../../../../../src/plugins/kibana_utils/common'; +} from '../../../index'; +import { TriggerContextMapping } from '../../../../../../../src/plugins/ui_actions/public'; +import { createStateContainer } from '../../../../../../../src/plugins/kibana_utils/common'; class MockDynamicActionManager implements PublicMethodsOf { public readonly state = createStateContainer({ diff --git a/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/drilldown_hello_bar.story.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/drilldown_hello_bar/drilldown_hello_bar.story.tsx similarity index 93% rename from x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/drilldown_hello_bar.story.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/drilldown_hello_bar/drilldown_hello_bar.story.tsx index c4a4630397f1c..df168275fceb3 100644 --- a/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/drilldown_hello_bar.story.tsx +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/drilldown_hello_bar/drilldown_hello_bar.story.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { storiesOf } from '@storybook/react'; -import { DrilldownHelloBar } from '.'; +import { DrilldownHelloBar } from './index'; const Demo = () => { const [show, setShow] = React.useState(true); diff --git a/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/drilldown_hello_bar.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/drilldown_hello_bar/drilldown_hello_bar.tsx similarity index 100% rename from x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/drilldown_hello_bar.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/drilldown_hello_bar/drilldown_hello_bar.tsx diff --git a/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/i18n.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/drilldown_hello_bar/i18n.ts similarity index 73% rename from x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/i18n.ts rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/drilldown_hello_bar/i18n.ts index 622376c5b40ad..e857366690c45 100644 --- a/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/i18n.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/drilldown_hello_bar/i18n.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; export const txtHelpText = i18n.translate( - 'xpack.drilldowns.components.DrilldownHelloBar.helpText', + 'xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.helpText', { defaultMessage: 'Drilldowns enable you to define new behaviors for interacting with panels. You can add multiple actions and override the default filter.', @@ -15,14 +15,14 @@ export const txtHelpText = i18n.translate( ); export const txtViewDocsLinkLabel = i18n.translate( - 'xpack.drilldowns.components.DrilldownHelloBar.viewDocsLinkLabel', + 'xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.viewDocsLinkLabel', { defaultMessage: 'View docs', } ); export const txtHideHelpButtonLabel = i18n.translate( - 'xpack.drilldowns.components.DrilldownHelloBar.hideHelpButtonLabel', + 'xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.hideHelpButtonLabel', { defaultMessage: 'Hide', } diff --git a/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/index.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/drilldown_hello_bar/index.tsx similarity index 100% rename from x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/index.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/drilldown_hello_bar/index.tsx diff --git a/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx similarity index 90% rename from x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx index be048bf920602..2069a83ab8ba0 100644 --- a/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx @@ -9,13 +9,13 @@ import * as React from 'react'; import { EuiFlyout } from '@elastic/eui'; import { storiesOf } from '@storybook/react'; -import { FlyoutDrilldownWizard } from '.'; +import { FlyoutDrilldownWizard } from './index'; import { dashboardFactory, urlFactory, // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../ui_actions_enhanced/public/components/action_wizard/test_data'; -import { UiActionsEnhancedActionFactory as ActionFactory } from '../../../../ui_actions_enhanced/public/'; +} from '../../../components/action_wizard/test_data'; +import { ActionFactory } from '../../../dynamic_actions'; storiesOf('components/FlyoutDrilldownWizard', module) .add('default', () => { diff --git a/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx similarity index 98% rename from x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx index 8994aac4123e1..58cf2501280c7 100644 --- a/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx @@ -16,7 +16,7 @@ import { txtEditDrilldownTitle, } from './i18n'; import { DrilldownHelloBar } from '../drilldown_hello_bar'; -import { UiActionsEnhancedActionFactory as ActionFactory } from '../../../../ui_actions_enhanced/public'; +import { ActionFactory } from '../../../dynamic_actions'; export interface DrilldownWizardConfig { name: string; diff --git a/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/i18n.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/i18n.ts similarity index 62% rename from x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/i18n.ts rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/i18n.ts index a4a2754a444ab..86485dd7b8bbe 100644 --- a/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/i18n.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/i18n.ts @@ -7,35 +7,35 @@ import { i18n } from '@kbn/i18n'; export const txtCreateDrilldownTitle = i18n.translate( - 'xpack.drilldowns.components.flyoutDrilldownWizard.createDrilldownTitle', + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.createDrilldownTitle', { defaultMessage: 'Create Drilldown', } ); export const txtEditDrilldownTitle = i18n.translate( - 'xpack.drilldowns.components.flyoutDrilldownWizard.editDrilldownTitle', + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.editDrilldownTitle', { defaultMessage: 'Edit Drilldown', } ); export const txtCreateDrilldownButtonLabel = i18n.translate( - 'xpack.drilldowns.components.flyoutDrilldownWizard.createDrilldownButtonLabel', + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.createDrilldownButtonLabel', { defaultMessage: 'Create drilldown', } ); export const txtEditDrilldownButtonLabel = i18n.translate( - 'xpack.drilldowns.components.flyoutDrilldownWizard.editDrilldownButtonLabel', + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.editDrilldownButtonLabel', { defaultMessage: 'Save', } ); export const txtDeleteDrilldownButtonLabel = i18n.translate( - 'xpack.drilldowns.components.flyoutDrilldownWizard.deleteDrilldownButtonLabel', + 'xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.deleteDrilldownButtonLabel', { defaultMessage: 'Delete drilldown', } diff --git a/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/index.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/index.ts similarity index 100% rename from x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/index.ts rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_drilldown_wizard/index.ts diff --git a/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.story.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/flyout_frame.story.tsx similarity index 97% rename from x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.story.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/flyout_frame.story.tsx index 7ef0bc5a8bee4..d47c34c4c7ec9 100644 --- a/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.story.tsx +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/flyout_frame.story.tsx @@ -9,7 +9,7 @@ import * as React from 'react'; import { EuiFlyout, EuiButton } from '@elastic/eui'; import { storiesOf } from '@storybook/react'; -import { FlyoutFrame } from '.'; +import { FlyoutFrame } from './index'; storiesOf('components/FlyoutFrame', module) .add('default', () => { diff --git a/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.test.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/flyout_frame.test.tsx similarity index 98% rename from x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.test.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/flyout_frame.test.tsx index 0a3989487745f..cdbf36d81de33 100644 --- a/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.test.tsx +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/flyout_frame.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { render } from 'react-dom'; import { render as renderTestingLibrary, fireEvent, cleanup } from '@testing-library/react/pure'; -import { FlyoutFrame } from '.'; +import { FlyoutFrame } from './index'; afterEach(cleanup); diff --git a/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/flyout_frame.tsx similarity index 100% rename from x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/flyout_frame.tsx diff --git a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/i18n.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/i18n.ts new file mode 100644 index 0000000000000..cf0cd95e25c79 --- /dev/null +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/i18n.ts @@ -0,0 +1,21 @@ +/* + * 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 { i18n } from '@kbn/i18n'; + +export const txtClose = i18n.translate( + 'xpack.uiActionsEnhanced.drilldowns.components.FlyoutFrame.CloseButtonLabel', + { + defaultMessage: 'Close', + } +); + +export const txtBack = i18n.translate( + 'xpack.uiActionsEnhanced.drilldowns.components.FlyoutFrame.BackButtonLabel', + { + defaultMessage: 'Back', + } +); diff --git a/x-pack/plugins/drilldowns/public/components/flyout_frame/index.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/index.tsx similarity index 100% rename from x-pack/plugins/drilldowns/public/components/flyout_frame/index.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_frame/index.tsx diff --git a/x-pack/plugins/drilldowns/public/components/flyout_list_manage_drilldowns/flyout_list_manage_drilldowns.story.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_list_manage_drilldowns/flyout_list_manage_drilldowns.story.tsx similarity index 100% rename from x-pack/plugins/drilldowns/public/components/flyout_list_manage_drilldowns/flyout_list_manage_drilldowns.story.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_list_manage_drilldowns/flyout_list_manage_drilldowns.story.tsx diff --git a/x-pack/plugins/drilldowns/public/components/flyout_list_manage_drilldowns/flyout_list_manage_drilldowns.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_list_manage_drilldowns/flyout_list_manage_drilldowns.tsx similarity index 100% rename from x-pack/plugins/drilldowns/public/components/flyout_list_manage_drilldowns/flyout_list_manage_drilldowns.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_list_manage_drilldowns/flyout_list_manage_drilldowns.tsx diff --git a/x-pack/plugins/drilldowns/public/components/flyout_list_manage_drilldowns/i18n.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_list_manage_drilldowns/i18n.ts similarity index 79% rename from x-pack/plugins/drilldowns/public/components/flyout_list_manage_drilldowns/i18n.ts rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_list_manage_drilldowns/i18n.ts index 0dd4e37d4dddd..f3aba205c0471 100644 --- a/x-pack/plugins/drilldowns/public/components/flyout_list_manage_drilldowns/i18n.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_list_manage_drilldowns/i18n.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; export const txtManageDrilldowns = i18n.translate( - 'xpack.drilldowns.components.FlyoutListManageDrilldowns.manageDrilldownsTitle', + 'xpack.uiActionsEnhanced.drilldowns.components.FlyoutListManageDrilldowns.manageDrilldownsTitle', { defaultMessage: 'Manage Drilldowns', } diff --git a/x-pack/plugins/drilldowns/public/components/flyout_list_manage_drilldowns/index.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_list_manage_drilldowns/index.ts similarity index 100% rename from x-pack/plugins/drilldowns/public/components/flyout_list_manage_drilldowns/index.ts rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/flyout_list_manage_drilldowns/index.ts diff --git a/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.story.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/form_drilldown_wizard/form_drilldown_wizard.story.tsx similarity index 94% rename from x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.story.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/form_drilldown_wizard/form_drilldown_wizard.story.tsx index 2fc35eb6b5298..fe63b0835af9e 100644 --- a/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.story.tsx +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/form_drilldown_wizard/form_drilldown_wizard.story.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { storiesOf } from '@storybook/react'; -import { FormDrilldownWizard } from '.'; +import { FormDrilldownWizard } from './index'; const DemoEditName: React.FC = () => { const [name, setName] = React.useState(''); diff --git a/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.test.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/form_drilldown_wizard/form_drilldown_wizard.test.tsx similarity index 100% rename from x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.test.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/form_drilldown_wizard/form_drilldown_wizard.test.tsx diff --git a/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/form_drilldown_wizard/form_drilldown_wizard.tsx similarity index 94% rename from x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/form_drilldown_wizard/form_drilldown_wizard.tsx index 1813851d728db..622ed58e3625d 100644 --- a/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.tsx +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/form_drilldown_wizard/form_drilldown_wizard.tsx @@ -7,10 +7,8 @@ import React from 'react'; import { EuiFieldText, EuiForm, EuiFormRow, EuiSpacer } from '@elastic/eui'; import { txtDrilldownAction, txtNameOfDrilldown, txtUntitledDrilldown } from './i18n'; -import { - UiActionsEnhancedActionFactory as ActionFactory, - ActionWizard, -} from '../../../../ui_actions_enhanced/public'; +import { ActionFactory } from '../../../dynamic_actions'; +import { ActionWizard } from '../../../components/action_wizard'; const noopFn = () => {}; diff --git a/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/i18n.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/form_drilldown_wizard/i18n.ts similarity index 68% rename from x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/i18n.ts rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/form_drilldown_wizard/i18n.ts index e9b19ab0afa97..9636b6e8a74e7 100644 --- a/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/i18n.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/form_drilldown_wizard/i18n.ts @@ -7,21 +7,21 @@ import { i18n } from '@kbn/i18n'; export const txtNameOfDrilldown = i18n.translate( - 'xpack.drilldowns.components.FormCreateDrilldown.nameOfDrilldown', + 'xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.nameOfDrilldown', { defaultMessage: 'Name', } ); export const txtUntitledDrilldown = i18n.translate( - 'xpack.drilldowns.components.FormCreateDrilldown.untitledDrilldown', + 'xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.untitledDrilldown', { defaultMessage: 'Untitled drilldown', } ); export const txtDrilldownAction = i18n.translate( - 'xpack.drilldowns.components.FormCreateDrilldown.drilldownAction', + 'xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.drilldownAction', { defaultMessage: 'Action', } diff --git a/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/index.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/form_drilldown_wizard/index.tsx similarity index 100% rename from x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/index.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/form_drilldown_wizard/index.tsx diff --git a/x-pack/plugins/drilldowns/scripts/storybook.js b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/index.ts similarity index 53% rename from x-pack/plugins/drilldowns/scripts/storybook.js rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/index.ts index 2bfd0eb1a8f19..a6bed0078bfd7 100644 --- a/x-pack/plugins/drilldowns/scripts/storybook.js +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/index.ts @@ -4,10 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -import { join } from 'path'; - -// eslint-disable-next-line -require('@kbn/storybook').runStorybookCli({ - name: 'drilldowns', - storyGlobs: [join(__dirname, '..', 'public', 'components', '**', '*.story.tsx')], -}); +export { createFlyoutManageDrilldowns } from './connected_flyout_manage_drilldowns'; diff --git a/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/i18n.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/list_manage_drilldowns/i18n.ts similarity index 54% rename from x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/i18n.ts rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/list_manage_drilldowns/i18n.ts index fbc7c9dcfb4a1..65087b8523cb1 100644 --- a/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/i18n.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/list_manage_drilldowns/i18n.ts @@ -7,29 +7,32 @@ import { i18n } from '@kbn/i18n'; export const txtCreateDrilldown = i18n.translate( - 'xpack.drilldowns.components.ListManageDrilldowns.createDrilldownButtonLabel', + 'xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.createDrilldownButtonLabel', { defaultMessage: 'Create new', } ); export const txtEditDrilldown = i18n.translate( - 'xpack.drilldowns.components.ListManageDrilldowns.editDrilldownButtonLabel', + 'xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.editDrilldownButtonLabel', { defaultMessage: 'Edit', } ); export const txtDeleteDrilldowns = (count: number) => - i18n.translate('xpack.drilldowns.components.ListManageDrilldowns.deleteDrilldownsButtonLabel', { - defaultMessage: 'Delete ({count})', - values: { - count, - }, - }); + i18n.translate( + 'xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.deleteDrilldownsButtonLabel', + { + defaultMessage: 'Delete ({count})', + values: { + count, + }, + } + ); export const txtSelectDrilldown = i18n.translate( - 'xpack.drilldowns.components.ListManageDrilldowns.selectThisDrilldownCheckboxLabel', + 'xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.selectThisDrilldownCheckboxLabel', { defaultMessage: 'Select this drilldown', } diff --git a/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/index.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/list_manage_drilldowns/index.tsx similarity index 100% rename from x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/index.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/list_manage_drilldowns/index.tsx diff --git a/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.story.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/list_manage_drilldowns/list_manage_drilldowns.story.tsx similarity index 100% rename from x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.story.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/list_manage_drilldowns/list_manage_drilldowns.story.tsx diff --git a/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.test.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/list_manage_drilldowns/list_manage_drilldowns.test.tsx similarity index 100% rename from x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.test.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/list_manage_drilldowns/list_manage_drilldowns.test.tsx diff --git a/x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.tsx b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/list_manage_drilldowns/list_manage_drilldowns.tsx similarity index 100% rename from x-pack/plugins/drilldowns/public/components/list_manage_drilldowns/list_manage_drilldowns.tsx rename to x-pack/plugins/ui_actions_enhanced/public/drilldowns/components/list_manage_drilldowns/list_manage_drilldowns.tsx diff --git a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/index.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/index.ts index 7f81a68c803eb..0d469e46fa9fd 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/index.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/index.ts @@ -5,3 +5,4 @@ */ export * from './drilldown_definition'; +export * from './components'; diff --git a/x-pack/plugins/ui_actions_enhanced/public/mocks.ts b/x-pack/plugins/ui_actions_enhanced/public/mocks.ts index 65fde12755beb..196b8f2c1d5c7 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/mocks.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/mocks.ts @@ -27,6 +27,7 @@ const createStartContract = (): Start => { ...uiActionsPluginMock.createStartContract(), getActionFactories: jest.fn(), getActionFactory: jest.fn(), + FlyoutManageDrilldowns: jest.fn(), }; return startContract; diff --git a/x-pack/plugins/ui_actions_enhanced/public/plugin.ts b/x-pack/plugins/ui_actions_enhanced/public/plugin.ts index d79996d5ecc1b..04caef92f15a2 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/plugin.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/plugin.ts @@ -24,7 +24,6 @@ import { CUSTOM_TIME_RANGE, TimeRangeActionContext, } from './custom_time_range_action'; - import { CustomTimeRangeBadge, CUSTOM_TIME_RANGE_BADGE, @@ -32,6 +31,8 @@ import { } from './custom_time_range_badge'; import { CommonlyUsedRange } from './types'; import { UiActionsServiceEnhancements } from './services'; +import { createFlyoutManageDrilldowns } from './drilldowns'; +import { Storage } from '../../../../src/plugins/kibana_utils/public'; interface SetupDependencies { embeddable: EmbeddableSetup; // Embeddable are needed because they register basic triggers/actions. @@ -49,7 +50,9 @@ export interface SetupContract export interface StartContract extends UiActionsStart, - Pick {} + Pick { + FlyoutManageDrilldowns: ReturnType; +} declare module '../../../../src/plugins/ui_actions/public' { export interface ActionContextMapping { @@ -94,6 +97,12 @@ export class AdvancedUiActionsPublicPlugin return { ...uiActions, ...this.enhancements, + FlyoutManageDrilldowns: createFlyoutManageDrilldowns({ + actionFactories: this.enhancements.getActionFactories(), + storage: new Storage(window?.localStorage), + toastService: core.notifications.toasts, + docsLink: core.docLinks.links.dashboard.drilldowns, + }), }; } diff --git a/x-pack/plugins/ui_actions_enhanced/scripts/storybook.js b/x-pack/plugins/ui_actions_enhanced/scripts/storybook.js index 2a192fc56469e..1e3ab0d96b81c 100644 --- a/x-pack/plugins/ui_actions_enhanced/scripts/storybook.js +++ b/x-pack/plugins/ui_actions_enhanced/scripts/storybook.js @@ -9,5 +9,8 @@ import { join } from 'path'; // eslint-disable-next-line require('@kbn/storybook').runStorybookCli({ name: 'ui_actions_enhanced', - storyGlobs: [join(__dirname, '..', 'public', 'components', '**', '*.story.tsx')], + storyGlobs: [ + join(__dirname, '..', 'public', 'components', '**', '*.story.tsx'), + join(__dirname, '..', 'public', 'drilldowns', 'components', '**', '*.story.tsx'), + ], }); From 9e8448fc0604474eb4de73f5c899584fb3055bac Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Thu, 18 Jun 2020 15:55:47 +0200 Subject: [PATCH 3/5] HttpService: duplicate some APIs from `setup` to `start` and clean mocks. (#69021) * add apis to http start contract and clean mocks * add apis to http start contract and clean mocks * add `getStartContract` method * fix new calls * remove isTlsEnabled * deprecates HttpServiceSetup.auth --- ...ibana-plugin-core-server.corestart.http.md | 13 +++ .../kibana-plugin-core-server.corestart.md | 1 + .../kibana-plugin-core-server.httpauth.get.md | 13 +++ ...in-core-server.httpauth.isauthenticated.md | 13 +++ .../kibana-plugin-core-server.httpauth.md | 20 ++++ ...lugin-core-server.httpservicesetup.auth.md | 12 ++- ...re-server.httpservicesetup.istlsenabled.md | 13 --- ...ana-plugin-core-server.httpservicesetup.md | 3 +- ...ugin-core-server.httpservicestart.auth.md} | 8 +- ...n-core-server.httpservicestart.basepath.md | 13 +++ ...e-server.httpservicestart.getserverinfo.md | 13 +++ ...ana-plugin-core-server.httpservicestart.md | 4 +- .../core/server/kibana-plugin-core-server.md | 1 + .../capabilities/capabilities_service.test.ts | 6 +- .../elasticsearch_service.test.ts | 2 +- src/core/server/http/http_server.test.ts | 11 --- src/core/server/http/http_server.ts | 2 - src/core/server/http/http_service.mock.ts | 99 ++++++++++++++++--- src/core/server/http/http_service.ts | 24 +++-- src/core/server/http/router/router.mock.ts | 2 +- src/core/server/http/types.ts | 64 ++++++++---- .../http_resources_service.test.ts | 2 +- src/core/server/index.ts | 5 +- src/core/server/internal_types.ts | 3 +- .../server/legacy/legacy_internals.test.ts | 4 +- src/core/server/legacy/legacy_service.test.ts | 4 +- src/core/server/legacy/legacy_service.ts | 6 +- .../server/metrics/metrics_service.test.ts | 2 +- .../metrics/ops_metrics_collector.test.ts | 2 +- src/core/server/mocks.ts | 23 +---- src/core/server/plugins/plugin_context.ts | 6 +- src/core/server/rendering/__mocks__/params.ts | 2 +- .../saved_objects_service.test.ts | 2 +- src/core/server/server.api.md | 20 ++-- src/core/server/server.ts | 3 + .../ui_settings/ui_settings_service.test.ts | 2 +- .../routes/custom_elements/create.test.ts | 9 +- .../routes/custom_elements/delete.test.ts | 9 +- .../routes/custom_elements/find.test.ts | 9 +- .../server/routes/custom_elements/get.test.ts | 9 +- .../routes/custom_elements/update.test.ts | 9 +- .../server/routes/es_fields/es_fields.test.ts | 9 +- .../server/routes/shareables/download.test.ts | 9 +- .../server/routes/shareables/zip.test.ts | 9 +- .../server/routes/workpad/create.test.ts | 9 +- .../server/routes/workpad/delete.test.ts | 9 +- .../canvas/server/routes/workpad/find.test.ts | 9 +- .../canvas/server/routes/workpad/get.test.ts | 9 +- .../server/routes/workpad/update.test.ts | 11 +-- .../routes/api/__fixtures__/mock_router.ts | 3 +- .../register_create_route.test.ts | 4 +- .../register_delete_route.test.ts | 4 +- .../register_fetch_route.test.ts | 4 +- .../register_get_route.test.ts | 4 +- .../register_pause_route.test.ts | 4 +- .../register_resume_route.test.ts | 4 +- .../register_update_route.test.ts | 4 +- .../register_create_route.test.ts | 4 +- .../register_fetch_route.test.ts | 4 +- .../follower_index/register_get_route.test.ts | 4 +- .../register_pause_route.test.ts | 4 +- .../register_resume_route.test.ts | 4 +- .../register_unfollow_route.test.ts | 4 +- .../component_templates/privileges.test.ts | 11 +-- x-pack/plugins/security/server/plugin.test.ts | 7 +- x-pack/plugins/security/server/plugin.ts | 2 +- .../routes/api/external/copy_to_space.test.ts | 4 +- .../server/routes/api/external/delete.test.ts | 3 +- .../server/routes/api/external/get.test.ts | 4 +- .../routes/api/external/get_all.test.ts | 4 +- .../server/routes/api/external/post.test.ts | 4 +- .../server/routes/api/external/put.test.ts | 4 +- 72 files changed, 376 insertions(+), 264 deletions(-) create mode 100644 docs/development/core/server/kibana-plugin-core-server.corestart.http.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.httpauth.get.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.httpauth.isauthenticated.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.httpauth.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.httpservicesetup.istlsenabled.md rename docs/development/core/server/{kibana-plugin-core-server.httpservicestart.islistening.md => kibana-plugin-core-server.httpservicestart.auth.md} (50%) create mode 100644 docs/development/core/server/kibana-plugin-core-server.httpservicestart.basepath.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.httpservicestart.getserverinfo.md diff --git a/docs/development/core/server/kibana-plugin-core-server.corestart.http.md b/docs/development/core/server/kibana-plugin-core-server.corestart.http.md new file mode 100644 index 0000000000000..d81049dfbd340 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corestart.http.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreStart](./kibana-plugin-core-server.corestart.md) > [http](./kibana-plugin-core-server.corestart.http.md) + +## CoreStart.http property + +[HttpServiceStart](./kibana-plugin-core-server.httpservicestart.md) + +Signature: + +```typescript +http: HttpServiceStart; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.corestart.md b/docs/development/core/server/kibana-plugin-core-server.corestart.md index c50e8924c9dd4..6a6bacf1eef40 100644 --- a/docs/development/core/server/kibana-plugin-core-server.corestart.md +++ b/docs/development/core/server/kibana-plugin-core-server.corestart.md @@ -18,6 +18,7 @@ export interface CoreStart | --- | --- | --- | | [capabilities](./kibana-plugin-core-server.corestart.capabilities.md) | CapabilitiesStart | [CapabilitiesStart](./kibana-plugin-core-server.capabilitiesstart.md) | | [elasticsearch](./kibana-plugin-core-server.corestart.elasticsearch.md) | ElasticsearchServiceStart | [ElasticsearchServiceStart](./kibana-plugin-core-server.elasticsearchservicestart.md) | +| [http](./kibana-plugin-core-server.corestart.http.md) | HttpServiceStart | [HttpServiceStart](./kibana-plugin-core-server.httpservicestart.md) | | [savedObjects](./kibana-plugin-core-server.corestart.savedobjects.md) | SavedObjectsServiceStart | [SavedObjectsServiceStart](./kibana-plugin-core-server.savedobjectsservicestart.md) | | [uiSettings](./kibana-plugin-core-server.corestart.uisettings.md) | UiSettingsServiceStart | [UiSettingsServiceStart](./kibana-plugin-core-server.uisettingsservicestart.md) | diff --git a/docs/development/core/server/kibana-plugin-core-server.httpauth.get.md b/docs/development/core/server/kibana-plugin-core-server.httpauth.get.md new file mode 100644 index 0000000000000..4ea67cf895a27 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.httpauth.get.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [HttpAuth](./kibana-plugin-core-server.httpauth.md) > [get](./kibana-plugin-core-server.httpauth.get.md) + +## HttpAuth.get property + +Gets authentication state for a request. Returned by `auth` interceptor. [GetAuthState](./kibana-plugin-core-server.getauthstate.md) + +Signature: + +```typescript +get: GetAuthState; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.httpauth.isauthenticated.md b/docs/development/core/server/kibana-plugin-core-server.httpauth.isauthenticated.md new file mode 100644 index 0000000000000..54db6bce5f161 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.httpauth.isauthenticated.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [HttpAuth](./kibana-plugin-core-server.httpauth.md) > [isAuthenticated](./kibana-plugin-core-server.httpauth.isauthenticated.md) + +## HttpAuth.isAuthenticated property + +Returns authentication status for a request. [IsAuthenticated](./kibana-plugin-core-server.isauthenticated.md) + +Signature: + +```typescript +isAuthenticated: IsAuthenticated; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.httpauth.md b/docs/development/core/server/kibana-plugin-core-server.httpauth.md new file mode 100644 index 0000000000000..d9d77809570ab --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.httpauth.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [HttpAuth](./kibana-plugin-core-server.httpauth.md) + +## HttpAuth interface + + +Signature: + +```typescript +export interface HttpAuth +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [get](./kibana-plugin-core-server.httpauth.get.md) | GetAuthState | Gets authentication state for a request. Returned by auth interceptor. [GetAuthState](./kibana-plugin-core-server.getauthstate.md) | +| [isAuthenticated](./kibana-plugin-core-server.httpauth.isauthenticated.md) | IsAuthenticated | Returns authentication status for a request. [IsAuthenticated](./kibana-plugin-core-server.isauthenticated.md) | + diff --git a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.auth.md b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.auth.md index 6667779c1c7ae..da348a2282b1a 100644 --- a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.auth.md +++ b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.auth.md @@ -4,11 +4,15 @@ ## HttpServiceSetup.auth property +> Warning: This API is now obsolete. +> +> use [the start contract](./kibana-plugin-core-server.httpservicestart.auth.md) instead. +> + +Auth status. See [HttpAuth](./kibana-plugin-core-server.httpauth.md) + Signature: ```typescript -auth: { - get: GetAuthState; - isAuthenticated: IsAuthenticated; - }; +auth: HttpAuth; ``` diff --git a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.istlsenabled.md b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.istlsenabled.md deleted file mode 100644 index fa86da18393f5..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.istlsenabled.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [HttpServiceSetup](./kibana-plugin-core-server.httpservicesetup.md) > [isTlsEnabled](./kibana-plugin-core-server.httpservicesetup.istlsenabled.md) - -## HttpServiceSetup.isTlsEnabled property - -Flag showing whether a server was configured to use TLS connection. - -Signature: - -```typescript -isTlsEnabled: boolean; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.md b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.md index 2dd832813afb8..b12983836d9e5 100644 --- a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.md +++ b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.md @@ -81,13 +81,12 @@ async (context, request, response) => { | Property | Type | Description | | --- | --- | --- | -| [auth](./kibana-plugin-core-server.httpservicesetup.auth.md) | {
get: GetAuthState;
isAuthenticated: IsAuthenticated;
} | | +| [auth](./kibana-plugin-core-server.httpservicesetup.auth.md) | HttpAuth | Auth status. See [HttpAuth](./kibana-plugin-core-server.httpauth.md) | | [basePath](./kibana-plugin-core-server.httpservicesetup.basepath.md) | IBasePath | Access or manipulate the Kibana base path See [IBasePath](./kibana-plugin-core-server.ibasepath.md). | | [createCookieSessionStorageFactory](./kibana-plugin-core-server.httpservicesetup.createcookiesessionstoragefactory.md) | <T>(cookieOptions: SessionStorageCookieOptions<T>) => Promise<SessionStorageFactory<T>> | Creates cookie based session storage factory [SessionStorageFactory](./kibana-plugin-core-server.sessionstoragefactory.md) | | [createRouter](./kibana-plugin-core-server.httpservicesetup.createrouter.md) | () => IRouter | Provides ability to declare a handler function for a particular path and HTTP request method. | | [csp](./kibana-plugin-core-server.httpservicesetup.csp.md) | ICspConfig | The CSP config used for Kibana. | | [getServerInfo](./kibana-plugin-core-server.httpservicesetup.getserverinfo.md) | () => HttpServerInfo | Provides common [information](./kibana-plugin-core-server.httpserverinfo.md) about the running http server. | -| [isTlsEnabled](./kibana-plugin-core-server.httpservicesetup.istlsenabled.md) | boolean | Flag showing whether a server was configured to use TLS connection. | | [registerAuth](./kibana-plugin-core-server.httpservicesetup.registerauth.md) | (handler: AuthenticationHandler) => void | To define custom authentication and/or authorization mechanism for incoming requests. | | [registerOnPostAuth](./kibana-plugin-core-server.httpservicesetup.registeronpostauth.md) | (handler: OnPostAuthHandler) => void | To define custom logic to perform for incoming requests. | | [registerOnPreAuth](./kibana-plugin-core-server.httpservicesetup.registeronpreauth.md) | (handler: OnPreAuthHandler) => void | To define custom logic to perform for incoming requests. | diff --git a/docs/development/core/server/kibana-plugin-core-server.httpservicestart.islistening.md b/docs/development/core/server/kibana-plugin-core-server.httpservicestart.auth.md similarity index 50% rename from docs/development/core/server/kibana-plugin-core-server.httpservicestart.islistening.md rename to docs/development/core/server/kibana-plugin-core-server.httpservicestart.auth.md index bf2922c62c15f..f7dffee2e125c 100644 --- a/docs/development/core/server/kibana-plugin-core-server.httpservicestart.islistening.md +++ b/docs/development/core/server/kibana-plugin-core-server.httpservicestart.auth.md @@ -1,13 +1,13 @@ -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [HttpServiceStart](./kibana-plugin-core-server.httpservicestart.md) > [isListening](./kibana-plugin-core-server.httpservicestart.islistening.md) +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [HttpServiceStart](./kibana-plugin-core-server.httpservicestart.md) > [auth](./kibana-plugin-core-server.httpservicestart.auth.md) -## HttpServiceStart.isListening property +## HttpServiceStart.auth property -Indicates if http server is listening on a given port +Auth status. See [HttpAuth](./kibana-plugin-core-server.httpauth.md) Signature: ```typescript -isListening: (port: number) => boolean; +auth: HttpAuth; ``` diff --git a/docs/development/core/server/kibana-plugin-core-server.httpservicestart.basepath.md b/docs/development/core/server/kibana-plugin-core-server.httpservicestart.basepath.md new file mode 100644 index 0000000000000..e8b2a0fc2cbaa --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.httpservicestart.basepath.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [HttpServiceStart](./kibana-plugin-core-server.httpservicestart.md) > [basePath](./kibana-plugin-core-server.httpservicestart.basepath.md) + +## HttpServiceStart.basePath property + +Access or manipulate the Kibana base path See [IBasePath](./kibana-plugin-core-server.ibasepath.md). + +Signature: + +```typescript +basePath: IBasePath; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.httpservicestart.getserverinfo.md b/docs/development/core/server/kibana-plugin-core-server.httpservicestart.getserverinfo.md new file mode 100644 index 0000000000000..a95c8da64fdb0 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.httpservicestart.getserverinfo.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [HttpServiceStart](./kibana-plugin-core-server.httpservicestart.md) > [getServerInfo](./kibana-plugin-core-server.httpservicestart.getserverinfo.md) + +## HttpServiceStart.getServerInfo property + +Provides common [information](./kibana-plugin-core-server.httpserverinfo.md) about the running http server. + +Signature: + +```typescript +getServerInfo: () => HttpServerInfo; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.httpservicestart.md b/docs/development/core/server/kibana-plugin-core-server.httpservicestart.md index 53239da516b25..bc99c1217f72b 100644 --- a/docs/development/core/server/kibana-plugin-core-server.httpservicestart.md +++ b/docs/development/core/server/kibana-plugin-core-server.httpservicestart.md @@ -15,5 +15,7 @@ export interface HttpServiceStart | Property | Type | Description | | --- | --- | --- | -| [isListening](./kibana-plugin-core-server.httpservicestart.islistening.md) | (port: number) => boolean | Indicates if http server is listening on a given port | +| [auth](./kibana-plugin-core-server.httpservicestart.auth.md) | HttpAuth | Auth status. See [HttpAuth](./kibana-plugin-core-server.httpauth.md) | +| [basePath](./kibana-plugin-core-server.httpservicestart.basepath.md) | IBasePath | Access or manipulate the Kibana base path See [IBasePath](./kibana-plugin-core-server.ibasepath.md). | +| [getServerInfo](./kibana-plugin-core-server.httpservicestart.getserverinfo.md) | () => HttpServerInfo | Provides common [information](./kibana-plugin-core-server.httpserverinfo.md) about the running http server. | diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md index a45bd3d44b28a..0f1bbbe7176e5 100644 --- a/docs/development/core/server/kibana-plugin-core-server.md +++ b/docs/development/core/server/kibana-plugin-core-server.md @@ -85,6 +85,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [EnvironmentMode](./kibana-plugin-core-server.environmentmode.md) | | | [ErrorHttpResponseOptions](./kibana-plugin-core-server.errorhttpresponseoptions.md) | HTTP response parameters | | [FakeRequest](./kibana-plugin-core-server.fakerequest.md) | Fake request object created manually by Kibana plugins. | +| [HttpAuth](./kibana-plugin-core-server.httpauth.md) | | | [HttpResources](./kibana-plugin-core-server.httpresources.md) | HttpResources service is responsible for serving static & dynamic assets for Kibana application via HTTP. Provides API allowing plug-ins to respond with: - a pre-configured HTML page bootstrapping Kibana client app - custom HTML page - custom JS script file. | | [HttpResourcesRenderOptions](./kibana-plugin-core-server.httpresourcesrenderoptions.md) | Allows to configure HTTP response parameters | | [HttpResourcesServiceToolkit](./kibana-plugin-core-server.httpresourcesservicetoolkit.md) | Extended set of [KibanaResponseFactory](./kibana-plugin-core-server.kibanaresponsefactory.md) helpers used to respond with HTML or JS resource. | diff --git a/src/core/server/capabilities/capabilities_service.test.ts b/src/core/server/capabilities/capabilities_service.test.ts index 7d2e7391aa8d4..42dc1604281b8 100644 --- a/src/core/server/capabilities/capabilities_service.test.ts +++ b/src/core/server/capabilities/capabilities_service.test.ts @@ -17,19 +17,19 @@ * under the License. */ -import { httpServiceMock, HttpServiceSetupMock } from '../http/http_service.mock'; +import { httpServiceMock, InternalHttpServiceSetupMock } from '../http/http_service.mock'; import { mockRouter, RouterMock } from '../http/router/router.mock'; import { CapabilitiesService, CapabilitiesSetup } from './capabilities_service'; import { mockCoreContext } from '../core_context.mock'; describe('CapabilitiesService', () => { - let http: HttpServiceSetupMock; + let http: InternalHttpServiceSetupMock; let service: CapabilitiesService; let setup: CapabilitiesSetup; let router: RouterMock; beforeEach(() => { - http = httpServiceMock.createSetupContract(); + http = httpServiceMock.createInternalSetupContract(); router = mockRouter.create(); http.createRouter.mockReturnValue(router); service = new CapabilitiesService(mockCoreContext.create()); diff --git a/src/core/server/elasticsearch/elasticsearch_service.test.ts b/src/core/server/elasticsearch/elasticsearch_service.test.ts index e7dab3807733a..8bf0df74186a9 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.test.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.test.ts @@ -39,7 +39,7 @@ const delay = async (durationMs: number) => let elasticsearchService: ElasticsearchService; const configService = configServiceMock.create(); const deps = { - http: httpServiceMock.createSetupContract(), + http: httpServiceMock.createInternalSetupContract(), }; configService.atPath.mockReturnValue( new BehaviorSubject({ diff --git a/src/core/server/http/http_server.test.ts b/src/core/server/http/http_server.test.ts index 1798c3a921da4..9a5deb9b45562 100644 --- a/src/core/server/http/http_server.test.ts +++ b/src/core/server/http/http_server.test.ts @@ -1046,17 +1046,6 @@ describe('setup contract', () => { }); }); - describe('#isTlsEnabled', () => { - it('returns "true" if TLS enabled', async () => { - const { isTlsEnabled } = await server.setup(configWithSSL); - expect(isTlsEnabled).toBe(true); - }); - it('returns "false" if TLS not enabled', async () => { - const { isTlsEnabled } = await server.setup(config); - expect(isTlsEnabled).toBe(false); - }); - }); - describe('#getServerInfo', () => { it('returns correct information', async () => { let { getServerInfo } = await server.setup(config); diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index 8089ee901fa65..d4615dd4744e5 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -53,7 +53,6 @@ export interface HttpServerSetup { registerOnPreAuth: HttpServiceSetup['registerOnPreAuth']; registerOnPostAuth: HttpServiceSetup['registerOnPostAuth']; registerOnPreResponse: HttpServiceSetup['registerOnPreResponse']; - isTlsEnabled: HttpServiceSetup['isTlsEnabled']; getAuthHeaders: GetAuthHeaders; auth: { get: GetAuthState; @@ -133,7 +132,6 @@ export class HttpServer { port: config.port, protocol: this.server!.info.protocol, }), - isTlsEnabled: config.ssl.enabled, // Return server instance with the connection options so that we can properly // bridge core and the "legacy" Kibana internally. Once this bridge isn't // needed anymore we shouldn't return the instance from this method. diff --git a/src/core/server/http/http_service.mock.ts b/src/core/server/http/http_service.mock.ts index 0788a8f2af7a1..02ae6f5d95a87 100644 --- a/src/core/server/http/http_service.mock.ts +++ b/src/core/server/http/http_service.mock.ts @@ -19,9 +19,14 @@ import { Server } from 'hapi'; import { CspConfig } from '../csp'; -import { mockRouter } from './router/router.mock'; +import { mockRouter, RouterMock } from './router/router.mock'; import { configMock } from '../config/config.mock'; -import { InternalHttpServiceSetup } from './types'; +import { + InternalHttpServiceSetup, + HttpServiceSetup, + HttpServiceStart, + InternalHttpServiceStart, +} from './types'; import { HttpService } from './http_service'; import { AuthStatus } from './auth_state_storage'; import { OnPreAuthToolkit } from './lifecycle/on_pre_auth'; @@ -32,7 +37,23 @@ import { OnPreResponseToolkit } from './lifecycle/on_pre_response'; type BasePathMocked = jest.Mocked; type AuthMocked = jest.Mocked; -export type HttpServiceSetupMock = jest.Mocked & { + +export type HttpServiceSetupMock = jest.Mocked< + Omit +> & { + basePath: BasePathMocked; + createRouter: jest.MockedFunction<() => RouterMock>; +}; +export type InternalHttpServiceSetupMock = jest.Mocked< + Omit +> & { + basePath: BasePathMocked; + createRouter: jest.MockedFunction<(path: string) => RouterMock>; +}; +export type HttpServiceStartMock = jest.Mocked & { + basePath: BasePathMocked; +}; +export type InternalHttpServiceStartMock = jest.Mocked & { basePath: BasePathMocked; }; @@ -54,8 +75,8 @@ const createAuthMock = () => { return mock; }; -const createSetupContractMock = () => { - const setupContract: HttpServiceSetupMock = { +const createInternalSetupContractMock = () => { + const mock: InternalHttpServiceSetupMock = { // we can mock other hapi server methods when we need it server: ({ name: 'http-server-test', @@ -77,31 +98,78 @@ const createSetupContractMock = () => { csp: CspConfig.DEFAULT, auth: createAuthMock(), getAuthHeaders: jest.fn(), - isTlsEnabled: false, getServerInfo: jest.fn(), }; - setupContract.createCookieSessionStorageFactory.mockResolvedValue( - sessionStorageMock.createFactory() - ); - setupContract.createRouter.mockImplementation(() => mockRouter.create()); - setupContract.getAuthHeaders.mockReturnValue({ authorization: 'authorization-header' }); - setupContract.getServerInfo.mockReturnValue({ + mock.createCookieSessionStorageFactory.mockResolvedValue(sessionStorageMock.createFactory()); + mock.createRouter.mockImplementation(() => mockRouter.create()); + mock.getAuthHeaders.mockReturnValue({ authorization: 'authorization-header' }); + mock.getServerInfo.mockReturnValue({ host: 'localhost', name: 'kibana', port: 80, protocol: 'http', }); - return setupContract; + return mock; +}; + +const createSetupContractMock = () => { + const internalMock = createInternalSetupContractMock(); + + const mock: HttpServiceSetupMock = { + createCookieSessionStorageFactory: internalMock.createCookieSessionStorageFactory, + registerOnPreAuth: internalMock.registerOnPreAuth, + registerAuth: internalMock.registerAuth, + registerOnPostAuth: internalMock.registerOnPostAuth, + registerOnPreResponse: internalMock.registerOnPreResponse, + basePath: internalMock.basePath, + csp: CspConfig.DEFAULT, + createRouter: jest.fn(), + registerRouteHandlerContext: jest.fn(), + auth: { + get: internalMock.auth.get, + isAuthenticated: internalMock.auth.isAuthenticated, + }, + getServerInfo: internalMock.getServerInfo, + }; + + mock.createRouter.mockImplementation(() => internalMock.createRouter('')); + + return mock; +}; + +const createStartContractMock = () => { + const mock: HttpServiceStartMock = { + auth: createAuthMock(), + basePath: createBasePathMock(), + getServerInfo: jest.fn(), + }; + + return mock; +}; + +const createInternalStartContractMock = () => { + const mock: InternalHttpServiceStartMock = { + ...createStartContractMock(), + isListening: jest.fn(), + }; + + mock.isListening.mockReturnValue(true); + + return mock; }; type HttpServiceContract = PublicMethodsOf; + const createHttpServiceMock = () => { const mocked: jest.Mocked = { setup: jest.fn(), + getStartContract: jest.fn(), start: jest.fn(), stop: jest.fn(), }; - mocked.setup.mockResolvedValue(createSetupContractMock()); + mocked.setup.mockResolvedValue(createInternalSetupContractMock()); + mocked.getStartContract.mockReturnValue(createInternalStartContractMock()); + mocked.start.mockResolvedValue(createInternalStartContractMock()); return mocked; }; @@ -128,7 +196,10 @@ export const httpServiceMock = { create: createHttpServiceMock, createBasePath: createBasePathMock, createAuth: createAuthMock, + createInternalSetupContract: createInternalSetupContractMock, createSetupContract: createSetupContractMock, + createInternalStartContract: createInternalStartContractMock, + createStartContract: createStartContractMock, createOnPreAuthToolkit: createOnPreAuthToolkitMock, createOnPostAuthToolkit: createOnPostAuthToolkitMock, createOnPreResponseToolkit: createOnPreResponseToolkitMock, diff --git a/src/core/server/http/http_service.ts b/src/core/server/http/http_service.ts index ae9d53f9fd3db..c2fd653918171 100644 --- a/src/core/server/http/http_service.ts +++ b/src/core/server/http/http_service.ts @@ -22,6 +22,7 @@ import { first, map } from 'rxjs/operators'; import { Server } from 'hapi'; import { CoreService } from '../../types'; +import { pick } from '../../utils'; import { Logger, LoggerFactory } from '../logging'; import { ContextSetup } from '../context'; import { Env } from '../config'; @@ -38,7 +39,7 @@ import { RequestHandlerContextContainer, RequestHandlerContextProvider, InternalHttpServiceSetup, - HttpServiceStart, + InternalHttpServiceStart, } from './types'; import { RequestHandlerContext } from '../../server'; @@ -49,7 +50,8 @@ interface SetupDeps { } /** @internal */ -export class HttpService implements CoreService { +export class HttpService + implements CoreService { private readonly httpServer: HttpServer; private readonly httpsRedirectServer: HttpsRedirectServer; private readonly config$: Observable; @@ -59,6 +61,7 @@ export class HttpService implements CoreService { @@ -114,7 +117,16 @@ export class HttpService implements CoreService this.requestHandlerContext!.registerContext(pluginOpaqueId, contextName, provider), }; - return contract; + return this.internalSetup; + } + + // this method exists because we need the start contract to create the `CoreStart` used to start + // the `plugin` and `legacy` services. + public getStartContract(): InternalHttpServiceStart { + return { + ...pick(this.internalSetup!, ['auth', 'basePath', 'getServerInfo']), + isListening: () => this.httpServer.isListening(), + }; } public async start() { @@ -134,9 +146,7 @@ export class HttpService implements CoreService this.httpServer.isListening(), - }; + return this.getStartContract(); } /** diff --git a/src/core/server/http/router/router.mock.ts b/src/core/server/http/router/router.mock.ts index 651d1712100ee..f85f187164c92 100644 --- a/src/core/server/http/router/router.mock.ts +++ b/src/core/server/http/router/router.mock.ts @@ -19,7 +19,7 @@ import { IRouter } from './router'; -export type RouterMock = DeeplyMockedKeys; +export type RouterMock = jest.Mocked; function create({ routerPath = '' }: { routerPath?: string } = {}): RouterMock { return { diff --git a/src/core/server/http/types.ts b/src/core/server/http/types.ts index 77e0d6b61692d..7f2e70545d015 100644 --- a/src/core/server/http/types.ts +++ b/src/core/server/http/types.ts @@ -47,6 +47,22 @@ export type RequestHandlerContextProvider< TContextName extends keyof RequestHandlerContext > = IContextProvider, TContextName>; +/** + * @public + */ +export interface HttpAuth { + /** + * Gets authentication state for a request. Returned by `auth` interceptor. + * {@link GetAuthState} + */ + get: GetAuthState; + /** + * Returns authentication status for a request. + * {@link IsAuthenticated} + */ + isAuthenticated: IsAuthenticated; +} + /** * Kibana HTTP Service provides own abstraction for work with HTTP stack. * Plugins don't have direct access to `hapi` server and its primitives anymore. Moreover, @@ -185,28 +201,18 @@ export interface HttpServiceSetup { */ basePath: IBasePath; - auth: { - /** - * Gets authentication state for a request. Returned by `auth` interceptor. - * {@link GetAuthState} - */ - get: GetAuthState; - /** - * Returns authentication status for a request. - * {@link IsAuthenticated} - */ - isAuthenticated: IsAuthenticated; - }; - /** - * The CSP config used for Kibana. + * Auth status. + * See {@link HttpAuth} + * + * @deprecated use {@link HttpServiceStart.auth | the start contract} instead. */ - csp: ICspConfig; + auth: HttpAuth; /** - * Flag showing whether a server was configured to use TLS connection. + * The CSP config used for Kibana. */ - isTlsEnabled: boolean; + csp: ICspConfig; /** * Provides ability to declare a handler function for a particular path and HTTP request method. @@ -276,8 +282,28 @@ export interface InternalHttpServiceSetup /** @public */ export interface HttpServiceStart { - /** Indicates if http server is listening on a given port */ - isListening: (port: number) => boolean; + /** + * Access or manipulate the Kibana base path + * See {@link IBasePath}. + */ + basePath: IBasePath; + + /** + * Auth status. + * See {@link HttpAuth} + */ + auth: HttpAuth; + + /** + * Provides common {@link HttpServerInfo | information} about the running http server. + */ + getServerInfo: () => HttpServerInfo; +} + +/** @internal */ +export interface InternalHttpServiceStart extends HttpServiceStart { + /** Indicates if the http server is listening on the configured port */ + isListening: () => boolean; } /** @public */ diff --git a/src/core/server/http_resources/http_resources_service.test.ts b/src/core/server/http_resources/http_resources_service.test.ts index e6f129ba12d78..80afddc166570 100644 --- a/src/core/server/http_resources/http_resources_service.test.ts +++ b/src/core/server/http_resources/http_resources_service.test.ts @@ -37,7 +37,7 @@ describe('HttpResources service', () => { describe('#createRegistrar', () => { beforeEach(() => { setupDeps = { - http: httpServiceMock.createSetupContract(), + http: httpServiceMock.createInternalSetupContract(), rendering: renderingMock.createSetupContract(), }; service = new HttpResourcesService(coreContext); diff --git a/src/core/server/index.ts b/src/core/server/index.ts index dccd58c24a7d0..0da7e5d66cf2a 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -46,7 +46,7 @@ import { ElasticsearchServiceStart, } from './elasticsearch'; -import { HttpServiceSetup } from './http'; +import { HttpServiceSetup, HttpServiceStart } from './http'; import { HttpResources } from './http_resources'; import { PluginsServiceSetup, PluginsServiceStart, PluginOpaqueId } from './plugins'; @@ -121,6 +121,7 @@ export { CustomHttpResponseOptions, GetAuthHeaders, GetAuthState, + HttpAuth, HttpResponseOptions, HttpResponsePayload, HttpServerInfo, @@ -421,6 +422,8 @@ export interface CoreStart { capabilities: CapabilitiesStart; /** {@link ElasticsearchServiceStart} */ elasticsearch: ElasticsearchServiceStart; + /** {@link HttpServiceStart} */ + http: HttpServiceStart; /** {@link SavedObjectsServiceStart} */ savedObjects: SavedObjectsServiceStart; /** {@link UiSettingsServiceStart} */ diff --git a/src/core/server/internal_types.ts b/src/core/server/internal_types.ts index 09ec772a41756..f68ab633dcbe6 100644 --- a/src/core/server/internal_types.ts +++ b/src/core/server/internal_types.ts @@ -23,7 +23,7 @@ import { CapabilitiesSetup, CapabilitiesStart } from './capabilities'; import { ConfigDeprecationProvider } from './config'; import { ContextSetup } from './context'; import { InternalElasticsearchServiceSetup, ElasticsearchServiceStart } from './elasticsearch'; -import { InternalHttpServiceSetup } from './http'; +import { InternalHttpServiceSetup, InternalHttpServiceStart } from './http'; import { InternalSavedObjectsServiceSetup, InternalSavedObjectsServiceStart, @@ -56,6 +56,7 @@ export interface InternalCoreSetup { export interface InternalCoreStart { capabilities: CapabilitiesStart; elasticsearch: ElasticsearchServiceStart; + http: InternalHttpServiceStart; savedObjects: InternalSavedObjectsServiceStart; uiSettings: InternalUiSettingsServiceStart; } diff --git a/src/core/server/legacy/legacy_internals.test.ts b/src/core/server/legacy/legacy_internals.test.ts index 2ae5e3a3fd1e8..67f2f433d4570 100644 --- a/src/core/server/legacy/legacy_internals.test.ts +++ b/src/core/server/legacy/legacy_internals.test.ts @@ -45,7 +45,7 @@ describe('LegacyInternals', () => { beforeEach(async () => { uiExports = findLegacyPluginSpecsMock().uiExports; config = configMock.create() as any; - server = httpServiceMock.createSetupContract().server; + server = httpServiceMock.createInternalSetupContract().server; legacyInternals = new LegacyInternals(uiExports, config, server); }); @@ -107,7 +107,7 @@ describe('LegacyInternals', () => { beforeEach(async () => { uiExports = findLegacyPluginSpecsMock().uiExports; config = configMock.create() as any; - server = httpServiceMock.createSetupContract().server; + server = httpServiceMock.createInternalSetupContract().server; legacyInternals = new LegacyInternals(uiExports, config, server); }); diff --git a/src/core/server/legacy/legacy_service.test.ts b/src/core/server/legacy/legacy_service.test.ts index d9a0ac5e4ecff..fb9dc0776716a 100644 --- a/src/core/server/legacy/legacy_service.test.ts +++ b/src/core/server/legacy/legacy_service.test.ts @@ -85,7 +85,7 @@ beforeEach(() => { elasticsearch: { legacy: {} } as any, uiSettings: uiSettingsServiceMock.createSetupContract(), http: { - ...httpServiceMock.createSetupContract(), + ...httpServiceMock.createInternalSetupContract(), auth: { getAuthHeaders: () => undefined, } as any, @@ -119,7 +119,7 @@ beforeEach(() => { startDeps = { core: { - ...coreMock.createStart(), + ...coreMock.createInternalStart(), savedObjects: savedObjectsServiceMock.createInternalStartContract(), plugins: { contracts: new Map() }, }, diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index 2ced8b4762406..cfc53b10d91f0 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -264,6 +264,11 @@ export class LegacyService implements CoreService { const coreStart: CoreStart = { capabilities: startDeps.core.capabilities, elasticsearch: startDeps.core.elasticsearch, + http: { + auth: startDeps.core.http.auth, + basePath: startDeps.core.http.basePath, + getServerInfo: startDeps.core.http.getServerInfo, + }, savedObjects: { getScopedClient: startDeps.core.savedObjects.getScopedClient, createScopedRepository: startDeps.core.savedObjects.createScopedRepository, @@ -302,7 +307,6 @@ export class LegacyService implements CoreService { isAuthenticated: setupDeps.core.http.auth.isAuthenticated, }, csp: setupDeps.core.http.csp, - isTlsEnabled: setupDeps.core.http.isTlsEnabled, getServerInfo: setupDeps.core.http.getServerInfo, }, metrics: { diff --git a/src/core/server/metrics/metrics_service.test.ts b/src/core/server/metrics/metrics_service.test.ts index 01a7429745cda..b3cc06ffca1d2 100644 --- a/src/core/server/metrics/metrics_service.test.ts +++ b/src/core/server/metrics/metrics_service.test.ts @@ -30,7 +30,7 @@ const testInterval = 100; const dummyMetrics = { metricA: 'value', metricB: 'otherValue' }; describe('MetricsService', () => { - const httpMock = httpServiceMock.createSetupContract(); + const httpMock = httpServiceMock.createInternalSetupContract(); let metricsService: MetricsService; beforeEach(() => { diff --git a/src/core/server/metrics/ops_metrics_collector.test.ts b/src/core/server/metrics/ops_metrics_collector.test.ts index 559588db60a42..9e76895b14578 100644 --- a/src/core/server/metrics/ops_metrics_collector.test.ts +++ b/src/core/server/metrics/ops_metrics_collector.test.ts @@ -29,7 +29,7 @@ describe('OpsMetricsCollector', () => { let collector: OpsMetricsCollector; beforeEach(() => { - const hapiServer = httpServiceMock.createSetupContract().server; + const hapiServer = httpServiceMock.createInternalSetupContract().server; collector = new OpsMetricsCollector(hapiServer); mockOsCollector.collect.mockResolvedValue('osMetrics'); diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index b6e9ffef6f3f1..f3ae5462f1631 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -19,7 +19,6 @@ import { of } from 'rxjs'; import { duration } from 'moment'; import { PluginInitializerContext, CoreSetup, CoreStart, StartServicesAccessor } from '.'; -import { CspConfig } from './csp'; import { loggingServiceMock } from './logging/logging_service.mock'; import { elasticsearchServiceMock } from './elasticsearch/elasticsearch_service.mock'; import { httpServiceMock } from './http/http_service.mock'; @@ -112,26 +111,10 @@ function createCoreSetupMock({ pluginStartDeps?: object; pluginStartContract?: any; } = {}) { - const httpService = httpServiceMock.createSetupContract(); const httpMock: jest.Mocked = { - createCookieSessionStorageFactory: httpService.createCookieSessionStorageFactory, - registerOnPreAuth: httpService.registerOnPreAuth, - registerAuth: httpService.registerAuth, - registerOnPostAuth: httpService.registerOnPostAuth, - registerOnPreResponse: httpService.registerOnPreResponse, - basePath: httpService.basePath, - csp: CspConfig.DEFAULT, - isTlsEnabled: httpService.isTlsEnabled, - createRouter: jest.fn(), - registerRouteHandlerContext: jest.fn(), - auth: { - get: httpService.auth.get, - isAuthenticated: httpService.auth.isAuthenticated, - }, + ...httpServiceMock.createSetupContract(), resources: httpResourcesMock.createRegistrar(), - getServerInfo: httpService.getServerInfo, }; - httpMock.createRouter.mockImplementation(() => httpService.createRouter('')); const uiSettingsMock = { register: uiSettingsServiceMock.createSetupContract().register, @@ -159,6 +142,7 @@ function createCoreStartMock() { const mock: MockedKeys = { capabilities: capabilitiesServiceMock.createStartContract(), elasticsearch: elasticsearchServiceMock.createStart(), + http: httpServiceMock.createStartContract(), savedObjects: savedObjectsServiceMock.createStartContract(), uiSettings: uiSettingsServiceMock.createStartContract(), }; @@ -171,7 +155,7 @@ function createInternalCoreSetupMock() { capabilities: capabilitiesServiceMock.createSetupContract(), context: contextServiceMock.createSetupContract(), elasticsearch: elasticsearchServiceMock.createInternalSetup(), - http: httpServiceMock.createSetupContract(), + http: httpServiceMock.createInternalSetupContract(), metrics: metricsServiceMock.createInternalSetupContract(), savedObjects: savedObjectsServiceMock.createInternalSetupContract(), status: statusServiceMock.createInternalSetupContract(), @@ -187,6 +171,7 @@ function createInternalCoreStartMock() { const startDeps: InternalCoreStart = { capabilities: capabilitiesServiceMock.createStartContract(), elasticsearch: elasticsearchServiceMock.createStart(), + http: httpServiceMock.createInternalStartContract(), savedObjects: savedObjectsServiceMock.createInternalStartContract(), uiSettings: uiSettingsServiceMock.createStartContract(), }; diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index f0db3a25e313d..31e36db49223a 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -164,7 +164,6 @@ export function createPluginSetupContext( basePath: deps.http.basePath, auth: { get: deps.http.auth.get, isAuthenticated: deps.http.auth.isAuthenticated }, csp: deps.http.csp, - isTlsEnabled: deps.http.isTlsEnabled, getServerInfo: deps.http.getServerInfo, }, metrics: { @@ -211,6 +210,11 @@ export function createPluginStartContext( resolveCapabilities: deps.capabilities.resolveCapabilities, }, elasticsearch: deps.elasticsearch, + http: { + auth: deps.http.auth, + basePath: deps.http.basePath, + getServerInfo: deps.http.getServerInfo, + }, savedObjects: { getScopedClient: deps.savedObjects.getScopedClient, createInternalRepository: deps.savedObjects.createInternalRepository, diff --git a/src/core/server/rendering/__mocks__/params.ts b/src/core/server/rendering/__mocks__/params.ts index 3e668b3f26ab5..ce2eea119d1bb 100644 --- a/src/core/server/rendering/__mocks__/params.ts +++ b/src/core/server/rendering/__mocks__/params.ts @@ -23,7 +23,7 @@ import { pluginServiceMock } from '../../plugins/plugins_service.mock'; import { legacyServiceMock } from '../../legacy/legacy_service.mock'; const context = mockCoreContext.create(); -const http = httpServiceMock.createSetupContract(); +const http = httpServiceMock.createInternalSetupContract(); const uiPlugins = pluginServiceMock.createUiPlugins(); const legacyPlugins = legacyServiceMock.createDiscoverPlugins(); diff --git a/src/core/server/saved_objects/saved_objects_service.test.ts b/src/core/server/saved_objects/saved_objects_service.test.ts index 9fba2728003d2..e8b2cf0b583b1 100644 --- a/src/core/server/saved_objects/saved_objects_service.test.ts +++ b/src/core/server/saved_objects/saved_objects_service.test.ts @@ -61,7 +61,7 @@ describe('SavedObjectsService', () => { const createSetupDeps = () => { const elasticsearchMock = elasticsearchServiceMock.createInternalSetup(); return { - http: httpServiceMock.createSetupContract(), + http: httpServiceMock.createInternalSetupContract(), elasticsearch: elasticsearchMock, legacyPlugins: legacyServiceMock.createDiscoverPlugins(), }; diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 833c8918a0860..9dc3ac9b94d96 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -657,6 +657,8 @@ export interface CoreStart { // (undocumented) elasticsearch: ElasticsearchServiceStart; // (undocumented) + http: HttpServiceStart; + // (undocumented) savedObjects: SavedObjectsServiceStart; // (undocumented) uiSettings: UiSettingsServiceStart; @@ -905,6 +907,12 @@ export type Headers = { [header: string]: string | string[] | undefined; }; +// @public (undocumented) +export interface HttpAuth { + get: GetAuthState; + isAuthenticated: IsAuthenticated; +} + // @public export interface HttpResources { register: (route: RouteConfig, handler: HttpResourcesRequestHandler) => void; @@ -948,17 +956,13 @@ export interface HttpServerInfo { // @public export interface HttpServiceSetup { - // (undocumented) - auth: { - get: GetAuthState; - isAuthenticated: IsAuthenticated; - }; + // @deprecated + auth: HttpAuth; basePath: IBasePath; createCookieSessionStorageFactory: (cookieOptions: SessionStorageCookieOptions) => Promise>; createRouter: () => IRouter; csp: ICspConfig; getServerInfo: () => HttpServerInfo; - isTlsEnabled: boolean; registerAuth: (handler: AuthenticationHandler) => void; registerOnPostAuth: (handler: OnPostAuthHandler) => void; registerOnPreAuth: (handler: OnPreAuthHandler) => void; @@ -968,7 +972,9 @@ export interface HttpServiceSetup { // @public (undocumented) export interface HttpServiceStart { - isListening: (port: number) => boolean; + auth: HttpAuth; + basePath: IBasePath; + getServerInfo: () => HttpServerInfo; } // @public diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 6ca580083648f..ae1a02cf71b88 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -202,10 +202,12 @@ export class Server { }); const capabilitiesStart = this.capabilities.start(); const uiSettingsStart = await this.uiSettings.start(); + const httpStart = this.http.getStartContract(); this.coreStart = { capabilities: capabilitiesStart, elasticsearch: elasticsearchStart, + http: httpStart, savedObjects: savedObjectsStart, uiSettings: uiSettingsStart, }; @@ -221,6 +223,7 @@ export class Server { }); await this.http.start(); + await this.rendering.start({ legacy: this.legacy, }); diff --git a/src/core/server/ui_settings/ui_settings_service.test.ts b/src/core/server/ui_settings/ui_settings_service.test.ts index ebcb0cf1d762f..096ca347e6f4b 100644 --- a/src/core/server/ui_settings/ui_settings_service.test.ts +++ b/src/core/server/ui_settings/ui_settings_service.test.ts @@ -49,7 +49,7 @@ describe('uiSettings', () => { beforeEach(() => { const coreContext = mockCoreContext.create(); coreContext.configService.atPath.mockReturnValue(new BehaviorSubject({ overrides })); - const httpSetup = httpServiceMock.createSetupContract(); + const httpSetup = httpServiceMock.createInternalSetupContract(); const savedObjectsSetup = savedObjectsServiceMock.createInternalSetupContract(); setupDeps = { http: httpSetup, savedObjects: savedObjectsSetup }; savedObjectsClient = savedObjectsClientMock.create(); diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/create.test.ts b/x-pack/plugins/canvas/server/routes/custom_elements/create.test.ts index c260d6ca8ac16..db0417434227c 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/create.test.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/create.test.ts @@ -13,12 +13,7 @@ import { } from 'src/core/server/mocks'; import { CUSTOM_ELEMENT_TYPE } from '../../../common/lib/constants'; import { initializeCreateCustomElementRoute } from './create'; -import { - IRouter, - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; const mockRouteContext = ({ core: { @@ -43,7 +38,7 @@ describe('POST custom element', () => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeCreateCustomElementRoute({ router, logger: loggingServiceMock.create().get(), diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/delete.test.ts b/x-pack/plugins/canvas/server/routes/custom_elements/delete.test.ts index e70fae5d18eaf..98b26ec368ab1 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/delete.test.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/delete.test.ts @@ -6,12 +6,7 @@ import { CUSTOM_ELEMENT_TYPE } from '../../../common/lib/constants'; import { initializeDeleteCustomElementRoute } from './delete'; -import { - IRouter, - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; import { savedObjectsClientMock, httpServiceMock, @@ -32,7 +27,7 @@ describe('DELETE custom element', () => { beforeEach(() => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeDeleteCustomElementRoute({ router, logger: loggingServiceMock.create().get(), diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/find.test.ts b/x-pack/plugins/canvas/server/routes/custom_elements/find.test.ts index 6644d3b56c681..dead9ded8a14a 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/find.test.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/find.test.ts @@ -5,12 +5,7 @@ */ import { initializeFindCustomElementsRoute } from './find'; -import { - IRouter, - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; import { savedObjectsClientMock, httpServiceMock, @@ -31,7 +26,7 @@ describe('Find custom element', () => { beforeEach(() => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeFindCustomElementsRoute({ router, logger: loggingServiceMock.create().get(), diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/get.test.ts b/x-pack/plugins/canvas/server/routes/custom_elements/get.test.ts index 03ae6048801bf..09b620aeff9bb 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/get.test.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/get.test.ts @@ -6,12 +6,7 @@ import { CUSTOM_ELEMENT_TYPE } from '../../../common/lib/constants'; import { initializeGetCustomElementRoute } from './get'; -import { - IRouter, - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; import { savedObjectsClientMock, httpServiceMock, @@ -32,7 +27,7 @@ describe('GET custom element', () => { beforeEach(() => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeGetCustomElementRoute({ router, logger: loggingServiceMock.create().get(), diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/update.test.ts b/x-pack/plugins/canvas/server/routes/custom_elements/update.test.ts index e67e42c26cd2b..19477458bacb5 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/update.test.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/update.test.ts @@ -8,12 +8,7 @@ import sinon from 'sinon'; import { CustomElement } from '../../../types'; import { CUSTOM_ELEMENT_TYPE } from '../../../common/lib/constants'; import { initializeUpdateCustomElementRoute } from './update'; -import { - IRouter, - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; import { savedObjectsClientMock, httpServiceMock, @@ -57,7 +52,7 @@ describe('PUT custom element', () => { clock = sinon.useFakeTimers(now); const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeUpdateCustomElementRoute({ router, logger: loggingServiceMock.create().get(), diff --git a/x-pack/plugins/canvas/server/routes/es_fields/es_fields.test.ts b/x-pack/plugins/canvas/server/routes/es_fields/es_fields.test.ts index c3588957ff68e..93fdb4304acc6 100644 --- a/x-pack/plugins/canvas/server/routes/es_fields/es_fields.test.ts +++ b/x-pack/plugins/canvas/server/routes/es_fields/es_fields.test.ts @@ -5,12 +5,7 @@ */ import { initializeESFieldsRoute } from './es_fields'; -import { - IRouter, - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; import { httpServiceMock, httpServerMock, @@ -31,7 +26,7 @@ describe('Retrieve ES Fields', () => { beforeEach(() => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeESFieldsRoute({ router, logger: loggingServiceMock.create().get(), diff --git a/x-pack/plugins/canvas/server/routes/shareables/download.test.ts b/x-pack/plugins/canvas/server/routes/shareables/download.test.ts index be4765217d7aa..75eeb46c890d5 100644 --- a/x-pack/plugins/canvas/server/routes/shareables/download.test.ts +++ b/x-pack/plugins/canvas/server/routes/shareables/download.test.ts @@ -7,12 +7,7 @@ jest.mock('fs'); import fs from 'fs'; -import { - IRouter, - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; import { httpServiceMock, httpServerMock, loggingServiceMock } from 'src/core/server/mocks'; import { initializeDownloadShareableWorkpadRoute } from './download'; @@ -25,7 +20,7 @@ describe('Download Canvas shareables runtime', () => { beforeEach(() => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeDownloadShareableWorkpadRoute({ router, logger: loggingServiceMock.create().get(), diff --git a/x-pack/plugins/canvas/server/routes/shareables/zip.test.ts b/x-pack/plugins/canvas/server/routes/shareables/zip.test.ts index 63776f897a04c..5a2d122c2754b 100644 --- a/x-pack/plugins/canvas/server/routes/shareables/zip.test.ts +++ b/x-pack/plugins/canvas/server/routes/shareables/zip.test.ts @@ -7,12 +7,7 @@ jest.mock('archiver'); const archiver = require('archiver') as jest.Mock; -import { - IRouter, - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; import { httpServiceMock, httpServerMock, loggingServiceMock } from 'src/core/server/mocks'; import { initializeZipShareableWorkpadRoute } from './zip'; import { API_ROUTE_SHAREABLE_ZIP } from '../../../common/lib'; @@ -31,7 +26,7 @@ describe('Zips Canvas shareables runtime together with workpad', () => { beforeEach(() => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeZipShareableWorkpadRoute({ router, logger: loggingServiceMock.create().get(), diff --git a/x-pack/plugins/canvas/server/routes/workpad/create.test.ts b/x-pack/plugins/canvas/server/routes/workpad/create.test.ts index 02b6376ece2ed..2ed63e7397108 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/create.test.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/create.test.ts @@ -13,12 +13,7 @@ import { } from 'src/core/server/mocks'; import { CANVAS_TYPE } from '../../../common/lib/constants'; import { initializeCreateWorkpadRoute } from './create'; -import { - IRouter, - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; const mockRouteContext = ({ core: { @@ -43,7 +38,7 @@ describe('POST workpad', () => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeCreateWorkpadRoute({ router, logger: loggingServiceMock.create().get(), diff --git a/x-pack/plugins/canvas/server/routes/workpad/delete.test.ts b/x-pack/plugins/canvas/server/routes/workpad/delete.test.ts index 57df4e7cffda6..712ff29400382 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/delete.test.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/delete.test.ts @@ -6,12 +6,7 @@ import { CANVAS_TYPE } from '../../../common/lib/constants'; import { initializeDeleteWorkpadRoute } from './delete'; -import { - IRouter, - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; import { savedObjectsClientMock, httpServiceMock, @@ -32,7 +27,7 @@ describe('DELETE workpad', () => { beforeEach(() => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeDeleteWorkpadRoute({ router, logger: loggingServiceMock.create().get(), diff --git a/x-pack/plugins/canvas/server/routes/workpad/find.test.ts b/x-pack/plugins/canvas/server/routes/workpad/find.test.ts index 08de9b20e9818..e2dd8552379b7 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/find.test.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/find.test.ts @@ -5,12 +5,7 @@ */ import { initializeFindWorkpadsRoute } from './find'; -import { - IRouter, - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; import { savedObjectsClientMock, httpServiceMock, @@ -31,7 +26,7 @@ describe('Find workpad', () => { beforeEach(() => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeFindWorkpadsRoute({ router, logger: loggingServiceMock.create().get(), diff --git a/x-pack/plugins/canvas/server/routes/workpad/get.test.ts b/x-pack/plugins/canvas/server/routes/workpad/get.test.ts index 6741f2b3fc9d6..9ecd9ceefed8d 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/get.test.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/get.test.ts @@ -6,12 +6,7 @@ import { CANVAS_TYPE } from '../../../common/lib/constants'; import { initializeGetWorkpadRoute } from './get'; -import { - IRouter, - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; import { savedObjectsClientMock, httpServiceMock, @@ -34,7 +29,7 @@ describe('GET workpad', () => { beforeEach(() => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeGetWorkpadRoute({ router, logger: loggingServiceMock.create().get(), diff --git a/x-pack/plugins/canvas/server/routes/workpad/update.test.ts b/x-pack/plugins/canvas/server/routes/workpad/update.test.ts index a6b34e7165121..36ea984447d8a 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/update.test.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/update.test.ts @@ -7,12 +7,7 @@ import sinon from 'sinon'; import { CANVAS_TYPE } from '../../../common/lib/constants'; import { initializeUpdateWorkpadRoute, initializeUpdateWorkpadAssetsRoute } from './update'; -import { - IRouter, - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; import { savedObjectsClientMock, httpServiceMock, @@ -44,7 +39,7 @@ describe('PUT workpad', () => { clock = sinon.useFakeTimers(now); const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeUpdateWorkpadRoute({ router, logger: loggingServiceMock.create().get(), @@ -158,7 +153,7 @@ describe('update assets', () => { beforeEach(() => { clock = sinon.useFakeTimers(now); const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); initializeUpdateWorkpadAssetsRoute({ router, logger: loggingServiceMock.create().get(), diff --git a/x-pack/plugins/case/server/routes/api/__fixtures__/mock_router.ts b/x-pack/plugins/case/server/routes/api/__fixtures__/mock_router.ts index eff91fff32c02..e00c1c111b41b 100644 --- a/x-pack/plugins/case/server/routes/api/__fixtures__/mock_router.ts +++ b/x-pack/plugins/case/server/routes/api/__fixtures__/mock_router.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { IRouter } from 'kibana/server'; import { loggingServiceMock, httpServiceMock } from '../../../../../../../src/core/server/mocks'; import { CaseService, CaseConfigureService } from '../../../services'; import { authenticationMock } from '../__fixtures__'; @@ -16,7 +15,7 @@ export const createRoute = async ( badAuth = false ) => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); const log = loggingServiceMock.create().get('case'); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.test.ts index 0b5f04556596a..cf2349bc7023c 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.test.ts @@ -5,7 +5,7 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../shared_imports'; import { formatEsError } from '../../../lib/format_es_error'; @@ -19,7 +19,7 @@ describe('[CCR API] Create auto-follow pattern', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerCreateRoute({ router, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts index 7468c643a3aa6..b2a3b631333b4 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts @@ -5,7 +5,7 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../shared_imports'; import { formatEsError } from '../../../lib/format_es_error'; @@ -19,7 +19,7 @@ describe('[CCR API] Delete auto-follow pattern(s)', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerDeleteRoute({ router, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts index 1aa7112c75276..4f2417ec816f4 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts @@ -5,7 +5,7 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../shared_imports'; import { formatEsError } from '../../../lib/format_es_error'; @@ -19,7 +19,7 @@ describe('[CCR API] Fetch all auto-follow patterns', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerFetchRoute({ router, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts index 980128027c2f9..802aebd6412fe 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts @@ -5,7 +5,7 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../shared_imports'; import { formatEsError } from '../../../lib/format_es_error'; @@ -19,7 +19,7 @@ describe('[CCR API] Get one auto-follow pattern', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerGetRoute({ router, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts index 5b27c77ca86de..a92a9b5edb9b7 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts @@ -5,7 +5,7 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../shared_imports'; import { formatEsError } from '../../../lib/format_es_error'; @@ -19,7 +19,7 @@ describe('[CCR API] Pause auto-follow pattern(s)', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerPauseRoute({ router, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts index afea0f631fe48..4ee77b1b3deaa 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts @@ -5,7 +5,7 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../shared_imports'; import { formatEsError } from '../../../lib/format_es_error'; @@ -19,7 +19,7 @@ describe('[CCR API] Resume auto-follow pattern(s)', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerResumeRoute({ router, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts index bdce84f6404b1..711538e2a1ee0 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts @@ -5,7 +5,7 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../shared_imports'; import { formatEsError } from '../../../lib/format_es_error'; @@ -19,7 +19,7 @@ describe('[CCR API] Update auto-follow pattern', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerUpdateRoute({ router, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts index ccf7c469fe780..de21458c0a25f 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts @@ -5,7 +5,7 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../shared_imports'; import { formatEsError } from '../../../lib/format_es_error'; @@ -19,7 +19,7 @@ describe('[CCR API] Create follower index', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerCreateRoute({ router, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts index e1ec28a7c90b1..ec52f1e431e38 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts @@ -5,7 +5,7 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../shared_imports'; import { formatEsError } from '../../../lib/format_es_error'; @@ -19,7 +19,7 @@ describe('[CCR API] Fetch all follower indices', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerFetchRoute({ router, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts index 99c871d5d4f2d..a0feeb2b1e5bc 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts @@ -5,7 +5,7 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../shared_imports'; import { formatEsError } from '../../../lib/format_es_error'; @@ -19,7 +19,7 @@ describe('[CCR API] Get one follower index', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerGetRoute({ router, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts index 3d28d36ac6182..dcbec8703622e 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts @@ -5,7 +5,7 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../shared_imports'; import { formatEsError } from '../../../lib/format_es_error'; @@ -19,7 +19,7 @@ describe('[CCR API] Pause follower index/indices', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerPauseRoute({ router, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts index 09975b262dca8..30d25c3bc4d03 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts @@ -5,7 +5,7 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../shared_imports'; import { formatEsError } from '../../../lib/format_es_error'; @@ -19,7 +19,7 @@ describe('[CCR API] Resume follower index/indices', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerResumeRoute({ router, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts index 5f0d148bfcae9..a56eb8178b478 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts @@ -5,7 +5,7 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../shared_imports'; import { formatEsError } from '../../../lib/format_es_error'; @@ -19,7 +19,7 @@ describe('[CCR API] Unfollow follower index/indices', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerUnfollowRoute({ router, diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/privileges.test.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/privileges.test.ts index b34ffe3e0baf5..060a423350ada 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/privileges.test.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/privileges.test.ts @@ -4,12 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { httpServerMock, httpServiceMock } from 'src/core/server/mocks'; -import { - kibanaResponseFactory, - RequestHandlerContext, - RequestHandler, - IRouter, -} from 'src/core/server'; +import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server'; import { License } from '../../../services/license'; import { IndexDataEnricher } from '../../../services/index_data_enricher'; @@ -46,7 +41,7 @@ describe('GET privileges', () => { let routeHandler: RequestHandler; beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerPrivilegesRoute({ router, @@ -115,7 +110,7 @@ describe('GET privileges', () => { describe('With security disabled', () => { beforeEach(() => { - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); registerPrivilegesRoute({ router, diff --git a/x-pack/plugins/security/server/plugin.test.ts b/x-pack/plugins/security/server/plugin.test.ts index e01c608e5f306..627d1408673be 100644 --- a/x-pack/plugins/security/server/plugin.test.ts +++ b/x-pack/plugins/security/server/plugin.test.ts @@ -36,7 +36,12 @@ describe('Security Plugin', () => { ); mockCoreSetup = coreMock.createSetup(); - mockCoreSetup.http.isTlsEnabled = true; + mockCoreSetup.http.getServerInfo.mockReturnValue({ + host: 'localhost', + name: 'kibana', + port: 80, + protocol: 'https', + }); mockClusterClient = elasticsearchServiceMock.createCustomClusterClient(); mockCoreSetup.elasticsearch.legacy.createClient.mockReturnValue(mockClusterClient); diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts index c8f47aaae7b5d..a14617c8489cc 100644 --- a/x-pack/plugins/security/server/plugin.ts +++ b/x-pack/plugins/security/server/plugin.ts @@ -118,7 +118,7 @@ export class Plugin { this.initializerContext.config.create>().pipe( map((rawConfig) => createConfig(rawConfig, this.initializerContext.logger.get('config'), { - isTLSEnabled: core.http.isTlsEnabled, + isTLSEnabled: core.http.getServerInfo().protocol === 'https', }) ) ), diff --git a/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts b/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts index 09fc990e9935c..53f5a219dda5b 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts @@ -14,7 +14,7 @@ import { createResolveSavedObjectsImportErrorsMock, createMockSavedObjectsService, } from '../__fixtures__'; -import { CoreSetup, IRouter, kibanaResponseFactory, RouteValidatorConfig } from 'src/core/server'; +import { CoreSetup, kibanaResponseFactory, RouteValidatorConfig } from 'src/core/server'; import { loggingServiceMock, httpServiceMock, @@ -54,7 +54,7 @@ describe('copy to space', () => { const setup = async () => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); const savedObjectsRepositoryMock = createMockSavedObjectsRepository(spacesSavedObjects); diff --git a/x-pack/plugins/spaces/server/routes/api/external/delete.test.ts b/x-pack/plugins/spaces/server/routes/api/external/delete.test.ts index 774b794d77e29..f31ef657642e7 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/delete.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/delete.test.ts @@ -13,7 +13,6 @@ import { } from '../__fixtures__'; import { CoreSetup, - IRouter, kibanaResponseFactory, RouteValidatorConfig, SavedObjectsErrorHelpers, @@ -37,7 +36,7 @@ describe('Spaces Public API', () => { const setup = async () => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); const savedObjectsRepositoryMock = createMockSavedObjectsRepository(spacesSavedObjects); diff --git a/x-pack/plugins/spaces/server/routes/api/external/get.test.ts b/x-pack/plugins/spaces/server/routes/api/external/get.test.ts index 19f9b81baa0b0..55e153cf47f5b 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/get.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/get.test.ts @@ -11,7 +11,7 @@ import { mockRouteContext, } from '../__fixtures__'; import { initGetSpaceApi } from './get'; -import { CoreSetup, IRouter, kibanaResponseFactory } from 'src/core/server'; +import { CoreSetup, kibanaResponseFactory } from 'src/core/server'; import { loggingServiceMock, httpServiceMock, @@ -30,7 +30,7 @@ describe('GET space', () => { const setup = async () => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); const coreStart = coreMock.createStart(); diff --git a/x-pack/plugins/spaces/server/routes/api/external/get_all.test.ts b/x-pack/plugins/spaces/server/routes/api/external/get_all.test.ts index 380cc9dbe5abf..aabd4900c5469 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/get_all.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/get_all.test.ts @@ -10,7 +10,7 @@ import { mockRouteContext, mockRouteContextWithInvalidLicense, } from '../__fixtures__'; -import { CoreSetup, kibanaResponseFactory, IRouter } from 'src/core/server'; +import { CoreSetup, kibanaResponseFactory } from 'src/core/server'; import { loggingServiceMock, httpServiceMock, @@ -30,7 +30,7 @@ describe('GET /spaces/space', () => { const setup = async () => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); const coreStart = coreMock.createStart(); diff --git a/x-pack/plugins/spaces/server/routes/api/external/post.test.ts b/x-pack/plugins/spaces/server/routes/api/external/post.test.ts index ca3afc04b9798..5e09308f07d31 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/post.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/post.test.ts @@ -10,7 +10,7 @@ import { mockRouteContext, mockRouteContextWithInvalidLicense, } from '../__fixtures__'; -import { CoreSetup, kibanaResponseFactory, IRouter, RouteValidatorConfig } from 'src/core/server'; +import { CoreSetup, kibanaResponseFactory, RouteValidatorConfig } from 'src/core/server'; import { loggingServiceMock, httpServerMock, @@ -30,7 +30,7 @@ describe('Spaces Public API', () => { const setup = async () => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); const coreStart = coreMock.createStart(); diff --git a/x-pack/plugins/spaces/server/routes/api/external/put.test.ts b/x-pack/plugins/spaces/server/routes/api/external/put.test.ts index 62444fd3e4dfd..7b068d3784043 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/put.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/put.test.ts @@ -11,7 +11,7 @@ import { mockRouteContext, mockRouteContextWithInvalidLicense, } from '../__fixtures__'; -import { CoreSetup, IRouter, kibanaResponseFactory, RouteValidatorConfig } from 'src/core/server'; +import { CoreSetup, kibanaResponseFactory, RouteValidatorConfig } from 'src/core/server'; import { loggingServiceMock, httpServiceMock, @@ -31,7 +31,7 @@ describe('PUT /api/spaces/space', () => { const setup = async () => { const httpService = httpServiceMock.createSetupContract(); - const router = httpService.createRouter('') as jest.Mocked; + const router = httpService.createRouter(); const coreStart = coreMock.createStart(); From e552a96121112f37f970ef4395d67eaf3a27c7b0 Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Thu, 18 Jun 2020 08:16:39 -0600 Subject: [PATCH 4/5] [SIEM] Fixes REST formatter bugs from io-ts migration ## Summary Fixes io-ts formatter bugs for REST and validation by: * First trying to get the correct key from the io-ts context. If no keys are found, then it will fall back on trying to get the first name from the context. * If the key is a value and an object then this will do a `JSON.stringify()` on the value object * This fixes a few places where `formatError` was not being used within the code base resulting in `[object Object]` within the validations to show up. ### Checklist - [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios --- .../schemas/types/default_comments_array.ts | 8 ++-- .../schemas/types/default_entries_array.ts | 4 +- .../common/schemas/types/default_namespace.ts | 4 +- .../add_prepackged_rules_schema.test.ts | 39 ++++++++++-------- .../request/create_rules_bulk_schema.test.ts | 3 +- .../request/create_rules_schema.test.ts | 39 ++++++++++-------- .../request/export_rules_schema.test.ts | 12 +++--- .../request/import_rules_schema.test.ts | 41 ++++++++++--------- .../request/patch_rules_bulk_schema.test.ts | 3 +- .../request/patch_rules_schema.test.ts | 3 +- .../request/update_rules_bulk_schema.test.ts | 3 +- .../request/update_rules_schema.test.ts | 39 ++++++++++-------- .../types/deafult_boolean_true.test.ts | 4 +- .../schemas/types/deafult_from_string.test.ts | 4 +- .../types/default_actions_array.test.ts | 4 +- .../schemas/types/default_actions_array.ts | 3 +- .../types/default_boolean_false.test.ts | 4 +- .../schemas/types/default_boolean_false.ts | 4 +- .../schemas/types/default_boolean_true.ts | 3 +- .../types/default_empty_string.test.ts | 4 +- .../schemas/types/default_empty_string.ts | 3 +- .../types/default_export_file_name.test.ts | 4 +- .../schemas/types/default_export_file_name.ts | 4 +- .../schemas/types/default_from_string.ts | 4 +- .../types/default_interval_string.test.ts | 4 +- .../schemas/types/default_interval_string.ts | 3 +- .../types/default_language_string.test.ts | 4 +- .../schemas/types/default_language_string.ts | 4 +- .../types/default_max_signals_number.test.ts | 12 ++++-- .../types/default_max_signals_number.ts | 4 +- .../schemas/types/default_page.test.ts | 16 ++++++-- .../schemas/types/default_page.ts | 6 +-- .../schemas/types/default_per_page.test.ts | 16 ++++++-- .../schemas/types/default_per_page.ts | 6 +-- .../types/default_string_array.test.ts | 4 +- .../schemas/types/default_string_array.ts | 4 +- .../default_string_boolean_false.test.ts | 12 ++++-- .../types/default_string_boolean_false.ts | 4 +- .../types/default_threat_array.test.ts | 4 +- .../schemas/types/default_threat_array.ts | 3 +- .../types/default_throttle_null.test.ts | 4 +- .../schemas/types/default_throttle_null.ts | 4 +- .../schemas/types/default_to_string.test.ts | 4 +- .../schemas/types/default_to_string.ts | 5 ++- .../schemas/types/default_uuid.test.ts | 2 +- .../schemas/types/default_uuid.ts | 4 +- .../types/default_version_number.test.ts | 12 ++++-- .../schemas/types/default_version_number.ts | 3 +- .../schemas/types/iso_date_string.test.ts | 8 ++-- .../schemas/types/lists_default_array.test.ts | 4 +- .../schemas/types/lists_default_array.ts | 4 +- .../schemas/types/non_empty_string.test.ts | 12 ++++-- .../schemas/types/only_false_allowed.test.ts | 8 +++- ...positive_integer_greater_than_zero.test.ts | 12 ++++-- .../schemas/types/postive_integer.test.ts | 8 +++- .../types/references_default_array.test.ts | 4 +- .../schemas/types/references_default_array.ts | 4 +- .../schemas/types/risk_score.test.ts | 8 ++-- .../schemas/types/uuid.test.ts | 4 +- .../common/format_errors.test.ts | 41 +++++++++++++++++++ .../security_solution/common/format_errors.ts | 10 ++++- .../routes/rules/import_rules_route.test.ts | 6 +-- .../create_rules_stream_from_ndjson.test.ts | 3 +- .../rules/create_rules_stream_from_ndjson.ts | 3 +- .../rules/get_prepackaged_rules.test.ts | 6 +-- .../rules/get_prepackaged_rules.ts | 9 ++-- .../read_stream/create_stream_from_ndjson.ts | 3 +- 67 files changed, 343 insertions(+), 201 deletions(-) diff --git a/x-pack/plugins/lists/common/schemas/types/default_comments_array.ts b/x-pack/plugins/lists/common/schemas/types/default_comments_array.ts index a80bb968561f0..e824d481b3618 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_comments_array.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_comments_array.ts @@ -27,8 +27,8 @@ export const DefaultCommentsArray: DefaultCommentsArrayC = new t.Type< >( 'DefaultCommentsArray', t.array(comment).is, - (input): Either => - input == null ? t.success([]) : t.array(comment).decode(input), + (input, context): Either => + input == null ? t.success([]) : t.array(comment).validate(input, context), t.identity ); @@ -43,7 +43,7 @@ export const DefaultCommentsPartialArray: DefaultCommentsPartialArrayC = new t.T >( 'DefaultCommentsPartialArray', t.array(commentPartial).is, - (input): Either => - input == null ? t.success([]) : t.array(commentPartial).decode(input), + (input, context): Either => + input == null ? t.success([]) : t.array(commentPartial).validate(input, context), t.identity ); diff --git a/x-pack/plugins/lists/common/schemas/types/default_entries_array.ts b/x-pack/plugins/lists/common/schemas/types/default_entries_array.ts index 43698665bb371..82487f04804f1 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_entries_array.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_entries_array.ts @@ -22,7 +22,7 @@ export const DefaultEntryArray: DefaultEntriesArrayC = new t.Type< >( 'DefaultEntryArray', t.array(entries).is, - (input): Either => - input == null ? t.success([]) : t.array(entries).decode(input), + (input, context): Either => + input == null ? t.success([]) : t.array(entries).validate(input, context), t.identity ); diff --git a/x-pack/plugins/lists/common/schemas/types/default_namespace.ts b/x-pack/plugins/lists/common/schemas/types/default_namespace.ts index ebe2cd60cf6c8..c98cb8d2bba72 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_namespace.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_namespace.ts @@ -24,7 +24,7 @@ export const DefaultNamespace: DefaultNamespaceC = new t.Type< >( 'DefaultNamespace', namespaceType.is, - (input): Either => - input == null ? t.success('single') : namespaceType.decode(input), + (input, context): Either => + input == null ? t.success('single') : namespaceType.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackged_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackged_rules_schema.test.ts index 5d170f5a78645..f946b3ad3b39b 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackged_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackged_rules_schema.test.ts @@ -625,7 +625,7 @@ describe('add prepackaged rules schema', () => { const decoded = addPrepackagedRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "references"']); expect(message.schema).toEqual({}); }); @@ -776,7 +776,9 @@ describe('add prepackaged rules schema', () => { const decoded = addPrepackagedRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "-1" supplied to "max_signals"', + ]); expect(message.schema).toEqual({}); }); @@ -789,7 +791,7 @@ describe('add prepackaged rules schema', () => { const decoded = addPrepackagedRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to "max_signals"']); expect(message.schema).toEqual({}); }); @@ -837,9 +839,9 @@ describe('add prepackaged rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "0" supplied to ""', - 'Invalid value "1" supplied to ""', - 'Invalid value "2" supplied to ""', + 'Invalid value "0" supplied to "tags"', + 'Invalid value "1" supplied to "tags"', + 'Invalid value "2" supplied to "tags"', ]); expect(message.schema).toEqual({}); }); @@ -871,7 +873,7 @@ describe('add prepackaged rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "framework"', + 'Invalid value "undefined" supplied to "threat,framework"', ]); expect(message.schema).toEqual({}); }); @@ -899,7 +901,7 @@ describe('add prepackaged rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "tactic"', + 'Invalid value "undefined" supplied to "threat,tactic"', ]); expect(message.schema).toEqual({}); }); @@ -925,7 +927,7 @@ describe('add prepackaged rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "technique"', + 'Invalid value "undefined" supplied to "threat,technique"', ]); expect(message.schema).toEqual({}); }); @@ -959,8 +961,8 @@ describe('add prepackaged rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "5" supplied to ""', - 'Invalid value "4" supplied to ""', + 'Invalid value "5" supplied to "false_positives"', + 'Invalid value "4" supplied to "false_positives"', ]); expect(message.schema).toEqual({}); }); @@ -1184,7 +1186,7 @@ describe('add prepackaged rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "group"', + 'Invalid value "undefined" supplied to "actions,group"', ]); expect(message.schema).toEqual({}); }); @@ -1198,7 +1200,9 @@ describe('add prepackaged rules schema', () => { const decoded = addPrepackagedRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "actions,id"', + ]); expect(message.schema).toEqual({}); }); @@ -1212,7 +1216,7 @@ describe('add prepackaged rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "action_type_id"', + 'Invalid value "undefined" supplied to "actions,action_type_id"', ]); expect(message.schema).toEqual({}); }); @@ -1227,7 +1231,7 @@ describe('add prepackaged rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "params"', + 'Invalid value "undefined" supplied to "actions,params"', ]); expect(message.schema).toEqual({}); }); @@ -1249,7 +1253,7 @@ describe('add prepackaged rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "action_type_id"', + 'Invalid value "undefined" supplied to "actions,action_type_id"', ]); expect(message.schema).toEqual({}); }); @@ -1323,8 +1327,7 @@ describe('add prepackaged rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - // TODO: Fix/Change the formatErrors to be better able to handle objects - 'Invalid value "[object Object]" supplied to "note"', + 'Invalid value "{"somethingHere":"something else"}" supplied to "note"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts index e79dde41752a3..00854f1ed5526 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts @@ -250,9 +250,8 @@ describe('create_rules_bulk_schema', () => { const decoded = createRulesBulkSchema.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); - // TODO: We should change the formatter used to better print objects expect(formatErrors(output.errors)).toEqual([ - 'Invalid value "[object Object]" supplied to "note"', + 'Invalid value "{"something":"some object"}" supplied to "note"', ]); expect(output.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts index d672d38028902..a126b833ba461 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts @@ -614,7 +614,7 @@ describe('create rules schema', () => { const decoded = createRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "references"']); expect(message.schema).toEqual({}); }); @@ -721,7 +721,9 @@ describe('create rules schema', () => { const decoded = createRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "-1" supplied to "max_signals"', + ]); expect(message.schema).toEqual({}); }); @@ -734,7 +736,7 @@ describe('create rules schema', () => { const decoded = createRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to "max_signals"']); expect(message.schema).toEqual({}); }); @@ -782,9 +784,9 @@ describe('create rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "0" supplied to ""', - 'Invalid value "1" supplied to ""', - 'Invalid value "2" supplied to ""', + 'Invalid value "0" supplied to "tags"', + 'Invalid value "1" supplied to "tags"', + 'Invalid value "2" supplied to "tags"', ]); expect(message.schema).toEqual({}); }); @@ -816,7 +818,7 @@ describe('create rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "framework"', + 'Invalid value "undefined" supplied to "threat,framework"', ]); expect(message.schema).toEqual({}); }); @@ -844,7 +846,7 @@ describe('create rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "tactic"', + 'Invalid value "undefined" supplied to "threat,tactic"', ]); expect(message.schema).toEqual({}); }); @@ -870,7 +872,7 @@ describe('create rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "technique"', + 'Invalid value "undefined" supplied to "threat,technique"', ]); expect(message.schema).toEqual({}); }); @@ -902,8 +904,8 @@ describe('create rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "5" supplied to ""', - 'Invalid value "4" supplied to ""', + 'Invalid value "5" supplied to "false_positives"', + 'Invalid value "4" supplied to "false_positives"', ]); expect(message.schema).toEqual({}); }); @@ -1081,7 +1083,7 @@ describe('create rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "group"', + 'Invalid value "undefined" supplied to "actions,group"', ]); expect(message.schema).toEqual({}); }); @@ -1095,7 +1097,9 @@ describe('create rules schema', () => { const decoded = createRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "actions,id"', + ]); expect(message.schema).toEqual({}); }); @@ -1109,7 +1113,7 @@ describe('create rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "action_type_id"', + 'Invalid value "undefined" supplied to "actions,action_type_id"', ]); expect(message.schema).toEqual({}); }); @@ -1124,7 +1128,7 @@ describe('create rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "params"', + 'Invalid value "undefined" supplied to "actions,params"', ]); expect(message.schema).toEqual({}); }); @@ -1146,7 +1150,7 @@ describe('create rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "action_type_id"', + 'Invalid value "undefined" supplied to "actions,action_type_id"', ]); expect(message.schema).toEqual({}); }); @@ -1198,8 +1202,7 @@ describe('create rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - // TODO: Fix/Change the formatErrors to be better able to handle objects - 'Invalid value "[object Object]" supplied to "note"', + 'Invalid value "{"somethingHere":"something else"}" supplied to "note"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.test.ts index 3e9799a5ad2f9..935b4b33081fa 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.test.ts @@ -34,10 +34,9 @@ describe('create rules schema', () => { const decoded = exportRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - // TODO: Change formatter to display a better value than [object Object] expect(getPaths(left(message.errors))).toEqual([ 'Invalid value "undefined" supplied to "objects"', - 'Invalid value "[object Object]" supplied to ""', + 'Invalid value "{}" supplied to "({| objects: Array<{| rule_id: string |}> |} | null)"', ]); expect(message.schema).toEqual(payload); }); @@ -70,10 +69,9 @@ describe('create rules schema', () => { const decoded = exportRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - // TODO: Change formatter to display a better value than [object Object] expect(getPaths(left(message.errors))).toEqual([ 'Invalid value "undefined" supplied to "objects,rule_id"', - 'Invalid value "[object Object]" supplied to ""', + 'Invalid value "{"objects":[{"id":"4a7ff83d-3055-4bb2-ba68-587b9c6c15a4"}]}" supplied to "({| objects: Array<{| rule_id: string |}> |} | null)"', ]); expect(message.schema).toEqual({}); }); @@ -120,7 +118,9 @@ describe('create rules schema', () => { const decoded = exportRulesQuerySchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "10" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "10" supplied to "file_name"', + ]); expect(message.schema).toEqual({}); }); @@ -151,7 +151,7 @@ describe('create rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "invalid string" supplied to ""', + 'Invalid value "invalid string" supplied to "exclude_export_details"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts index be2c3e046fe91..9fe3e95a20621 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts @@ -625,7 +625,7 @@ describe('import rules schema', () => { const decoded = importRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "references"']); expect(message.schema).toEqual({}); }); @@ -773,7 +773,9 @@ describe('import rules schema', () => { const decoded = importRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "-1" supplied to "max_signals"', + ]); expect(message.schema).toEqual({}); }); @@ -786,7 +788,7 @@ describe('import rules schema', () => { const decoded = importRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to "max_signals"']); expect(message.schema).toEqual({}); }); @@ -834,9 +836,9 @@ describe('import rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "0" supplied to ""', - 'Invalid value "1" supplied to ""', - 'Invalid value "2" supplied to ""', + 'Invalid value "0" supplied to "tags"', + 'Invalid value "1" supplied to "tags"', + 'Invalid value "2" supplied to "tags"', ]); expect(message.schema).toEqual({}); }); @@ -868,7 +870,7 @@ describe('import rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "framework"', + 'Invalid value "undefined" supplied to "threat,framework"', ]); expect(message.schema).toEqual({}); }); @@ -896,7 +898,7 @@ describe('import rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "tactic"', + 'Invalid value "undefined" supplied to "threat,tactic"', ]); expect(message.schema).toEqual({}); }); @@ -922,7 +924,7 @@ describe('import rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "technique"', + 'Invalid value "undefined" supplied to "threat,technique"', ]); expect(message.schema).toEqual({}); }); @@ -954,8 +956,8 @@ describe('import rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "5" supplied to ""', - 'Invalid value "4" supplied to ""', + 'Invalid value "5" supplied to "false_positives"', + 'Invalid value "4" supplied to "false_positives"', ]); expect(message.schema).toEqual({}); }); @@ -1254,7 +1256,7 @@ describe('import rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "invalid-string" supplied to ""', + 'Invalid value "invalid-string" supplied to "overwrite"', ]); expect(message.schema).toEqual({}); }); @@ -1377,7 +1379,7 @@ describe('import rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "group"', + 'Invalid value "undefined" supplied to "actions,group"', ]); expect(message.schema).toEqual({}); }); @@ -1391,7 +1393,9 @@ describe('import rules schema', () => { const decoded = importRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "actions,id"', + ]); expect(message.schema).toEqual({}); }); @@ -1405,7 +1409,7 @@ describe('import rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "action_type_id"', + 'Invalid value "undefined" supplied to "actions,action_type_id"', ]); expect(message.schema).toEqual({}); }); @@ -1420,7 +1424,7 @@ describe('import rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "params"', + 'Invalid value "undefined" supplied to "actions,params"', ]); expect(message.schema).toEqual({}); }); @@ -1442,7 +1446,7 @@ describe('import rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "action_type_id"', + 'Invalid value "undefined" supplied to "actions,action_type_id"', ]); expect(message.schema).toEqual({}); }); @@ -1513,8 +1517,7 @@ describe('import rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - // TODO: Fix/Change the formatErrors to be better able to handle objects - 'Invalid value "[object Object]" supplied to "note"', + 'Invalid value "{"somethingHere":"something else"}" supplied to "note"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.test.ts index 7b86c02e5c475..a03bb2db0fd4b 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.test.ts @@ -92,9 +92,8 @@ describe('patch_rules_bulk_schema', () => { const decoded = patchRulesBulkSchema.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); - // TODO: Fix the formatter to give something better than [object Object] expect(formatErrors(output.errors)).toEqual([ - 'Invalid value "[object Object]" supplied to "note"', + 'Invalid value "{"someprop":"some value here"}" supplied to "note"', ]); expect(output.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts index 921e07a29609c..55363ffb18307 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts @@ -1065,9 +1065,8 @@ describe('patch_rules_schema', () => { const decoded = patchRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - // TODO: Change the formatter to output something more readable than [object Object] expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "[object Object]" supplied to "note"', + 'Invalid value "{"someProperty":"something else here"}" supplied to "note"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts index edc652ce3b3f4..4cb38889045fc 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts @@ -246,9 +246,8 @@ describe('update_rules_bulk_schema', () => { const decoded = updateRulesBulkSchema.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); - // TODO: We should change the formatter used to better print objects expect(formatErrors(output.errors)).toEqual([ - 'Invalid value "[object Object]" supplied to "note"', + 'Invalid value "{"something":"some object"}" supplied to "note"', ]); expect(output.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts index e60522e1964f4..1ff38f1351f59 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts @@ -608,7 +608,7 @@ describe('update rules schema', () => { const decoded = updateRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "references"']); expect(message.schema).toEqual({}); }); @@ -756,7 +756,9 @@ describe('update rules schema', () => { const decoded = updateRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "-1" supplied to "max_signals"', + ]); expect(message.schema).toEqual({}); }); @@ -769,7 +771,7 @@ describe('update rules schema', () => { const decoded = updateRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to "max_signals"']); expect(message.schema).toEqual({}); }); @@ -817,9 +819,9 @@ describe('update rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "0" supplied to ""', - 'Invalid value "1" supplied to ""', - 'Invalid value "2" supplied to ""', + 'Invalid value "0" supplied to "tags"', + 'Invalid value "1" supplied to "tags"', + 'Invalid value "2" supplied to "tags"', ]); expect(message.schema).toEqual({}); }); @@ -851,7 +853,7 @@ describe('update rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "framework"', + 'Invalid value "undefined" supplied to "threat,framework"', ]); expect(message.schema).toEqual({}); }); @@ -879,7 +881,7 @@ describe('update rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "tactic"', + 'Invalid value "undefined" supplied to "threat,tactic"', ]); expect(message.schema).toEqual({}); }); @@ -905,7 +907,7 @@ describe('update rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "technique"', + 'Invalid value "undefined" supplied to "threat,technique"', ]); expect(message.schema).toEqual({}); }); @@ -937,8 +939,8 @@ describe('update rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "5" supplied to ""', - 'Invalid value "4" supplied to ""', + 'Invalid value "5" supplied to "false_positives"', + 'Invalid value "4" supplied to "false_positives"', ]); expect(message.schema).toEqual({}); }); @@ -1173,7 +1175,7 @@ describe('update rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "group"', + 'Invalid value "undefined" supplied to "actions,group"', ]); expect(message.schema).toEqual({}); }); @@ -1187,7 +1189,9 @@ describe('update rules schema', () => { const decoded = updateRulesSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "actions,id"', + ]); expect(message.schema).toEqual({}); }); @@ -1201,7 +1205,7 @@ describe('update rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "action_type_id"', + 'Invalid value "undefined" supplied to "actions,action_type_id"', ]); expect(message.schema).toEqual({}); }); @@ -1216,7 +1220,7 @@ describe('update rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "params"', + 'Invalid value "undefined" supplied to "actions,params"', ]); expect(message.schema).toEqual({}); }); @@ -1238,7 +1242,7 @@ describe('update rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "action_type_id"', + 'Invalid value "undefined" supplied to "actions,action_type_id"', ]); expect(message.schema).toEqual({}); }); @@ -1323,8 +1327,7 @@ describe('update rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - // TODO: Fix/Change the formatErrors to be better able to handle objects - 'Invalid value "[object Object]" supplied to "note"', + 'Invalid value "{"somethingHere":"something else"}" supplied to "note"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_boolean_true.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_boolean_true.test.ts index a2deaf626624f..1f111515d391a 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_boolean_true.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_boolean_true.test.ts @@ -33,7 +33,9 @@ describe('default_boolean_true', () => { const decoded = DefaultBooleanTrue.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultBooleanTrue"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_from_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_from_string.test.ts index d68d447ca4454..3862fcb95b91d 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_from_string.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_from_string.test.ts @@ -24,7 +24,9 @@ describe('default_from_string', () => { const decoded = DefaultFromString.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultFromString"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.test.ts index 645eade71916f..ac22d36a062cb 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.test.ts @@ -39,7 +39,9 @@ describe('default_actions_array', () => { const decoded = DefaultActionsArray.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultActionsArray"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.ts index ce3eb7fa7da83..c69ae591f5ddc 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.ts @@ -15,7 +15,8 @@ import { actions, Actions } from '../common/schemas'; export const DefaultActionsArray = new t.Type( 'DefaultActionsArray', actions.is, - (input): Either => (input == null ? t.success([]) : actions.decode(input)), + (input, context): Either => + input == null ? t.success([]) : actions.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.test.ts index 1697928b17e0c..954a0f3651048 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.test.ts @@ -33,7 +33,9 @@ describe('default_boolean_false', () => { const decoded = DefaultBooleanFalse.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultBooleanFalse"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.ts index 624b9802f680c..0cab6525779a6 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.ts @@ -14,8 +14,8 @@ import { Either } from 'fp-ts/lib/Either'; export const DefaultBooleanFalse = new t.Type( 'DefaultBooleanFalse', t.boolean.is, - (input): Either => - input == null ? t.success(false) : t.boolean.decode(input), + (input, context): Either => + input == null ? t.success(false) : t.boolean.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_true.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_true.ts index 58c912a0a8650..6997652b72636 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_true.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_true.ts @@ -14,7 +14,8 @@ import { Either } from 'fp-ts/lib/Either'; export const DefaultBooleanTrue = new t.Type( 'DefaultBooleanTrue', t.boolean.is, - (input): Either => (input == null ? t.success(true) : t.boolean.decode(input)), + (input, context): Either => + input == null ? t.success(true) : t.boolean.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.test.ts index 386d4c55905cd..4c59ae44fb8d8 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.test.ts @@ -24,7 +24,9 @@ describe('default_empty_string', () => { const decoded = DefaultEmptyString.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultEmptyString"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.ts index 6216d0c1111b0..a1103c4aa8d0e 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.ts @@ -14,7 +14,8 @@ import { Either } from 'fp-ts/lib/Either'; export const DefaultEmptyString = new t.Type( 'DefaultEmptyString', t.string.is, - (input): Either => (input == null ? t.success('') : t.string.decode(input)), + (input, context): Either => + input == null ? t.success('') : t.string.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.test.ts index 328cd738d7de0..70aa9501a3080 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.test.ts @@ -24,7 +24,9 @@ describe('default_export_file_name', () => { const decoded = DefaultExportFileName.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultExportFileName"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.ts index 41dfdee1e0da0..4c7f663e7f46d 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.ts @@ -14,8 +14,8 @@ import { Either } from 'fp-ts/lib/Either'; export const DefaultExportFileName = new t.Type( 'DefaultExportFileName', t.string.is, - (input): Either => - input == null ? t.success('export.ndjson') : t.string.decode(input), + (input, context): Either => + input == null ? t.success('export.ndjson') : t.string.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_from_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_from_string.ts index 4217532de954e..b6b432858eb92 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_from_string.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_from_string.ts @@ -14,8 +14,8 @@ import { Either } from 'fp-ts/lib/Either'; export const DefaultFromString = new t.Type( 'DefaultFromString', t.string.is, - (input): Either => - input == null ? t.success('now-6m') : t.string.decode(input), + (input, context): Either => + input == null ? t.success('now-6m') : t.string.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.test.ts index 9720178a4ae9b..c7cda54a54b04 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.test.ts @@ -24,7 +24,9 @@ describe('default_interval_string', () => { const decoded = DefaultIntervalString.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultIntervalString"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.ts index 579e7591fdb03..9492374ffe91e 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.ts @@ -14,7 +14,8 @@ import { Either } from 'fp-ts/lib/Either'; export const DefaultIntervalString = new t.Type( 'DefaultIntervalString', t.string.is, - (input): Either => (input == null ? t.success('5m') : t.string.decode(input)), + (input, context): Either => + input == null ? t.success('5m') : t.string.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.test.ts index e3da8dbd280ab..e210bcf7d881f 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.test.ts @@ -25,7 +25,9 @@ describe('default_language_string', () => { const decoded = DefaultLanguageString.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultLanguageString"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.ts index 248e15d56dfd7..1e05a46d7273c 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.ts @@ -15,8 +15,8 @@ import { language } from '../common/schemas'; export const DefaultLanguageString = new t.Type( 'DefaultLanguageString', t.string.is, - (input): Either => - input == null ? t.success('kuery') : language.decode(input), + (input, context): Either => + input == null ? t.success('kuery') : language.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.test.ts index a6f137c3f2113..33ac02ee1bf53 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.test.ts @@ -25,7 +25,9 @@ describe('default_from_string', () => { const decoded = DefaultMaxSignalsNumber.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultMaxSignals"', + ]); expect(message.schema).toEqual({}); }); @@ -34,7 +36,9 @@ describe('default_from_string', () => { const decoded = DefaultMaxSignalsNumber.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "0" supplied to "DefaultMaxSignals"', + ]); expect(message.schema).toEqual({}); }); @@ -43,7 +47,9 @@ describe('default_from_string', () => { const decoded = DefaultMaxSignalsNumber.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "-1" supplied to "DefaultMaxSignals"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts index 6f0c32c5466f3..d3c48b5522f57 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts @@ -23,8 +23,8 @@ export const DefaultMaxSignalsNumber: DefaultMaxSignalsNumberC = new t.Type< >( 'DefaultMaxSignals', t.number.is, - (input): Either => { - return input == null ? t.success(DEFAULT_MAX_SIGNALS) : max_signals.decode(input); + (input, context): Either => { + return input == null ? t.success(DEFAULT_MAX_SIGNALS) : max_signals.validate(input, context); }, t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.test.ts index 1d1d43667c710..dd90813646319 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.test.ts @@ -33,7 +33,9 @@ describe('default_page', () => { const decoded = DefaultPage.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "NaN" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "NaN" supplied to "DefaultPerPage"', + ]); expect(message.schema).toEqual({}); }); @@ -42,7 +44,9 @@ describe('default_page', () => { const decoded = DefaultPage.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "NaN" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "NaN" supplied to "DefaultPerPage"', + ]); expect(message.schema).toEqual({}); }); @@ -51,7 +55,9 @@ describe('default_page', () => { const decoded = DefaultPage.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "0" supplied to "DefaultPerPage"', + ]); expect(message.schema).toEqual({}); }); @@ -60,7 +66,9 @@ describe('default_page', () => { const decoded = DefaultPage.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "-1" supplied to "DefaultPerPage"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.ts index 95e3b42f3e138..96e01d381e34b 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.ts @@ -17,13 +17,13 @@ import { PositiveIntegerGreaterThanZero } from './positive_integer_greater_than_ export const DefaultPage = new t.Type( 'DefaultPerPage', t.number.is, - (input): Either => { + (input, context): Either => { if (input == null) { return t.success(1); } else if (typeof input === 'string') { - return PositiveIntegerGreaterThanZero.decode(parseInt(input, 10)); + return PositiveIntegerGreaterThanZero.validate(parseInt(input, 10), context); } else { - return PositiveIntegerGreaterThanZero.decode(input); + return PositiveIntegerGreaterThanZero.validate(input, context); } }, t.identity diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.test.ts index 3ecbae6ed43f5..2115d6d3b52ef 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.test.ts @@ -33,7 +33,9 @@ describe('default_per_page', () => { const decoded = DefaultPerPage.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "NaN" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "NaN" supplied to "DefaultPerPage"', + ]); expect(message.schema).toEqual({}); }); @@ -42,7 +44,9 @@ describe('default_per_page', () => { const decoded = DefaultPerPage.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "NaN" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "NaN" supplied to "DefaultPerPage"', + ]); expect(message.schema).toEqual({}); }); @@ -51,7 +55,9 @@ describe('default_per_page', () => { const decoded = DefaultPerPage.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "0" supplied to "DefaultPerPage"', + ]); expect(message.schema).toEqual({}); }); @@ -60,7 +66,9 @@ describe('default_per_page', () => { const decoded = DefaultPerPage.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "-1" supplied to "DefaultPerPage"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.ts index f96f280f6af11..b78de8b35cede 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.ts @@ -17,13 +17,13 @@ import { PositiveIntegerGreaterThanZero } from './positive_integer_greater_than_ export const DefaultPerPage = new t.Type( 'DefaultPerPage', t.number.is, - (input): Either => { + (input, context): Either => { if (input == null) { return t.success(20); } else if (typeof input === 'string') { - return PositiveIntegerGreaterThanZero.decode(parseInt(input, 10)); + return PositiveIntegerGreaterThanZero.validate(parseInt(input, 10), context); } else { - return PositiveIntegerGreaterThanZero.decode(input); + return PositiveIntegerGreaterThanZero.validate(input, context); } }, t.identity diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.test.ts index 83142c8d65777..6d352f3ffc4ba 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.test.ts @@ -33,7 +33,9 @@ describe('default_string_array', () => { const decoded = DefaultStringArray.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultStringArray"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.ts index 1f043cfd1b8e5..a8c53c230acd9 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.ts @@ -14,8 +14,8 @@ import { Either } from 'fp-ts/lib/Either'; export const DefaultStringArray = new t.Type( 'DefaultStringArray', t.array(t.string).is, - (input): Either => - input == null ? t.success([]) : t.array(t.string).decode(input), + (input, context): Either => + input == null ? t.success([]) : t.array(t.string).validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.test.ts index 1941a642e8baf..dcb264d77b14b 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.test.ts @@ -33,7 +33,9 @@ describe('default_string_boolean_false', () => { const decoded = DefaultStringBooleanFalse.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultStringBooleanFalse"', + ]); expect(message.schema).toEqual({}); }); @@ -78,7 +80,9 @@ describe('default_string_boolean_false', () => { const decoded = DefaultStringBooleanFalse.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "junk" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "junk" supplied to "DefaultStringBooleanFalse"', + ]); expect(message.schema).toEqual({}); }); @@ -87,7 +91,9 @@ describe('default_string_boolean_false', () => { const decoded = DefaultStringBooleanFalse.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "" supplied to "DefaultStringBooleanFalse"', + ]); expect(message.schema).toEqual({}); }); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.ts index 48a40d4b9ceec..aa070c171d7ea 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.ts @@ -15,7 +15,7 @@ import { Either } from 'fp-ts/lib/Either'; export const DefaultStringBooleanFalse = new t.Type( 'DefaultStringBooleanFalse', t.boolean.is, - (input): Either => { + (input, context): Either => { if (input == null) { return t.success(false); } else if (typeof input === 'string' && input.toLowerCase() === 'true') { @@ -23,7 +23,7 @@ export const DefaultStringBooleanFalse = new t.Type( } else if (typeof input === 'string' && input.toLowerCase() === 'false') { return t.success(false); } else { - return t.boolean.decode(input); + return t.boolean.validate(input, context); } }, t.identity diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.test.ts index 9819da0b8d463..42193128cccfa 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.test.ts @@ -47,7 +47,9 @@ describe('default_threat_null', () => { const decoded = DefaultThreatArray.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultThreatArray"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.ts index da0611e24bc7e..5499a3c1e3064 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.ts @@ -15,7 +15,8 @@ import { Threat, threat } from '../common/schemas'; export const DefaultThreatArray = new t.Type( 'DefaultThreatArray', threat.is, - (input): Either => (input == null ? t.success([]) : threat.decode(input)), + (input, context): Either => + input == null ? t.success([]) : threat.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.test.ts index 304fd65647c3c..5b08de40e0aa2 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.test.ts @@ -25,7 +25,9 @@ describe('default_throttle_null', () => { const decoded = DefaultThrottleNull.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultThreatNull"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.ts index fd31594323f4d..b76a35c0265a0 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.ts @@ -15,8 +15,8 @@ import { ThrottleOrNull, throttle } from '../common/schemas'; export const DefaultThrottleNull = new t.Type( 'DefaultThreatNull', throttle.is, - (input): Either => - input == null ? t.success(null) : throttle.decode(input), + (input, context): Either => + input == null ? t.success(null) : throttle.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.test.ts index 3e22d57cedf99..96c298c805ccb 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.test.ts @@ -24,7 +24,9 @@ describe('default_to_string', () => { const decoded = DefaultToString.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultToString"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.ts index 163bcf8c4e5b2..158eedc121c53 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.ts @@ -12,9 +12,10 @@ import { Either } from 'fp-ts/lib/Either'; * - If null or undefined, then a default of the string "now" will be used */ export const DefaultToString = new t.Type( - 'DefaultFromString', + 'DefaultToString', t.string.is, - (input): Either => (input == null ? t.success('now') : t.string.decode(input)), + (input, context): Either => + input == null ? t.success('now') : t.string.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.test.ts index 7dab8869d5d87..4bfeed479d582 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.test.ts @@ -24,7 +24,7 @@ describe('default_uuid', () => { const decoded = DefaultUuid.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "DefaultUuid"']); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.ts index b0c328a93ff03..74e32e083cc44 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.ts @@ -18,8 +18,8 @@ import { NonEmptyString } from './non_empty_string'; export const DefaultUuid = new t.Type( 'DefaultUuid', t.string.is, - (input): Either => - input == null ? t.success(uuid.v4()) : NonEmptyString.decode(input), + (input, context): Either => + input == null ? t.success(uuid.v4()) : NonEmptyString.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.test.ts index 65697d8830b66..6d701b94a9c4d 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.test.ts @@ -24,7 +24,9 @@ describe('default_version_number', () => { const decoded = DefaultVersionNumber.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "0" supplied to "DefaultVersionNumber"', + ]); expect(message.schema).toEqual({}); }); @@ -33,7 +35,9 @@ describe('default_version_number', () => { const decoded = DefaultVersionNumber.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "-1" supplied to "DefaultVersionNumber"', + ]); expect(message.schema).toEqual({}); }); @@ -42,7 +46,9 @@ describe('default_version_number', () => { const decoded = DefaultVersionNumber.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultVersionNumber"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts index 4a310329660df..832c942291c32 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts @@ -15,7 +15,8 @@ import { version, Version } from '../common/schemas'; export const DefaultVersionNumber = new t.Type( 'DefaultVersionNumber', version.is, - (input): Either => (input == null ? t.success(1) : version.decode(input)), + (input, context): Either => + input == null ? t.success(1) : version.validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/iso_date_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/iso_date_string.test.ts index e8bce3f38f4b3..ca9244419b286 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/iso_date_string.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/iso_date_string.test.ts @@ -25,7 +25,7 @@ describe('ios_date_string', () => { const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "1582677283067" supplied to ""', + 'Invalid value "1582677283067" supplied to "IsoDateString"', ]); expect(message.schema).toEqual({}); }); @@ -35,7 +35,9 @@ describe('ios_date_string', () => { const decoded = IsoDateString.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "2000" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "2000" supplied to "IsoDateString"', + ]); expect(message.schema).toEqual({}); }); @@ -45,7 +47,7 @@ describe('ios_date_string', () => { const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "Wed, 26 Feb 2020 00:36:20 GMT" supplied to ""', + 'Invalid value "Wed, 26 Feb 2020 00:36:20 GMT" supplied to "IsoDateString"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.test.ts index 31e0a8e5c2c73..9eb55c22756fa 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.test.ts @@ -173,8 +173,8 @@ describe('lists_default_array', () => { const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "5" supplied to ""', - 'Invalid value "5" supplied to ""', + 'Invalid value "5" supplied to "listsWithDefaultArray"', + 'Invalid value "5" supplied to "listsWithDefaultArray"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.ts index 8cdd865469112..7fe98cdc300ef 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.ts @@ -24,8 +24,8 @@ export type ListOperator = t.TypeOf; export const ListsDefaultArray = new t.Type( 'listsWithDefaultArray', t.array(listAnd).is, - (input): Either => - input == null ? t.success([]) : t.array(listAnd).decode(input), + (input, context): Either => + input == null ? t.success([]) : t.array(listAnd).validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/non_empty_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/non_empty_string.test.ts index 0a88b87421e70..0c12aa78cd247 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/non_empty_string.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/non_empty_string.test.ts @@ -24,7 +24,9 @@ describe('non_empty_string', () => { const decoded = NonEmptyString.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "NonEmptyString"', + ]); expect(message.schema).toEqual({}); }); @@ -33,7 +35,9 @@ describe('non_empty_string', () => { const decoded = NonEmptyString.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "" supplied to "NonEmptyString"', + ]); expect(message.schema).toEqual({}); }); @@ -42,7 +46,9 @@ describe('non_empty_string', () => { const decoded = NonEmptyString.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value " " supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value " " supplied to "NonEmptyString"', + ]); expect(message.schema).toEqual({}); }); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/only_false_allowed.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/only_false_allowed.test.ts index 01183e59378bd..a11fec1f064b1 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/only_false_allowed.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/only_false_allowed.test.ts @@ -24,7 +24,9 @@ describe('only_false_allowed', () => { const decoded = OnlyFalseAllowed.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "true" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "true" supplied to "DefaultBooleanTrue"', + ]); expect(message.schema).toEqual({}); }); @@ -33,7 +35,9 @@ describe('only_false_allowed', () => { const decoded = OnlyFalseAllowed.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultBooleanTrue"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer_greater_than_zero.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer_greater_than_zero.test.ts index 821eb066a6531..b67825b271216 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer_greater_than_zero.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer_greater_than_zero.test.ts @@ -24,7 +24,9 @@ describe('positive_integer_greater_than_zero', () => { const decoded = PositiveIntegerGreaterThanZero.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "0" supplied to "PositiveIntegerGreaterThanZero"', + ]); expect(message.schema).toEqual({}); }); @@ -33,7 +35,9 @@ describe('positive_integer_greater_than_zero', () => { const decoded = PositiveIntegerGreaterThanZero.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "-1" supplied to "PositiveIntegerGreaterThanZero"', + ]); expect(message.schema).toEqual({}); }); @@ -42,7 +46,9 @@ describe('positive_integer_greater_than_zero', () => { const decoded = PositiveIntegerGreaterThanZero.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "some string" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "some string" supplied to "PositiveIntegerGreaterThanZero"', + ]); expect(message.schema).toEqual({}); }); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/postive_integer.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/postive_integer.test.ts index ea00ecf5efe0d..7324f5ffda062 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/postive_integer.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/postive_integer.test.ts @@ -33,7 +33,9 @@ describe('positive_integer_greater_than_zero', () => { const decoded = PositiveInteger.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "-1" supplied to "PositiveInteger"', + ]); expect(message.schema).toEqual({}); }); @@ -42,7 +44,9 @@ describe('positive_integer_greater_than_zero', () => { const decoded = PositiveInteger.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "some string" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "some string" supplied to "PositiveInteger"', + ]); expect(message.schema).toEqual({}); }); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.test.ts index 83142c8d65777..6d352f3ffc4ba 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.test.ts @@ -33,7 +33,9 @@ describe('default_string_array', () => { const decoded = DefaultStringArray.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to "DefaultStringArray"', + ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.ts index b809181ce8c32..f246a26bdf4cb 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.ts @@ -14,8 +14,8 @@ import { Either } from 'fp-ts/lib/Either'; export const ReferencesDefaultArray = new t.Type( 'referencesWithDefaultArray', t.array(t.string).is, - (input): Either => - input == null ? t.success([]) : t.array(t.string).decode(input), + (input, context): Either => + input == null ? t.success([]) : t.array(t.string).validate(input, context), t.identity ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/risk_score.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/risk_score.test.ts index cf849f28a0963..c8bf3cbecdaaf 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/risk_score.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/risk_score.test.ts @@ -33,7 +33,7 @@ describe('risk_score', () => { const decoded = RiskScore.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to "RiskScore"']); expect(message.schema).toEqual({}); }); @@ -42,7 +42,9 @@ describe('risk_score', () => { const decoded = RiskScore.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "some string" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "some string" supplied to "RiskScore"', + ]); expect(message.schema).toEqual({}); }); @@ -51,7 +53,7 @@ describe('risk_score', () => { const decoded = RiskScore.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "101" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "101" supplied to "RiskScore"']); expect(message.schema).toEqual({}); }); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/uuid.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/uuid.test.ts index d3a68a7575487..2bfaa3603d6a7 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/uuid.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/uuid.test.ts @@ -25,7 +25,7 @@ describe('uuid', () => { const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "4656dc92-5832-11ea-8e2d" supplied to ""', + 'Invalid value "4656dc92-5832-11ea-8e2d" supplied to "UUID"', ]); expect(message.schema).toEqual({}); }); @@ -35,7 +35,7 @@ describe('uuid', () => { const decoded = UUID.decode(payload); const message = pipe(decoded, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to ""']); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "UUID"']); expect(message.schema).toEqual({}); }); }); diff --git a/x-pack/plugins/security_solution/common/format_errors.test.ts b/x-pack/plugins/security_solution/common/format_errors.test.ts index f9dd9e76a1d9c..c8cd72b72816b 100644 --- a/x-pack/plugins/security_solution/common/format_errors.test.ts +++ b/x-pack/plugins/security_solution/common/format_errors.test.ts @@ -127,4 +127,45 @@ describe('utils', () => { 'Invalid value "Some existing error 1" supplied to "some string key 2"', ]); }); + + test('will use a name context if it cannot find a keyContext', () => { + const context: t.Context = ([ + { key: '' }, + { key: '', type: { name: 'someName' } }, + ] as unknown) as t.Context; + const validationError1: t.ValidationError = { + value: 'Some existing error 1', + context, + }; + const errors: t.Errors = [validationError1]; + const output = formatErrors(errors); + expect(output).toEqual(['Invalid value "Some existing error 1" supplied to "someName"']); + }); + + test('will return an empty string if name does not exist but type does', () => { + const context: t.Context = ([{ key: '' }, { key: '', type: {} }] as unknown) as t.Context; + const validationError1: t.ValidationError = { + value: 'Some existing error 1', + context, + }; + const errors: t.Errors = [validationError1]; + const output = formatErrors(errors); + expect(output).toEqual(['Invalid value "Some existing error 1" supplied to ""']); + }); + + test('will stringify an error value', () => { + const context: t.Context = ([ + { key: '' }, + { key: 'some string key 2' }, + ] as unknown) as t.Context; + const validationError1: t.ValidationError = { + value: { foo: 'some error' }, + context, + }; + const errors: t.Errors = [validationError1]; + const output = formatErrors(errors); + expect(output).toEqual([ + 'Invalid value "{"foo":"some error"}" supplied to "some string key 2"', + ]); + }); }); diff --git a/x-pack/plugins/security_solution/common/format_errors.ts b/x-pack/plugins/security_solution/common/format_errors.ts index d712979f9eff3..ba963f34f2983 100644 --- a/x-pack/plugins/security_solution/common/format_errors.ts +++ b/x-pack/plugins/security_solution/common/format_errors.ts @@ -5,19 +5,25 @@ */ import * as t from 'io-ts'; +import { isObject } from 'lodash/fp'; export const formatErrors = (errors: t.Errors): string[] => { return errors.map((error) => { if (error.message != null) { return error.message; } else { - const mappedContext = error.context + const keyContext = error.context .filter( (entry) => entry.key != null && !Number.isInteger(+entry.key) && entry.key.trim() !== '' ) .map((entry) => entry.key) .join(','); - return `Invalid value "${error.value}" supplied to "${mappedContext}"`; + + const nameContext = error.context.find((entry) => entry.type?.name?.length > 0); + const suppliedValue = + keyContext !== '' ? keyContext : nameContext != null ? nameContext.type.name : ''; + const value = isObject(error.value) ? JSON.stringify(error.value) : error.value; + return `Invalid value "${value}" supplied to "${suppliedValue}"`; } }); }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts index 84148231431a1..a1cf9ccc45f38 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts @@ -254,16 +254,14 @@ describe('import_rules_route', () => { errors: [ { error: { - // TODO: Change the formatter to do better than output [object Object] - message: '[object Object]', + message: 'Invalid value "undefined" supplied to "rule_id"', status_code: 400, }, rule_id: '(unknown id)', }, { error: { - // TODO: Change the formatter to do better than output [object Object] - message: '[object Object]', + message: 'Invalid value "undefined" supplied to "rule_id"', status_code: 400, }, rule_id: '(unknown id)', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.test.ts index 73d3c65774b3d..c4d7df61061bd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.test.ts @@ -365,9 +365,8 @@ describe('create_rules_stream_from_ndjson', () => { references: [], version: 1, }); - // TODO: Change the formatter to output something better than [object Object] expect(resultOrError[1].message).toEqual( - '[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]' + 'Invalid value "undefined" supplied to "description",Invalid value "undefined" supplied to "risk_score",Invalid value "undefined" supplied to "name",Invalid value "undefined" supplied to "severity",Invalid value "undefined" supplied to "type",Invalid value "undefined" supplied to "rule_id"' ); expect(resultOrError[2]).toEqual({ actions: [], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.ts index 932a4ef9eed92..d7723232ca921 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.ts @@ -7,6 +7,7 @@ import { Transform } from 'stream'; import * as t from 'io-ts'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; +import { formatErrors } from '../../../../common/format_errors'; import { importRuleValidateTypeDependents } from '../../../../common/detection_engine/schemas/request/import_rules_type_dependents'; import { exactCheck } from '../../../../common/exact_check'; import { @@ -32,7 +33,7 @@ export const validateRules = (): Transform => { const decoded = importRulesSchema.decode(obj); const checked = exactCheck(obj, decoded); const onLeft = (errors: t.Errors): BadRequestError | ImportRulesSchemaDecoded => { - return new BadRequestError(errors.join()); + return new BadRequestError(formatErrors(errors).join()); }; const onRight = (schema: ImportRulesSchema): BadRequestError | ImportRulesSchemaDecoded => { const validationErrors = importRuleValidateTypeDependents(schema); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.test.ts index 597a74f6efbbd..ed1a239facf79 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.test.ts @@ -33,16 +33,14 @@ describe('get_existing_prepackaged_rules', () => { }); test('should throw an exception if a pre-packaged rule is not valid', () => { - // TODO: Improve the error formatter around [object Object] expect(() => getPrepackagedRules([{ not_valid_made_up_key: true }])).toThrow( - 'name: "(rule name unknown)", rule_id: "(rule rule_id unknown)" within the folder rules/prepackaged_rules is not a valid detection engine rule. Expect the system to not work with pre-packaged rules until this rule is fixed or the file is removed. Error is: [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object], Full rule contents are:\n{\n "not_valid_made_up_key": true\n}' + 'name: "(rule name unknown)", rule_id: "(rule rule_id unknown)" within the folder rules/prepackaged_rules is not a valid detection engine rule. Expect the system to not work with pre-packaged rules until this rule is fixed or the file is removed. Error is: Invalid value "undefined" supplied to "description",Invalid value "undefined" supplied to "risk_score",Invalid value "undefined" supplied to "name",Invalid value "undefined" supplied to "severity",Invalid value "undefined" supplied to "type",Invalid value "undefined" supplied to "rule_id",Invalid value "undefined" supplied to "version", Full rule contents are:\n{\n "not_valid_made_up_key": true\n}' ); }); test('should throw an exception with a message having rule_id and name in it', () => { - // TODO: Improve the error formatter around [object Object] expect(() => getPrepackagedRules([{ name: 'rule name', rule_id: 'id-123' }])).toThrow( - 'name: "rule name", rule_id: "id-123" within the folder rules/prepackaged_rules is not a valid detection engine rule. Expect the system to not work with pre-packaged rules until this rule is fixed or the file is removed. Error is: [object Object],[object Object],[object Object],[object Object],[object Object], Full rule contents are:\n{\n "name": "rule name",\n "rule_id": "id-123"\n}' + 'name: "rule name", rule_id: "id-123" within the folder rules/prepackaged_rules is not a valid detection engine rule. Expect the system to not work with pre-packaged rules until this rule is fixed or the file is removed. Error is: Invalid value "undefined" supplied to "description",Invalid value "undefined" supplied to "risk_score",Invalid value "undefined" supplied to "severity",Invalid value "undefined" supplied to "type",Invalid value "undefined" supplied to "version", Full rule contents are:\n{\n "name": "rule name",\n "rule_id": "id-123"\n}' ); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.ts index d2af93c329636..354f8b90fae23 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.ts @@ -7,6 +7,7 @@ import * as t from 'io-ts'; import { fold } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; +import { formatErrors } from '../../../../common/format_errors'; import { exactCheck } from '../../../../common/exact_check'; import { addPrepackagedRulesSchema, @@ -35,11 +36,9 @@ export const validateAllPrepackagedRules = ( `name: "${ruleName}", rule_id: "${ruleId}" within the folder rules/prepackaged_rules ` + `is not a valid detection engine rule. Expect the system ` + `to not work with pre-packaged rules until this rule is fixed ` + - `or the file is removed. Error is: ${errors.join()}, Full rule contents are:\n${JSON.stringify( - rule, - null, - 2 - )}` + `or the file is removed. Error is: ${formatErrors( + errors + ).join()}, Full rule contents are:\n${JSON.stringify(rule, null, 2)}` ); }; diff --git a/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.ts b/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.ts index f455ac0696e4e..0eb021bfe2a83 100644 --- a/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.ts +++ b/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.ts @@ -8,6 +8,7 @@ import { has, isString } from 'lodash/fp'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import * as t from 'io-ts'; +import { formatErrors } from '../../../common/format_errors'; import { importRuleValidateTypeDependents } from '../../../common/detection_engine/schemas/request/import_rules_type_dependents'; import { ImportRulesSchemaDecoded, @@ -47,7 +48,7 @@ export const validateRules = (): Transform => { const decoded = importRulesSchema.decode(obj); const checked = exactCheck(obj, decoded); const onLeft = (errors: t.Errors): BadRequestError | ImportRulesSchemaDecoded => { - return new BadRequestError(errors.join()); + return new BadRequestError(formatErrors(errors).join()); }; const onRight = (schema: ImportRulesSchema): BadRequestError | ImportRulesSchemaDecoded => { const validationErrors = importRuleValidateTypeDependents(schema); From 72111702e95214594d5d56bc856e1d5c78e6d802 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 18 Jun 2020 17:13:28 +0200 Subject: [PATCH 5/5] [RUM Dashboard] Initial Version (#68778) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Casper Hübertz --- .../elasticsearch_fieldnames.test.ts.snap | 24 +++ .../apm/common/elasticsearch_fieldnames.ts | 6 + .../plugins/apm/common/projections/errors.ts | 2 +- .../plugins/apm/common/projections/metrics.ts | 2 +- .../apm/common/projections/rum_overview.ts | 46 +++++ .../apm/common/projections/services.ts | 2 +- .../apm/common/projections/transactions.ts | 2 +- .../plugins/apm/common/projections/typings.ts | 1 + .../helpers => common/utils}/range_filter.ts | 0 .../apm/e2e/cypress/integration/helpers.ts | 20 +- .../cypress/integration/rum_dashboard.feature | 7 + .../apm/e2e/cypress/integration/snapshots.js | 23 ++- .../support/step_definitions/rum_dashboard.ts | 43 ++++ x-pack/plugins/apm/e2e/ingest-data/replay.js | 6 +- x-pack/plugins/apm/e2e/run-e2e.sh | 2 +- x-pack/plugins/apm/e2e/yarn.lock | 8 +- .../plugins/apm/public/application/index.tsx | 3 +- .../apm/public/components/app/Home/index.tsx | 24 ++- .../app/Main/route_config/index.tsx | 9 + .../app/Main/route_config/route_names.tsx | 1 + .../app/RumDashboard/ChartWrapper/index.tsx | 63 ++++++ .../app/RumDashboard/ClientMetrics/index.tsx | 82 ++++++++ .../PercentileAnnotations.tsx | 60 ++++++ .../PageLoadDistribution/index.tsx | 144 +++++++++++++ .../app/RumDashboard/PageViewsTrend/index.tsx | 111 ++++++++++ .../app/RumDashboard/RumDashboard.tsx | 65 ++++++ .../components/app/RumDashboard/index.tsx | 40 ++++ .../app/RumDashboard/translations.ts | 73 +++++++ .../app/ServiceDetails/ServiceDetailTabs.tsx | 16 ++ .../components/shared/KueryBar/index.tsx | 4 +- .../shared/Links/apm/RumOverviewLink.tsx | 31 +++ .../lib/errors/distribution/get_buckets.ts | 2 +- .../apm/server/lib/errors/get_error_group.ts | 2 +- .../__snapshots__/queries.test.ts.snap | 194 ++++++++++++++++++ .../lib/rum_client/get_client_metrics.ts | 61 ++++++ .../rum_client/get_page_load_distribution.ts | 140 +++++++++++++ .../lib/rum_client/get_page_view_trends.ts | 57 +++++ .../apm/server/lib/rum_client/queries.test.ts | 52 +++++ .../get_service_map_service_node_info.ts | 2 +- .../lib/service_map/get_trace_sample_ids.ts | 2 +- .../get_derived_service_annotations.ts | 2 +- .../lib/services/get_service_agent_name.ts | 2 +- .../services/get_service_transaction_types.ts | 2 +- .../apm/server/lib/traces/get_trace_items.ts | 2 +- .../avg_duration_by_browser/fetcher.ts | 2 +- .../avg_duration_by_country/index.ts | 2 +- .../lib/transactions/breakdown/index.ts | 2 +- .../charts/get_timeseries_data/fetcher.ts | 2 +- .../distribution/get_buckets/fetcher.ts | 2 +- .../lib/transactions/get_transaction/index.ts | 2 +- .../server/lib/ui_filters/get_environments.ts | 2 +- .../lib/ui_filters/local_ui_filters/config.ts | 35 ++++ .../apm/server/routes/create_apm_api.ts | 14 +- .../plugins/apm/server/routes/rum_client.ts | 57 +++++ .../plugins/apm/server/routes/ui_filters.ts | 11 + .../apm/typings/elasticsearch/aggregations.ts | 26 +++ .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 58 files changed, 1552 insertions(+), 47 deletions(-) create mode 100644 x-pack/plugins/apm/common/projections/rum_overview.ts rename x-pack/plugins/apm/{server/lib/helpers => common/utils}/range_filter.ts (100%) create mode 100644 x-pack/plugins/apm/e2e/cypress/integration/rum_dashboard.feature create mode 100644 x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum_dashboard.ts create mode 100644 x-pack/plugins/apm/public/components/app/RumDashboard/ChartWrapper/index.tsx create mode 100644 x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx create mode 100644 x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/PercentileAnnotations.tsx create mode 100644 x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx create mode 100644 x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx create mode 100644 x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx create mode 100644 x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx create mode 100644 x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts create mode 100644 x-pack/plugins/apm/public/components/shared/Links/apm/RumOverviewLink.tsx create mode 100644 x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap create mode 100644 x-pack/plugins/apm/server/lib/rum_client/get_client_metrics.ts create mode 100644 x-pack/plugins/apm/server/lib/rum_client/get_page_load_distribution.ts create mode 100644 x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts create mode 100644 x-pack/plugins/apm/server/lib/rum_client/queries.test.ts create mode 100644 x-pack/plugins/apm/server/routes/rum_client.ts diff --git a/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap b/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap index 54dd4704edfc0..f3dc7abcf8239 100644 --- a/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap +++ b/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap @@ -4,6 +4,8 @@ exports[`Error AGENT_NAME 1`] = `"java"`; exports[`Error AGENT_VERSION 1`] = `"agent version"`; +exports[`Error CLIENT_GEO 1`] = `undefined`; + exports[`Error CLIENT_GEO_COUNTRY_ISO_CODE 1`] = `undefined`; exports[`Error CONTAINER_ID 1`] = `undefined`; @@ -122,18 +124,26 @@ exports[`Error TRANSACTION_SAMPLED 1`] = `undefined`; exports[`Error TRANSACTION_TYPE 1`] = `"request"`; +exports[`Error TRANSACTION_URL 1`] = `undefined`; + exports[`Error URL_FULL 1`] = `undefined`; +exports[`Error USER_AGENT_DEVICE 1`] = `undefined`; + exports[`Error USER_AGENT_NAME 1`] = `undefined`; exports[`Error USER_AGENT_ORIGINAL 1`] = `undefined`; +exports[`Error USER_AGENT_OS 1`] = `undefined`; + exports[`Error USER_ID 1`] = `undefined`; exports[`Span AGENT_NAME 1`] = `"java"`; exports[`Span AGENT_VERSION 1`] = `"agent version"`; +exports[`Span CLIENT_GEO 1`] = `undefined`; + exports[`Span CLIENT_GEO_COUNTRY_ISO_CODE 1`] = `undefined`; exports[`Span CONTAINER_ID 1`] = `undefined`; @@ -252,18 +262,26 @@ exports[`Span TRANSACTION_SAMPLED 1`] = `undefined`; exports[`Span TRANSACTION_TYPE 1`] = `undefined`; +exports[`Span TRANSACTION_URL 1`] = `undefined`; + exports[`Span URL_FULL 1`] = `undefined`; +exports[`Span USER_AGENT_DEVICE 1`] = `undefined`; + exports[`Span USER_AGENT_NAME 1`] = `undefined`; exports[`Span USER_AGENT_ORIGINAL 1`] = `undefined`; +exports[`Span USER_AGENT_OS 1`] = `undefined`; + exports[`Span USER_ID 1`] = `undefined`; exports[`Transaction AGENT_NAME 1`] = `"java"`; exports[`Transaction AGENT_VERSION 1`] = `"agent version"`; +exports[`Transaction CLIENT_GEO 1`] = `undefined`; + exports[`Transaction CLIENT_GEO_COUNTRY_ISO_CODE 1`] = `undefined`; exports[`Transaction CONTAINER_ID 1`] = `"container1234567890abcdef"`; @@ -382,10 +400,16 @@ exports[`Transaction TRANSACTION_SAMPLED 1`] = `true`; exports[`Transaction TRANSACTION_TYPE 1`] = `"transaction type"`; +exports[`Transaction TRANSACTION_URL 1`] = `undefined`; + exports[`Transaction URL_FULL 1`] = `"http://www.elastic.co"`; +exports[`Transaction USER_AGENT_DEVICE 1`] = `undefined`; + exports[`Transaction USER_AGENT_NAME 1`] = `"Other"`; exports[`Transaction USER_AGENT_ORIGINAL 1`] = `"test original"`; +exports[`Transaction USER_AGENT_OS 1`] = `undefined`; + exports[`Transaction USER_ID 1`] = `"1337"`; diff --git a/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts b/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts index d5c3f91eb9247..7537dba7f8411 100644 --- a/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts +++ b/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts @@ -87,3 +87,9 @@ export const CONTAINER_ID = 'container.id'; export const POD_NAME = 'kubernetes.pod.name'; export const CLIENT_GEO_COUNTRY_ISO_CODE = 'client.geo.country_iso_code'; + +// RUM Labels +export const TRANSACTION_URL = 'transaction.page.url'; +export const CLIENT_GEO = 'client.geo'; +export const USER_AGENT_DEVICE = 'user_agent.device.name'; +export const USER_AGENT_OS = 'user_agent.os.name'; diff --git a/x-pack/plugins/apm/common/projections/errors.ts b/x-pack/plugins/apm/common/projections/errors.ts index bd397afae2243..390a8a0968102 100644 --- a/x-pack/plugins/apm/common/projections/errors.ts +++ b/x-pack/plugins/apm/common/projections/errors.ts @@ -16,7 +16,7 @@ import { ERROR_GROUP_ID, } from '../elasticsearch_fieldnames'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { rangeFilter } from '../../server/lib/helpers/range_filter'; +import { rangeFilter } from '../utils/range_filter'; export function getErrorGroupsProjection({ setup, diff --git a/x-pack/plugins/apm/common/projections/metrics.ts b/x-pack/plugins/apm/common/projections/metrics.ts index b05ec5f2ba876..45998bfe82e96 100644 --- a/x-pack/plugins/apm/common/projections/metrics.ts +++ b/x-pack/plugins/apm/common/projections/metrics.ts @@ -16,7 +16,7 @@ import { SERVICE_NODE_NAME, } from '../elasticsearch_fieldnames'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { rangeFilter } from '../../server/lib/helpers/range_filter'; +import { rangeFilter } from '../utils/range_filter'; import { SERVICE_NODE_NAME_MISSING } from '../service_nodes'; function getServiceNodeNameFilters(serviceNodeName?: string) { diff --git a/x-pack/plugins/apm/common/projections/rum_overview.ts b/x-pack/plugins/apm/common/projections/rum_overview.ts new file mode 100644 index 0000000000000..b1218546d09ff --- /dev/null +++ b/x-pack/plugins/apm/common/projections/rum_overview.ts @@ -0,0 +1,46 @@ +/* + * 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 { + Setup, + SetupTimeRange, + SetupUIFilters, + // eslint-disable-next-line @kbn/eslint/no-restricted-paths +} from '../../server/lib/helpers/setup_request'; +import { PROCESSOR_EVENT, TRANSACTION_TYPE } from '../elasticsearch_fieldnames'; +import { rangeFilter } from '../utils/range_filter'; + +export function getRumOverviewProjection({ + setup, +}: { + setup: Setup & SetupTimeRange & SetupUIFilters; +}) { + const { start, end, uiFiltersES, indices } = setup; + + const bool = { + filter: [ + { range: rangeFilter(start, end) }, + { term: { [PROCESSOR_EVENT]: 'transaction' } }, + { term: { [TRANSACTION_TYPE]: 'page-load' } }, + { + // Adding this filter to cater for some inconsistent rum data + exists: { + field: 'transaction.marks.navigationTiming.fetchStart', + }, + }, + ...uiFiltersES, + ], + }; + + return { + index: indices['apm_oss.transactionIndices'], + body: { + query: { + bool, + }, + }, + }; +} diff --git a/x-pack/plugins/apm/common/projections/services.ts b/x-pack/plugins/apm/common/projections/services.ts index bcfc27d720ba9..80a3471e9c30d 100644 --- a/x-pack/plugins/apm/common/projections/services.ts +++ b/x-pack/plugins/apm/common/projections/services.ts @@ -12,7 +12,7 @@ import { } from '../../server/lib/helpers/setup_request'; import { SERVICE_NAME, PROCESSOR_EVENT } from '../elasticsearch_fieldnames'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { rangeFilter } from '../../server/lib/helpers/range_filter'; +import { rangeFilter } from '../utils/range_filter'; export function getServicesProjection({ setup, diff --git a/x-pack/plugins/apm/common/projections/transactions.ts b/x-pack/plugins/apm/common/projections/transactions.ts index 99d5a04c1e722..b6cd73ca9aaad 100644 --- a/x-pack/plugins/apm/common/projections/transactions.ts +++ b/x-pack/plugins/apm/common/projections/transactions.ts @@ -17,7 +17,7 @@ import { TRANSACTION_NAME, } from '../elasticsearch_fieldnames'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { rangeFilter } from '../../server/lib/helpers/range_filter'; +import { rangeFilter } from '../utils/range_filter'; export function getTransactionsProjection({ setup, diff --git a/x-pack/plugins/apm/common/projections/typings.ts b/x-pack/plugins/apm/common/projections/typings.ts index 3361770336dde..693795b09e1d0 100644 --- a/x-pack/plugins/apm/common/projections/typings.ts +++ b/x-pack/plugins/apm/common/projections/typings.ts @@ -29,4 +29,5 @@ export enum PROJECTION { METRICS = 'metrics', ERROR_GROUPS = 'errorGroups', SERVICE_NODES = 'serviceNodes', + RUM_OVERVIEW = 'rumOverview', } diff --git a/x-pack/plugins/apm/server/lib/helpers/range_filter.ts b/x-pack/plugins/apm/common/utils/range_filter.ts similarity index 100% rename from x-pack/plugins/apm/server/lib/helpers/range_filter.ts rename to x-pack/plugins/apm/common/utils/range_filter.ts diff --git a/x-pack/plugins/apm/e2e/cypress/integration/helpers.ts b/x-pack/plugins/apm/e2e/cypress/integration/helpers.ts index 90d5c9eda632d..689b88390810f 100644 --- a/x-pack/plugins/apm/e2e/cypress/integration/helpers.ts +++ b/x-pack/plugins/apm/e2e/cypress/integration/helpers.ts @@ -6,20 +6,30 @@ /* eslint-disable import/no-extraneous-dependencies */ -const RANGE_FROM = '2020-03-04T12:30:00.000Z'; -const RANGE_TO = '2020-03-04T13:00:00.000Z'; +const RANGE_FROM = '2020-06-01T14:59:32.686Z'; +const RANGE_TO = '2020-06-16T16:59:36.219Z'; + const BASE_URL = Cypress.config().baseUrl; /** The default time in ms to wait for a Cypress command to complete */ export const DEFAULT_TIMEOUT = 60 * 1000; -export function loginAndWaitForPage(url: string) { +export function loginAndWaitForPage( + url: string, + dateRange?: { to: string; from: string } +) { const username = Cypress.env('elasticsearch_username'); const password = Cypress.env('elasticsearch_password'); cy.log(`Authenticating via ${username} / ${password}`); - - const fullUrl = `${BASE_URL}${url}?rangeFrom=${RANGE_FROM}&rangeTo=${RANGE_TO}`; + let rangeFrom = RANGE_FROM; + let rangeTo = RANGE_TO; + if (dateRange) { + rangeFrom = dateRange.from; + rangeTo = dateRange.to; + } + + const fullUrl = `${BASE_URL}${url}?rangeFrom=${rangeFrom}&rangeTo=${rangeTo}`; cy.visit(fullUrl, { auth: { username, password } }); cy.viewport('macbook-15'); diff --git a/x-pack/plugins/apm/e2e/cypress/integration/rum_dashboard.feature b/x-pack/plugins/apm/e2e/cypress/integration/rum_dashboard.feature new file mode 100644 index 0000000000000..eabfaf096731b --- /dev/null +++ b/x-pack/plugins/apm/e2e/cypress/integration/rum_dashboard.feature @@ -0,0 +1,7 @@ +Feature: RUM Dashboard + + Scenario: Client metrics + Given a user browses the APM UI application for RUM Data + When the user inspects the real user monitoring tab + Then should redirect to rum dashboard + And should have correct client metrics diff --git a/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js b/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js index d4c8ba4910850..dd96a57ef8c45 100644 --- a/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js +++ b/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js @@ -1,10 +1,17 @@ module.exports = { - APM: { - 'Transaction duration charts': { - '1': '350 ms', - '2': '175 ms', - '3': '0 ms', - }, + "__version": "4.5.0", + "APM": { + "Transaction duration charts": { + "1": "55 ms", + "2": "28 ms", + "3": "0 ms" + } }, - __version: '4.5.0', -}; + "RUM Dashboard": { + "Client metrics": { + "1": "62", + "2": "0.07 sec", + "3": "0.01 sec" + } + } +} diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum_dashboard.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum_dashboard.ts new file mode 100644 index 0000000000000..38eadbf513032 --- /dev/null +++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum_dashboard.ts @@ -0,0 +1,43 @@ +/* + * 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 { Given, When, Then } from 'cypress-cucumber-preprocessor/steps'; +import { loginAndWaitForPage } from '../../integration/helpers'; + +/** The default time in ms to wait for a Cypress command to complete */ +export const DEFAULT_TIMEOUT = 60 * 1000; + +Given(`a user browses the APM UI application for RUM Data`, () => { + // open service overview page + const RANGE_FROM = 'now-24h'; + const RANGE_TO = 'now'; + loginAndWaitForPage(`/app/apm#/services`, { from: RANGE_FROM, to: RANGE_TO }); +}); + +When(`the user inspects the real user monitoring tab`, () => { + // click rum tab + cy.get(':contains(Real User Monitoring)', { timeout: DEFAULT_TIMEOUT }) + .last() + .click({ force: true }); +}); + +Then(`should redirect to rum dashboard`, () => { + cy.url().should('contain', `/app/apm#/rum-overview`); +}); + +Then(`should have correct client metrics`, () => { + const clientMetrics = '[data-cy=client-metrics] .euiStat__title'; + + // wait for all loading to finish + cy.get('kbnLoadingIndicator').should('not.be.visible'); + cy.get('.euiStat__title-isLoading').should('not.be.visible'); + + cy.get(clientMetrics).eq(2).invoke('text').snapshot(); + + cy.get(clientMetrics).eq(1).invoke('text').snapshot(); + + cy.get(clientMetrics).eq(0).invoke('text').snapshot(); +}); diff --git a/x-pack/plugins/apm/e2e/ingest-data/replay.js b/x-pack/plugins/apm/e2e/ingest-data/replay.js index ae3f62894afc0..3478039f39b50 100644 --- a/x-pack/plugins/apm/e2e/ingest-data/replay.js +++ b/x-pack/plugins/apm/e2e/ingest-data/replay.js @@ -99,7 +99,11 @@ async function init() { .split('\n') .filter((item) => item) .map((item) => JSON.parse(item)) - .filter((item) => item.url === '/intake/v2/events'); + .filter((item) => { + return ( + item.url === '/intake/v2/events' || item.url === '/intake/v2/rum/events' + ); + }); spinner.start(); requestProgress.total = items.length; diff --git a/x-pack/plugins/apm/e2e/run-e2e.sh b/x-pack/plugins/apm/e2e/run-e2e.sh index aa7c0e21425ad..43cc74a197f42 100755 --- a/x-pack/plugins/apm/e2e/run-e2e.sh +++ b/x-pack/plugins/apm/e2e/run-e2e.sh @@ -109,7 +109,7 @@ echo "${bold}Static mock data (logs: ${E2E_DIR}${TMP_DIR}/ingest-data.log)${norm # Download static data if not already done if [ ! -e "${TMP_DIR}/events.json" ]; then echo 'Downloading events.json...' - curl --silent https://storage.googleapis.com/apm-ui-e2e-static-data/events.json --output ${TMP_DIR}/events.json + curl --silent https://storage.googleapis.com/apm-ui-e2e-static-data/2020-06-12.json --output ${TMP_DIR}/events.json fi # echo "Deleting existing indices (apm* and .apm*)" diff --git a/x-pack/plugins/apm/e2e/yarn.lock b/x-pack/plugins/apm/e2e/yarn.lock index a6729c56ecb09..975154d71b85d 100644 --- a/x-pack/plugins/apm/e2e/yarn.lock +++ b/x-pack/plugins/apm/e2e/yarn.lock @@ -5561,10 +5561,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@3.9.2: - version "3.9.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.2.tgz#64e9c8e9be6ea583c54607677dd4680a1cf35db9" - integrity sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw== +typescript@3.9.5: + version "3.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" + integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== umd@^3.0.0: version "3.0.3" diff --git a/x-pack/plugins/apm/public/application/index.tsx b/x-pack/plugins/apm/public/application/index.tsx index 56c427e67ad4c..8800b2fd492bf 100644 --- a/x-pack/plugins/apm/public/application/index.tsx +++ b/x-pack/plugins/apm/public/application/index.tsx @@ -23,7 +23,7 @@ import { KibanaContextProvider, useUiSetting$, } from '../../../../../src/plugins/kibana_react/public'; -import { px, unit, units } from '../style/variables'; +import { px, units } from '../style/variables'; import { UpdateBreadcrumbs } from '../components/app/Main/UpdateBreadcrumbs'; import { APMIndicesPermission } from '../components/app/APMIndicesPermission'; import { ScrollToTopOnPathChange } from '../components/app/Main/ScrollToTopOnPathChange'; @@ -33,7 +33,6 @@ import { ConfigSchema } from '..'; import 'react-vis/dist/style.css'; const MainContainer = styled.div` - min-width: ${px(unit * 50)}; padding: ${px(units.plus)}; height: 100%; `; diff --git a/x-pack/plugins/apm/public/components/app/Home/index.tsx b/x-pack/plugins/apm/public/components/app/Home/index.tsx index 74cbc00b17889..c325a72375359 100644 --- a/x-pack/plugins/apm/public/components/app/Home/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Home/index.tsx @@ -25,6 +25,9 @@ import { SetupInstructionsLink } from '../../shared/Links/SetupInstructionsLink' import { ServiceMap } from '../ServiceMap'; import { ServiceOverview } from '../ServiceOverview'; import { TraceOverview } from '../TraceOverview'; +import { RumOverview } from '../RumDashboard'; +import { RumOverviewLink } from '../../shared/Links/apm/RumOverviewLink'; +import { EndUserExperienceLabel } from '../RumDashboard/translations'; function getHomeTabs({ serviceMapEnabled = true, @@ -70,14 +73,27 @@ function getHomeTabs({ }); } + homeTabs.push({ + link: ( + + {i18n.translate('xpack.apm.home.rumTabLabel', { + defaultMessage: 'Real User Monitoring', + })} + + ), + render: () => , + name: 'rum-overview', + }); + return homeTabs; } + const SETTINGS_LINK_LABEL = i18n.translate('xpack.apm.settingsLinkLabel', { defaultMessage: 'Settings', }); interface Props { - tab: 'traces' | 'services' | 'service-map'; + tab: 'traces' | 'services' | 'service-map' | 'rum-overview'; } export function Home({ tab }: Props) { @@ -93,7 +109,11 @@ export function Home({ tab }: Props) { -

APM

+

+ {selectedTab.name === 'rum-overview' + ? EndUserExperienceLabel + : 'APM'} +

diff --git a/x-pack/plugins/apm/public/components/app/Main/route_config/index.tsx b/x-pack/plugins/apm/public/components/app/Main/route_config/index.tsx index 577af75e92d9e..295f343b411a9 100644 --- a/x-pack/plugins/apm/public/components/app/Main/route_config/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Main/route_config/index.tsx @@ -250,4 +250,13 @@ export const routes: BreadcrumbRoute[] = [ }), name: RouteName.CUSTOMIZE_UI, }, + { + exact: true, + path: '/rum-overview', + component: () => , + breadcrumb: i18n.translate('xpack.apm.home.rumOverview.title', { + defaultMessage: 'Real User Monitoring', + }), + name: RouteName.RUM_OVERVIEW, + }, ]; diff --git a/x-pack/plugins/apm/public/components/app/Main/route_config/route_names.tsx b/x-pack/plugins/apm/public/components/app/Main/route_config/route_names.tsx index 167de1a37f427..4965aa9db8760 100644 --- a/x-pack/plugins/apm/public/components/app/Main/route_config/route_names.tsx +++ b/x-pack/plugins/apm/public/components/app/Main/route_config/route_names.tsx @@ -26,4 +26,5 @@ export enum RouteName { SERVICE_NODES = 'nodes', LINK_TO_TRACE = 'link_to_trace', CUSTOMIZE_UI = 'customize_ui', + RUM_OVERVIEW = 'rum_overview', } diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ChartWrapper/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/ChartWrapper/index.tsx new file mode 100644 index 0000000000000..a3cfbb28abee2 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/ChartWrapper/index.tsx @@ -0,0 +1,63 @@ +/* + * 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 React, { FC, HTMLAttributes } from 'react'; +import { + EuiErrorBoundary, + EuiFlexGroup, + EuiFlexItem, + EuiLoadingChart, +} from '@elastic/eui'; + +interface Props { + /** + * Height for the chart + */ + height?: string; + /** + * if chart data source is still loading + */ + loading?: boolean; + /** + * aria-label for accessibility + */ + 'aria-label'?: string; +} + +export const ChartWrapper: FC = ({ + loading = false, + height = '100%', + children, + ...rest +}) => { + const opacity = loading === true ? 0.3 : 1; + + return ( + +
)} + > + {children} +
+ {loading === true && ( + + + + + + )} +
+ ); +}; diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx new file mode 100644 index 0000000000000..8c0a7c6a91f67 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx @@ -0,0 +1,82 @@ +/* + * 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. + */ +// @flow +import * as React from 'react'; +import styled from 'styled-components'; +import { EuiFlexGroup, EuiFlexItem, EuiStat } from '@elastic/eui'; +import { useFetcher } from '../../../../hooks/useFetcher'; +import { useUrlParams } from '../../../../hooks/useUrlParams'; +import { BackEndLabel, FrontEndLabel, PageViewsLabel } from '../translations'; + +export const formatBigValue = (val?: number | null, fixed?: number): string => { + if (val && val >= 1000) { + const result = val / 1000; + if (fixed) { + return result.toFixed(fixed) + 'k'; + } + return result + 'k'; + } + return val + ''; +}; + +const ClFlexGroup = styled(EuiFlexGroup)` + flex-direction: row; + @media only screen and (max-width: 768px) { + flex-direction: row; + justify-content: space-between; + } +`; + +export const ClientMetrics = () => { + const { urlParams, uiFilters } = useUrlParams(); + + const { start, end } = urlParams; + + const { data, status } = useFetcher( + (callApmApi) => { + if (start && end) { + return callApmApi({ + pathname: '/api/apm/rum/client-metrics', + params: { + query: { start, end, uiFilters: JSON.stringify(uiFilters) }, + }, + }); + } + }, + [start, end, uiFilters] + ); + + const STAT_STYLE = { width: '240px' }; + + return ( + + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/PercentileAnnotations.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/PercentileAnnotations.tsx new file mode 100644 index 0000000000000..9c89b8bc161b7 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/PercentileAnnotations.tsx @@ -0,0 +1,60 @@ +/* + * 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 * as React from 'react'; +import { + AnnotationDomainTypes, + LineAnnotation, + LineAnnotationDatum, + LineAnnotationStyle, +} from '@elastic/charts'; +import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; +import styled from 'styled-components'; + +interface Props { + percentiles?: Record; +} + +function generateAnnotationData( + values?: Record +): LineAnnotationDatum[] { + return Object.entries(values ?? {}).map((value, index) => ({ + dataValue: value[1], + details: `${(+value[0]).toFixed(0)}`, + })); +} + +const PercentileMarker = styled.span` + position: relative; + bottom: 140px; +`; + +export const PercentileAnnotations = ({ percentiles }: Props) => { + const dataValues = generateAnnotationData(percentiles) ?? []; + + const style: Partial = { + line: { + strokeWidth: 1, + stroke: euiLightVars.euiColorSecondary, + opacity: 1, + }, + }; + + return ( + <> + {dataValues.map((annotation, index) => ( + {annotation.details}th} + /> + ))} + + ); +}; diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx new file mode 100644 index 0000000000000..c7a0b64f6a8b8 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx @@ -0,0 +1,144 @@ +/* + * 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 React, { useState } from 'react'; +import { + EuiButton, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiTitle, +} from '@elastic/eui'; +import { + Axis, + Chart, + ScaleType, + LineSeries, + CurveType, + BrushEndListener, + Settings, + TooltipValueFormatter, + TooltipValue, +} from '@elastic/charts'; +import { Position } from '@elastic/charts/dist/utils/commons'; +import { useUrlParams } from '../../../../hooks/useUrlParams'; +import { useFetcher } from '../../../../hooks/useFetcher'; +import { ChartWrapper } from '../ChartWrapper'; +import { PercentileAnnotations } from './PercentileAnnotations'; +import { + PageLoadDistLabel, + PageLoadTimeLabel, + PercPageLoadedLabel, + ResetZoomLabel, +} from '../translations'; + +export const PageLoadDistribution = () => { + const { urlParams, uiFilters } = useUrlParams(); + + const { start, end } = urlParams; + + const [percentileRange, setPercentileRange] = useState<{ + min: string | null; + max: string | null; + }>({ + min: null, + max: null, + }); + + const { data, status } = useFetcher( + (callApmApi) => { + if (start && end) { + return callApmApi({ + pathname: '/api/apm/rum-client/page-load-distribution', + params: { + query: { + start, + end, + uiFilters: JSON.stringify(uiFilters), + ...(percentileRange.min && percentileRange.max + ? { + minPercentile: percentileRange.min, + maxPercentile: percentileRange.max, + } + : {}), + }, + }, + }); + } + }, + [end, start, uiFilters, percentileRange.min, percentileRange.max] + ); + + const onBrushEnd: BrushEndListener = ({ x }) => { + if (!x) { + return; + } + const [minX, maxX] = x; + setPercentileRange({ min: String(minX), max: String(maxX) }); + }; + + const headerFormatter: TooltipValueFormatter = (tooltip: TooltipValue) => { + return ( +
+

{tooltip.value} seconds

+
+ ); + }; + + const tooltipProps = { + headerFormatter, + }; + + return ( +
+ + + +

{PageLoadDistLabel}

+
+
+ + { + setPercentileRange({ min: null, max: null }); + }} + fill={percentileRange.min !== null && percentileRange.max !== null} + > + {ResetZoomLabel} + + +
+ + + + + + + Number(d).toFixed(1) + ' %'} + /> + + + +
+ ); +}; diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx new file mode 100644 index 0000000000000..cc41bd4352947 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx @@ -0,0 +1,111 @@ +/* + * 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 * as React from 'react'; +import { EuiTitle } from '@elastic/eui'; +import { + Axis, + BarSeries, + BrushEndListener, + Chart, + niceTimeFormatByDay, + ScaleType, + Settings, + timeFormatter, +} from '@elastic/charts'; +import moment from 'moment'; +import { Position } from '@elastic/charts/dist/utils/commons'; +import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; +import { useUrlParams } from '../../../../hooks/useUrlParams'; +import { useFetcher } from '../../../../hooks/useFetcher'; +import { ChartWrapper } from '../ChartWrapper'; +import { DateTimeLabel, PageViewsLabel } from '../translations'; +import { history } from '../../../../utils/history'; +import { fromQuery, toQuery } from '../../../shared/Links/url_helpers'; +import { formatBigValue } from '../ClientMetrics'; + +export const PageViewsTrend = () => { + const { urlParams, uiFilters } = useUrlParams(); + + const { start, end } = urlParams; + + const { data, status } = useFetcher( + (callApmApi) => { + if (start && end) { + return callApmApi({ + pathname: '/api/apm/rum-client/page-view-trends', + params: { + query: { + start, + end, + uiFilters: JSON.stringify(uiFilters), + }, + }, + }); + } + }, + [end, start, uiFilters] + ); + const formatter = timeFormatter(niceTimeFormatByDay(2)); + + const onBrushEnd: BrushEndListener = ({ x }) => { + if (!x) { + return; + } + const [minX, maxX] = x; + + const rangeFrom = moment(minX).toISOString(); + const rangeTo = moment(maxX).toISOString(); + + history.push({ + ...history.location, + search: fromQuery({ + ...toQuery(history.location.search), + rangeFrom, + rangeTo, + }), + }); + }; + + return ( +
+ +

{PageViewsLabel}

+
+ + + + + formatBigValue(Number(d))} + /> + + + +
+ ); +}; diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx new file mode 100644 index 0000000000000..e3fa7374afb38 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx @@ -0,0 +1,65 @@ +/* + * 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 { + EuiFlexGroup, + EuiFlexItem, + EuiTitle, + EuiSpacer, + EuiPanel, +} from '@elastic/eui'; +import React from 'react'; +import { ClientMetrics } from './ClientMetrics'; +import { PageViewsTrend } from './PageViewsTrend'; +import { PageLoadDistribution } from './PageLoadDistribution'; +import { getWhatIsGoingOnLabel } from './translations'; +import { useUrlParams } from '../../../hooks/useUrlParams'; + +export function RumDashboard() { + const { urlParams } = useUrlParams(); + + const { environment } = urlParams; + + let environmentLabel = environment || 'all environments'; + + if (environment === 'ENVIRONMENT_NOT_DEFINED') { + environmentLabel = 'undefined environment'; + } + + return ( + <> + +

{getWhatIsGoingOnLabel(environmentLabel)}

+
+ + + + + + + +

Page load times

+
+ + +
+
+
+
+ + + + + + + + + + +
+ + ); +} diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx new file mode 100644 index 0000000000000..8f21065b0dab0 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx @@ -0,0 +1,40 @@ +/* + * 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 { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; +import React, { useMemo } from 'react'; +import { useTrackPageview } from '../../../../../observability/public'; +import { LocalUIFilters } from '../../shared/LocalUIFilters'; +import { PROJECTION } from '../../../../common/projections/typings'; +import { RumDashboard } from './RumDashboard'; + +export function RumOverview() { + useTrackPageview({ app: 'apm', path: 'rum_overview' }); + useTrackPageview({ app: 'apm', path: 'rum_overview', delay: 15000 }); + + const localUIFiltersConfig = useMemo(() => { + const config: React.ComponentProps = { + filterNames: ['transactionUrl', 'location', 'device', 'os', 'browser'], + projection: PROJECTION.RUM_OVERVIEW, + }; + + return config; + }, []); + + return ( + <> + + + + + + + + + + + ); +} diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts b/x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts new file mode 100644 index 0000000000000..c2aed41a55c7d --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts @@ -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 { i18n } from '@kbn/i18n'; + +export const EndUserExperienceLabel = i18n.translate( + 'xpack.apm.rum.dashboard.title', + { + defaultMessage: 'End User Experience', + } +); + +export const getWhatIsGoingOnLabel = (environmentVal: string) => + i18n.translate('xpack.apm.rum.dashboard.environment.title', { + defaultMessage: `What's going on in {environmentVal}?`, + values: { environmentVal }, + }); + +export const BackEndLabel = i18n.translate('xpack.apm.rum.dashboard.backend', { + defaultMessage: 'Backend', +}); + +export const FrontEndLabel = i18n.translate( + 'xpack.apm.rum.dashboard.frontend', + { + defaultMessage: 'Frontend', + } +); + +export const PageViewsLabel = i18n.translate( + 'xpack.apm.rum.dashboard.pageViews', + { + defaultMessage: 'Page views', + } +); + +export const DateTimeLabel = i18n.translate( + 'xpack.apm.rum.dashboard.dateTime.label', + { + defaultMessage: 'Date / Time', + } +); + +export const PercPageLoadedLabel = i18n.translate( + 'xpack.apm.rum.dashboard.pagesLoaded.label', + { + defaultMessage: 'Pages loaded', + } +); + +export const PageLoadTimeLabel = i18n.translate( + 'xpack.apm.rum.dashboard.pageLoadTime.label', + { + defaultMessage: 'Page load time (seconds)', + } +); + +export const PageLoadDistLabel = i18n.translate( + 'xpack.apm.rum.dashboard.pageLoadDistribution.label', + { + defaultMessage: 'Page load distribution', + } +); + +export const ResetZoomLabel = i18n.translate( + 'xpack.apm.rum.dashboard.resetZoom.label', + { + defaultMessage: 'Reset zoom', + } +); diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx index 2f35e329720de..81bdbdad805d6 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx @@ -22,6 +22,8 @@ import { ServiceMap } from '../ServiceMap'; import { ServiceMetrics } from '../ServiceMetrics'; import { ServiceNodeOverview } from '../ServiceNodeOverview'; import { TransactionOverview } from '../TransactionOverview'; +import { RumOverviewLink } from '../../shared/Links/apm/RumOverviewLink'; +import { RumOverview } from '../RumDashboard'; interface Props { tab: 'transactions' | 'errors' | 'metrics' | 'nodes' | 'service-map'; @@ -110,6 +112,20 @@ export function ServiceDetailTabs({ tab }: Props) { tabs.push(serviceMapTab); } + if (isRumAgentName(agentName)) { + tabs.push({ + link: ( + + {i18n.translate('xpack.apm.home.rumTabLabel', { + defaultMessage: 'Real User Monitoring', + })} + + ), + render: () => , + name: 'rum-overview', + }); + } + const selectedTab = tabs.find((serviceTab) => serviceTab.name === tab); return ( diff --git a/x-pack/plugins/apm/public/components/shared/KueryBar/index.tsx b/x-pack/plugins/apm/public/components/shared/KueryBar/index.tsx index d01deb8160858..eab685a4c1ab4 100644 --- a/x-pack/plugins/apm/public/components/shared/KueryBar/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/KueryBar/index.tsx @@ -76,10 +76,10 @@ export function KueryBar() { }); // The bar should be disabled when viewing the service map - const disabled = /\/service-map$/.test(location.pathname); + const disabled = /\/(service-map|rum-overview)$/.test(location.pathname); const disabledPlaceholder = i18n.translate( 'xpack.apm.kueryBar.disabledPlaceholder', - { defaultMessage: 'Search is not available for service map' } + { defaultMessage: 'Search is not available here' } ); async function onChange(inputValue: string, selectionStart: number) { diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/RumOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/RumOverviewLink.tsx new file mode 100644 index 0000000000000..abca9817bd69d --- /dev/null +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/RumOverviewLink.tsx @@ -0,0 +1,31 @@ +/* + * 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. + */ + +/* + * 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 React from 'react'; +import { APMLink, APMLinkExtendProps } from './APMLink'; +import { useUrlParams } from '../../../../hooks/useUrlParams'; +import { pickKeys } from '../../../../../common/utils/pick_keys'; + +const RumOverviewLink = (props: APMLinkExtendProps) => { + const { urlParams } = useUrlParams(); + + const persistedFilters = pickKeys( + urlParams, + 'transactionResult', + 'host', + 'containerId', + 'podName' + ); + + return ; +}; + +export { RumOverviewLink }; diff --git a/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.ts b/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.ts index 7d96c490fcd70..db36ad1ede91c 100644 --- a/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.ts +++ b/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.ts @@ -10,7 +10,7 @@ import { PROCESSOR_EVENT, SERVICE_NAME, } from '../../../../common/elasticsearch_fieldnames'; -import { rangeFilter } from '../../helpers/range_filter'; +import { rangeFilter } from '../../../../common/utils/range_filter'; import { Setup, SetupTimeRange, diff --git a/x-pack/plugins/apm/server/lib/errors/get_error_group.ts b/x-pack/plugins/apm/server/lib/errors/get_error_group.ts index b157abd0b7e76..3d20f84ccfbc2 100644 --- a/x-pack/plugins/apm/server/lib/errors/get_error_group.ts +++ b/x-pack/plugins/apm/server/lib/errors/get_error_group.ts @@ -12,7 +12,7 @@ import { } from '../../../common/elasticsearch_fieldnames'; import { PromiseReturnType } from '../../../typings/common'; import { APMError } from '../../../typings/es_schemas/ui/apm_error'; -import { rangeFilter } from '../helpers/range_filter'; +import { rangeFilter } from '../../../common/utils/range_filter'; import { Setup, SetupTimeRange, diff --git a/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap new file mode 100644 index 0000000000000..7d8f31aaeca7f --- /dev/null +++ b/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap @@ -0,0 +1,194 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`rum client dashboard queries fetches client metrics 1`] = ` +Object { + "body": Object { + "aggs": Object { + "backEnd": Object { + "avg": Object { + "field": "transaction.marks.agent.timeToFirstByte", + "missing": 0, + }, + }, + "domInteractive": Object { + "avg": Object { + "field": "transaction.marks.agent.domInteractive", + "missing": 0, + }, + }, + "pageViews": Object { + "value_count": Object { + "field": "transaction.type", + }, + }, + }, + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "range": Object { + "@timestamp": Object { + "format": "epoch_millis", + "gte": 1528113600000, + "lte": 1528977600000, + }, + }, + }, + Object { + "term": Object { + "processor.event": "transaction", + }, + }, + Object { + "term": Object { + "transaction.type": "page-load", + }, + }, + Object { + "exists": Object { + "field": "transaction.marks.navigationTiming.fetchStart", + }, + }, + Object { + "term": Object { + "my.custom.ui.filter": "foo-bar", + }, + }, + ], + }, + }, + "size": 0, + }, + "index": "myIndex", +} +`; + +exports[`rum client dashboard queries fetches page load distribution 1`] = ` +Object { + "body": Object { + "aggs": Object { + "durationMinMax": Object { + "min": Object { + "field": "transaction.duration.us", + "missing": 0, + }, + }, + "durationPercentiles": Object { + "percentiles": Object { + "field": "transaction.duration.us", + "percents": Array [ + 50, + 75, + 90, + 95, + 99, + ], + "script": Object { + "lang": "painless", + "params": Object { + "timeUnit": 1000, + }, + "source": "doc['transaction.duration.us'].value / params.timeUnit", + }, + }, + }, + }, + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "range": Object { + "@timestamp": Object { + "format": "epoch_millis", + "gte": 1528113600000, + "lte": 1528977600000, + }, + }, + }, + Object { + "term": Object { + "processor.event": "transaction", + }, + }, + Object { + "term": Object { + "transaction.type": "page-load", + }, + }, + Object { + "exists": Object { + "field": "transaction.marks.navigationTiming.fetchStart", + }, + }, + Object { + "term": Object { + "my.custom.ui.filter": "foo-bar", + }, + }, + ], + }, + }, + "size": 0, + }, + "index": "myIndex", +} +`; + +exports[`rum client dashboard queries fetches page view trends 1`] = ` +Object { + "body": Object { + "aggs": Object { + "pageViews": Object { + "aggs": Object { + "trans_count": Object { + "value_count": Object { + "field": "transaction.type", + }, + }, + }, + "auto_date_histogram": Object { + "buckets": 50, + "field": "@timestamp", + }, + }, + }, + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "range": Object { + "@timestamp": Object { + "format": "epoch_millis", + "gte": 1528113600000, + "lte": 1528977600000, + }, + }, + }, + Object { + "term": Object { + "processor.event": "transaction", + }, + }, + Object { + "term": Object { + "transaction.type": "page-load", + }, + }, + Object { + "exists": Object { + "field": "transaction.marks.navigationTiming.fetchStart", + }, + }, + Object { + "term": Object { + "my.custom.ui.filter": "foo-bar", + }, + }, + ], + }, + }, + "size": 0, + }, + "index": "myIndex", +} +`; diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_client_metrics.ts b/x-pack/plugins/apm/server/lib/rum_client/get_client_metrics.ts new file mode 100644 index 0000000000000..8b3f733fc402a --- /dev/null +++ b/x-pack/plugins/apm/server/lib/rum_client/get_client_metrics.ts @@ -0,0 +1,61 @@ +/* + * 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 { getRumOverviewProjection } from '../../../common/projections/rum_overview'; +import { mergeProjection } from '../../../common/projections/util/merge_projection'; +import { + Setup, + SetupTimeRange, + SetupUIFilters, +} from '../helpers/setup_request'; + +export async function getClientMetrics({ + setup, +}: { + setup: Setup & SetupTimeRange & SetupUIFilters; +}) { + const projection = getRumOverviewProjection({ + setup, + }); + + const params = mergeProjection(projection, { + body: { + size: 0, + query: { + bool: projection.body.query.bool, + }, + aggs: { + pageViews: { value_count: { field: 'transaction.type' } }, + backEnd: { + avg: { + field: 'transaction.marks.agent.timeToFirstByte', + missing: 0, + }, + }, + domInteractive: { + avg: { + field: 'transaction.marks.agent.domInteractive', + missing: 0, + }, + }, + }, + }, + }); + + const { client } = setup; + + const response = await client.search(params); + const { backEnd, domInteractive, pageViews } = response.aggregations!; + + // Divide by 1000 to convert ms into seconds + return { + pageViews, + backEnd: { value: (backEnd.value || 0) / 1000 }, + frontEnd: { + value: ((domInteractive.value || 0) - (backEnd.value || 0)) / 1000, + }, + }; +} diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_page_load_distribution.ts b/x-pack/plugins/apm/server/lib/rum_client/get_page_load_distribution.ts new file mode 100644 index 0000000000000..3c563946e4052 --- /dev/null +++ b/x-pack/plugins/apm/server/lib/rum_client/get_page_load_distribution.ts @@ -0,0 +1,140 @@ +/* + * 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 { getRumOverviewProjection } from '../../../common/projections/rum_overview'; +import { mergeProjection } from '../../../common/projections/util/merge_projection'; +import { + Setup, + SetupTimeRange, + SetupUIFilters, +} from '../helpers/setup_request'; + +export async function getPageLoadDistribution({ + setup, + minPercentile, + maxPercentile, +}: { + setup: Setup & SetupTimeRange & SetupUIFilters; + minPercentile?: string; + maxPercentile?: string; +}) { + const projection = getRumOverviewProjection({ + setup, + }); + + const params = mergeProjection(projection, { + body: { + size: 0, + query: { + bool: projection.body.query.bool, + }, + aggs: { + durationMinMax: { + min: { + field: 'transaction.duration.us', + missing: 0, + }, + }, + durationPercentiles: { + percentiles: { + field: 'transaction.duration.us', + percents: [50, 75, 90, 95, 99], + script: { + lang: 'painless', + source: "doc['transaction.duration.us'].value / params.timeUnit", + params: { + timeUnit: 1000, + }, + }, + }, + }, + }, + }, + }); + + const { client } = setup; + + const { + aggregations, + hits: { total }, + } = await client.search(params); + + if (total.value === 0) { + return null; + } + + const minDuration = (aggregations?.durationMinMax.value ?? 0) / 1000; + + const minPerc = minPercentile ? +minPercentile : minDuration; + + const maxPercentileQuery = + aggregations?.durationPercentiles.values['99.0'] ?? 100; + + const maxPerc = maxPercentile ? +maxPercentile : maxPercentileQuery; + + const pageDist = await getPercentilesDistribution(setup, minPerc, maxPerc); + return { + pageLoadDistribution: pageDist, + percentiles: aggregations?.durationPercentiles.values, + }; +} + +const getPercentilesDistribution = async ( + setup: Setup & SetupTimeRange & SetupUIFilters, + minPercentiles: number, + maxPercentile: number +) => { + const stepValue = (maxPercentile - minPercentiles) / 50; + const stepValues = []; + for (let i = 1; i < 50; i++) { + stepValues.push((stepValue * i + minPercentiles).toFixed(2)); + } + + const projection = getRumOverviewProjection({ + setup, + }); + + const params = mergeProjection(projection, { + body: { + size: 0, + query: { + bool: projection.body.query.bool, + }, + aggs: { + loadDistribution: { + percentile_ranks: { + field: 'transaction.duration.us', + values: stepValues, + keyed: false, + script: { + lang: 'painless', + source: "doc['transaction.duration.us'].value / params.timeUnit", + params: { + timeUnit: 1000, + }, + }, + }, + }, + }, + }, + }); + + const { client } = setup; + + const { aggregations } = await client.search(params); + + const pageDist = (aggregations?.loadDistribution.values ?? []) as Array<{ + key: number; + value: number; + }>; + + return pageDist.map(({ key, value }, index: number, arr) => { + return { + x: key, + y: index === 0 ? value : value - arr[index - 1].value, + }; + }); +}; diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts b/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts new file mode 100644 index 0000000000000..126605206d299 --- /dev/null +++ b/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts @@ -0,0 +1,57 @@ +/* + * 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 { getRumOverviewProjection } from '../../../common/projections/rum_overview'; +import { mergeProjection } from '../../../common/projections/util/merge_projection'; +import { + Setup, + SetupTimeRange, + SetupUIFilters, +} from '../helpers/setup_request'; + +export async function getPageViewTrends({ + setup, +}: { + setup: Setup & SetupTimeRange & SetupUIFilters; +}) { + const projection = getRumOverviewProjection({ + setup, + }); + + const params = mergeProjection(projection, { + body: { + size: 0, + query: { + bool: projection.body.query.bool, + }, + aggs: { + pageViews: { + auto_date_histogram: { + field: '@timestamp', + buckets: 50, + }, + aggs: { + trans_count: { + value_count: { + field: 'transaction.type', + }, + }, + }, + }, + }, + }, + }); + + const { client } = setup; + + const response = await client.search(params); + + const result = response.aggregations?.pageViews.buckets ?? []; + return result.map(({ key, trans_count }) => ({ + x: key, + y: trans_count.value, + })); +} diff --git a/x-pack/plugins/apm/server/lib/rum_client/queries.test.ts b/x-pack/plugins/apm/server/lib/rum_client/queries.test.ts new file mode 100644 index 0000000000000..5f5a48eced746 --- /dev/null +++ b/x-pack/plugins/apm/server/lib/rum_client/queries.test.ts @@ -0,0 +1,52 @@ +/* + * 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 { + SearchParamsMock, + inspectSearchParams, +} from '../../../public/utils/testHelpers'; +import { getClientMetrics } from './get_client_metrics'; +import { getPageViewTrends } from './get_page_view_trends'; +import { getPageLoadDistribution } from './get_page_load_distribution'; + +describe('rum client dashboard queries', () => { + let mock: SearchParamsMock; + + afterEach(() => { + mock.teardown(); + }); + + it('fetches client metrics', async () => { + mock = await inspectSearchParams((setup) => + getClientMetrics({ + setup, + }) + ); + + expect(mock.params).toMatchSnapshot(); + }); + + it('fetches page view trends', async () => { + mock = await inspectSearchParams((setup) => + getPageViewTrends({ + setup, + }) + ); + + expect(mock.params).toMatchSnapshot(); + }); + + it('fetches page load distribution', async () => { + mock = await inspectSearchParams((setup) => + getPageLoadDistribution({ + setup, + minPercentile: '0', + maxPercentile: '99', + }) + ); + expect(mock.params).toMatchSnapshot(); + }); +}); diff --git a/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts b/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts index d069e93397611..e521efa687388 100644 --- a/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts +++ b/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts @@ -6,7 +6,7 @@ import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { ESFilter } from '../../../typings/elasticsearch'; -import { rangeFilter } from '../helpers/range_filter'; +import { rangeFilter } from '../../../common/utils/range_filter'; import { PROCESSOR_EVENT, SERVICE_ENVIRONMENT, diff --git a/x-pack/plugins/apm/server/lib/service_map/get_trace_sample_ids.ts b/x-pack/plugins/apm/server/lib/service_map/get_trace_sample_ids.ts index 6eba84f2205a1..11c3a00f32980 100644 --- a/x-pack/plugins/apm/server/lib/service_map/get_trace_sample_ids.ts +++ b/x-pack/plugins/apm/server/lib/service_map/get_trace_sample_ids.ts @@ -5,7 +5,7 @@ */ import { uniq, take, sortBy } from 'lodash'; import { Setup, SetupTimeRange } from '../helpers/setup_request'; -import { rangeFilter } from '../helpers/range_filter'; +import { rangeFilter } from '../../../common/utils/range_filter'; import { ESFilter } from '../../../typings/elasticsearch'; import { PROCESSOR_EVENT, diff --git a/x-pack/plugins/apm/server/lib/services/annotations/get_derived_service_annotations.ts b/x-pack/plugins/apm/server/lib/services/annotations/get_derived_service_annotations.ts index 9829c5cb25182..6da5d195cf194 100644 --- a/x-pack/plugins/apm/server/lib/services/annotations/get_derived_service_annotations.ts +++ b/x-pack/plugins/apm/server/lib/services/annotations/get_derived_service_annotations.ts @@ -7,7 +7,7 @@ import { isNumber } from 'lodash'; import { Annotation, AnnotationType } from '../../../../common/annotations'; import { SetupTimeRange, Setup } from '../../helpers/setup_request'; import { ESFilter } from '../../../../typings/elasticsearch'; -import { rangeFilter } from '../../helpers/range_filter'; +import { rangeFilter } from '../../../../common/utils/range_filter'; import { PROCESSOR_EVENT, SERVICE_NAME, diff --git a/x-pack/plugins/apm/server/lib/services/get_service_agent_name.ts b/x-pack/plugins/apm/server/lib/services/get_service_agent_name.ts index 0b016828d5f00..8d75d746c7fca 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_agent_name.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_agent_name.ts @@ -8,7 +8,7 @@ import { AGENT_NAME, SERVICE_NAME, } from '../../../common/elasticsearch_fieldnames'; -import { rangeFilter } from '../helpers/range_filter'; +import { rangeFilter } from '../../../common/utils/range_filter'; import { Setup, SetupTimeRange } from '../helpers/setup_request'; export async function getServiceAgentName( diff --git a/x-pack/plugins/apm/server/lib/services/get_service_transaction_types.ts b/x-pack/plugins/apm/server/lib/services/get_service_transaction_types.ts index 963dea4d8322c..d88be4055dc21 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_transaction_types.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_transaction_types.ts @@ -8,7 +8,7 @@ import { SERVICE_NAME, TRANSACTION_TYPE, } from '../../../common/elasticsearch_fieldnames'; -import { rangeFilter } from '../helpers/range_filter'; +import { rangeFilter } from '../../../common/utils/range_filter'; import { Setup, SetupTimeRange } from '../helpers/setup_request'; export async function getServiceTransactionTypes( diff --git a/x-pack/plugins/apm/server/lib/traces/get_trace_items.ts b/x-pack/plugins/apm/server/lib/traces/get_trace_items.ts index e96b323958fd7..f9374558dfeeb 100644 --- a/x-pack/plugins/apm/server/lib/traces/get_trace_items.ts +++ b/x-pack/plugins/apm/server/lib/traces/get_trace_items.ts @@ -16,7 +16,7 @@ import { import { Span } from '../../../typings/es_schemas/ui/span'; import { Transaction } from '../../../typings/es_schemas/ui/transaction'; import { APMError } from '../../../typings/es_schemas/ui/apm_error'; -import { rangeFilter } from '../helpers/range_filter'; +import { rangeFilter } from '../../../common/utils/range_filter'; import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { PromiseValueType } from '../../../typings/common'; diff --git a/x-pack/plugins/apm/server/lib/transactions/avg_duration_by_browser/fetcher.ts b/x-pack/plugins/apm/server/lib/transactions/avg_duration_by_browser/fetcher.ts index 90dd41cb9b0c8..e3d688b694380 100644 --- a/x-pack/plugins/apm/server/lib/transactions/avg_duration_by_browser/fetcher.ts +++ b/x-pack/plugins/apm/server/lib/transactions/avg_duration_by_browser/fetcher.ts @@ -13,7 +13,7 @@ import { USER_AGENT_NAME, TRANSACTION_DURATION, } from '../../../../common/elasticsearch_fieldnames'; -import { rangeFilter } from '../../helpers/range_filter'; +import { rangeFilter } from '../../../../common/utils/range_filter'; import { getBucketSize } from '../../helpers/get_bucket_size'; import { Options } from '.'; import { TRANSACTION_PAGE_LOAD } from '../../../../common/transaction_types'; diff --git a/x-pack/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts b/x-pack/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts index cc23055e34672..ea6213f64ee36 100644 --- a/x-pack/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts @@ -17,7 +17,7 @@ import { SetupTimeRange, SetupUIFilters, } from '../../helpers/setup_request'; -import { rangeFilter } from '../../helpers/range_filter'; +import { rangeFilter } from '../../../../common/utils/range_filter'; import { TRANSACTION_PAGE_LOAD } from '../../../../common/transaction_types'; export async function getTransactionAvgDurationByCountry({ diff --git a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts index 713423f8953d5..5af8b9f78cec1 100644 --- a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts @@ -20,7 +20,7 @@ import { SetupTimeRange, SetupUIFilters, } from '../../helpers/setup_request'; -import { rangeFilter } from '../../helpers/range_filter'; +import { rangeFilter } from '../../../../common/utils/range_filter'; import { getMetricsDateHistogramParams } from '../../helpers/metrics'; import { MAX_KPIS } from './constants'; import { getVizColorForIndex } from '../../../../common/viz_colors'; diff --git a/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.ts b/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.ts index 71c40010a2a3f..8e19af926ce02 100644 --- a/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.ts +++ b/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.ts @@ -15,7 +15,7 @@ import { } from '../../../../../common/elasticsearch_fieldnames'; import { PromiseReturnType } from '../../../../../../observability/typings/common'; import { getBucketSize } from '../../../helpers/get_bucket_size'; -import { rangeFilter } from '../../../helpers/range_filter'; +import { rangeFilter } from '../../../../../common/utils/range_filter'; import { Setup, SetupTimeRange, diff --git a/x-pack/plugins/apm/server/lib/transactions/distribution/get_buckets/fetcher.ts b/x-pack/plugins/apm/server/lib/transactions/distribution/get_buckets/fetcher.ts index 920552d1c1aeb..3f8bf635712be 100644 --- a/x-pack/plugins/apm/server/lib/transactions/distribution/get_buckets/fetcher.ts +++ b/x-pack/plugins/apm/server/lib/transactions/distribution/get_buckets/fetcher.ts @@ -15,7 +15,7 @@ import { TRANSACTION_SAMPLED, TRANSACTION_TYPE, } from '../../../../../common/elasticsearch_fieldnames'; -import { rangeFilter } from '../../../helpers/range_filter'; +import { rangeFilter } from '../../../../../common/utils/range_filter'; import { Setup, SetupTimeRange, diff --git a/x-pack/plugins/apm/server/lib/transactions/get_transaction/index.ts b/x-pack/plugins/apm/server/lib/transactions/get_transaction/index.ts index 60dc16b6a546c..a7de93a3bf650 100644 --- a/x-pack/plugins/apm/server/lib/transactions/get_transaction/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/get_transaction/index.ts @@ -10,7 +10,7 @@ import { TRANSACTION_ID, } from '../../../../common/elasticsearch_fieldnames'; import { Transaction } from '../../../../typings/es_schemas/ui/transaction'; -import { rangeFilter } from '../../helpers/range_filter'; +import { rangeFilter } from '../../../../common/utils/range_filter'; import { Setup, SetupTimeRange, diff --git a/x-pack/plugins/apm/server/lib/ui_filters/get_environments.ts b/x-pack/plugins/apm/server/lib/ui_filters/get_environments.ts index ccbe7a19d2f82..3fca30634be6a 100644 --- a/x-pack/plugins/apm/server/lib/ui_filters/get_environments.ts +++ b/x-pack/plugins/apm/server/lib/ui_filters/get_environments.ts @@ -9,7 +9,7 @@ import { SERVICE_ENVIRONMENT, SERVICE_NAME, } from '../../../common/elasticsearch_fieldnames'; -import { rangeFilter } from '../helpers/range_filter'; +import { rangeFilter } from '../../../common/utils/range_filter'; import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { ENVIRONMENT_NOT_DEFINED } from '../../../common/environment_filter_values'; import { ESFilter } from '../../../typings/elasticsearch'; diff --git a/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/config.ts b/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/config.ts index 8f35664c2599c..25a559cb07a3d 100644 --- a/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/config.ts +++ b/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/config.ts @@ -11,6 +11,11 @@ import { HOST_NAME, TRANSACTION_RESULT, SERVICE_VERSION, + TRANSACTION_URL, + USER_AGENT_NAME, + USER_AGENT_DEVICE, + CLIENT_GEO, + USER_AGENT_OS, } from '../../../../common/elasticsearch_fieldnames'; const filtersByName = { @@ -50,6 +55,36 @@ const filtersByName = { }), fieldName: SERVICE_VERSION, }, + transactionUrl: { + title: i18n.translate('xpack.apm.localFilters.titles.transactionUrl', { + defaultMessage: 'Url', + }), + fieldName: TRANSACTION_URL, + }, + browser: { + title: i18n.translate('xpack.apm.localFilters.titles.browser', { + defaultMessage: 'Browser', + }), + fieldName: USER_AGENT_NAME, + }, + device: { + title: i18n.translate('xpack.apm.localFilters.titles.device', { + defaultMessage: 'Device', + }), + fieldName: USER_AGENT_DEVICE, + }, + location: { + title: i18n.translate('xpack.apm.localFilters.titles.location', { + defaultMessage: 'Location', + }), + fieldName: CLIENT_GEO, + }, + os: { + title: i18n.translate('xpack.apm.localFilters.titles.os', { + defaultMessage: 'OS', + }), + fieldName: USER_AGENT_OS, + }, }; export type LocalUIFilterName = keyof typeof filtersByName; diff --git a/x-pack/plugins/apm/server/routes/create_apm_api.ts b/x-pack/plugins/apm/server/routes/create_apm_api.ts index bdfb49fa30828..a34690aff43b4 100644 --- a/x-pack/plugins/apm/server/routes/create_apm_api.ts +++ b/x-pack/plugins/apm/server/routes/create_apm_api.ts @@ -59,6 +59,7 @@ import { transactionsLocalFiltersRoute, serviceNodesLocalFiltersRoute, uiFiltersEnvironmentsRoute, + rumOverviewLocalFiltersRoute, } from './ui_filters'; import { createApi } from './create_api'; import { serviceMapRoute, serviceMapServiceNodeRoute } from './service_map'; @@ -70,6 +71,11 @@ import { listCustomLinksRoute, customLinkTransactionRoute, } from './settings/custom_link'; +import { + rumClientMetricsRoute, + rumPageViewsTrendRoute, + rumPageLoadDistributionRoute, +} from './rum_client'; const createApmApi = () => { const api = createApi() @@ -148,7 +154,13 @@ const createApmApi = () => { .add(updateCustomLinkRoute) .add(deleteCustomLinkRoute) .add(listCustomLinksRoute) - .add(customLinkTransactionRoute); + .add(customLinkTransactionRoute) + + // Rum Overview + .add(rumOverviewLocalFiltersRoute) + .add(rumPageViewsTrendRoute) + .add(rumPageLoadDistributionRoute) + .add(rumClientMetricsRoute); return api; }; diff --git a/x-pack/plugins/apm/server/routes/rum_client.ts b/x-pack/plugins/apm/server/routes/rum_client.ts new file mode 100644 index 0000000000000..9b5f6529b1783 --- /dev/null +++ b/x-pack/plugins/apm/server/routes/rum_client.ts @@ -0,0 +1,57 @@ +/* + * 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 * as t from 'io-ts'; +import { createRoute } from './create_route'; +import { setupRequest } from '../lib/helpers/setup_request'; +import { getClientMetrics } from '../lib/rum_client/get_client_metrics'; +import { rangeRt, uiFiltersRt } from './default_api_types'; +import { getPageViewTrends } from '../lib/rum_client/get_page_view_trends'; +import { getPageLoadDistribution } from '../lib/rum_client/get_page_load_distribution'; + +export const percentileRangeRt = t.partial({ + minPercentile: t.string, + maxPercentile: t.string, +}); + +export const rumClientMetricsRoute = createRoute(() => ({ + path: '/api/apm/rum/client-metrics', + params: { + query: t.intersection([uiFiltersRt, rangeRt]), + }, + handler: async ({ context, request }) => { + const setup = await setupRequest(context, request); + + return getClientMetrics({ setup }); + }, +})); + +export const rumPageLoadDistributionRoute = createRoute(() => ({ + path: '/api/apm/rum-client/page-load-distribution', + params: { + query: t.intersection([uiFiltersRt, rangeRt, percentileRangeRt]), + }, + handler: async ({ context, request }) => { + const setup = await setupRequest(context, request); + + const { + query: { minPercentile, maxPercentile }, + } = context.params; + + return getPageLoadDistribution({ setup, minPercentile, maxPercentile }); + }, +})); + +export const rumPageViewsTrendRoute = createRoute(() => ({ + path: '/api/apm/rum-client/page-view-trends', + params: { + query: t.intersection([uiFiltersRt, rangeRt]), + }, + handler: async ({ context, request }) => { + const setup = await setupRequest(context, request); + return getPageViewTrends({ setup }); + }, +})); diff --git a/x-pack/plugins/apm/server/routes/ui_filters.ts b/x-pack/plugins/apm/server/routes/ui_filters.ts index 8f4ef94b86ac5..280645d4de8d0 100644 --- a/x-pack/plugins/apm/server/routes/ui_filters.ts +++ b/x-pack/plugins/apm/server/routes/ui_filters.ts @@ -29,6 +29,7 @@ import { createRoute } from './create_route'; import { uiFiltersRt, rangeRt } from './default_api_types'; import { jsonRt } from '../../common/runtime_types/json_rt'; import { getServiceNodesProjection } from '../../common/projections/service_nodes'; +import { getRumOverviewProjection } from '../../common/projections/rum_overview'; export const uiFiltersEnvironmentsRoute = createRoute(() => ({ path: '/api/apm/ui_filters/environments', @@ -221,6 +222,16 @@ export const serviceNodesLocalFiltersRoute = createLocalFiltersRoute({ }), }); +export const rumOverviewLocalFiltersRoute = createLocalFiltersRoute({ + path: '/api/apm/ui_filters/local_filters/rumOverview', + getProjection: ({ setup }) => { + return getRumOverviewProjection({ + setup, + }); + }, + queryRt: t.type({}), +}); + type BaseQueryType = typeof localUiBaseQueryRt; type GetProjection< diff --git a/x-pack/plugins/apm/typings/elasticsearch/aggregations.ts b/x-pack/plugins/apm/typings/elasticsearch/aggregations.ts index 0739e8e6120bf..6ee26caa4ef7c 100644 --- a/x-pack/plugins/apm/typings/elasticsearch/aggregations.ts +++ b/x-pack/plugins/apm/typings/elasticsearch/aggregations.ts @@ -137,6 +137,15 @@ export interface AggregationOptionsByType { >; keyed?: boolean; }; + auto_date_histogram: { + field: string; + buckets: number; + }; + percentile_ranks: { + field: string; + values: string[]; + keyed?: boolean; + }; } type AggregationType = keyof AggregationOptionsByType; @@ -301,6 +310,23 @@ interface AggregationResponsePart< ? Record : { buckets: DateRangeBucket[] }; }; + auto_date_histogram: { + buckets: Array< + { + doc_count: number; + key: number; + key_as_string: string; + } & BucketSubAggregationResponse< + TAggregationOptionsMap['aggs'], + TDocument + > + >; + interval: string; + }; + + percentile_ranks: { + values: Record | Array<{ key: number; value: number }>; + }; } // Type for debugging purposes. If you see an error in AggregationResponseMap diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 37cdbf5c0d8a9..d119ddb5a1a1f 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -4229,7 +4229,6 @@ "xpack.apm.jvmsTable.noJvmsLabel": "JVM が見つかりませんでした", "xpack.apm.jvmsTable.nonHeapMemoryColumnLabel": "非ヒープ領域の平均", "xpack.apm.jvmsTable.threadCountColumnLabel": "最大スレッド数", - "xpack.apm.kueryBar.disabledPlaceholder": "サービスマップの検索は利用できません", "xpack.apm.kueryBar.placeholder": "検索 {event, select,\n transaction {トランザクション}\n metric {メトリック}\n error {エラー}\n other {その他}\n } (E.g. {queryExample})", "xpack.apm.license.betaBadge": "ベータ", "xpack.apm.license.betaTooltipMessage": "現在、この機能はベータです。不具合を見つけた場合やご意見がある場合、サポートに問い合わせるか、またはディスカッションフォーラムにご報告ください。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 2dfa0d40b9a8a..240baa3fe7744 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -4232,7 +4232,6 @@ "xpack.apm.jvmsTable.noJvmsLabel": "未找到任何 JVM", "xpack.apm.jvmsTable.nonHeapMemoryColumnLabel": "非堆内存平均值", "xpack.apm.jvmsTable.threadCountColumnLabel": "线程计数最大值", - "xpack.apm.kueryBar.disabledPlaceholder": "搜索不适用于服务地图", "xpack.apm.kueryBar.placeholder": "搜索{event, select,\n transaction {事务}\n metric {指标}\n error {错误}\n other {事务、错误和指标}\n }(例如 {queryExample})", "xpack.apm.license.betaBadge": "公测版", "xpack.apm.license.betaTooltipMessage": "此功能当前为公测版。如果遇到任何错误或有任何反馈,请报告问题或访问我们的论坛。",