From 2ce942488b8643ba55086cdd7dd63ebd12c92800 Mon Sep 17 00:00:00 2001 From: Robert Austin Date: Wed, 28 Oct 2020 10:44:25 -0400 Subject: [PATCH 01/80] [Resolver] Enable resolver test plugin tests (#81339) Resolver has a test plugin. It can be found in `x-pack/tests/plugin_functional`. You can try it out like this: ``` yarn start --plugin-path x-pack/test/plugin_functional/plugins/resolver_test/ ``` This PR enables automated tests for the test plugin. This ensures that the test plugin will render. --- x-pack/scripts/functional_tests.js | 1 + x-pack/test/plugin_functional/config.ts | 2 +- .../test_suites/global_search/global_search_bar.ts | 3 ++- .../test_suites/global_search/index.ts | 3 ++- .../plugin_functional/test_suites/resolver/index.ts | 12 ++++++------ 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/x-pack/scripts/functional_tests.js b/x-pack/scripts/functional_tests.js index b15a2cf8d1f1d..ad6ec7bf82282 100644 --- a/x-pack/scripts/functional_tests.js +++ b/x-pack/scripts/functional_tests.js @@ -7,6 +7,7 @@ const alwaysImportedTests = [ require.resolve('../test/functional/config.js'), require.resolve('../test/security_solution_endpoint/config.ts'), + require.resolve('../test/plugin_functional/config.ts'), require.resolve('../test/functional_with_es_ssl/config.ts'), require.resolve('../test/functional/config_security_basic.ts'), require.resolve('../test/security_functional/login_selector.config.ts'), diff --git a/x-pack/test/plugin_functional/config.ts b/x-pack/test/plugin_functional/config.ts index e7d96023f3653..37d35662eb15b 100644 --- a/x-pack/test/plugin_functional/config.ts +++ b/x-pack/test/plugin_functional/config.ts @@ -59,7 +59,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { apps: { ...xpackFunctionalConfig.get('apps'), resolverTest: { - pathname: '/app/resolver_test', + pathname: '/app/resolverTest', }, }, diff --git a/x-pack/test/plugin_functional/test_suites/global_search/global_search_bar.ts b/x-pack/test/plugin_functional/test_suites/global_search/global_search_bar.ts index 2b7ae3e576590..005d516e2943c 100644 --- a/x-pack/test/plugin_functional/test_suites/global_search/global_search_bar.ts +++ b/x-pack/test/plugin_functional/test_suites/global_search/global_search_bar.ts @@ -8,7 +8,8 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getPageObjects, getService }: FtrProviderContext) { - describe('GlobalSearchBar', function () { + // See: https://github.com/elastic/kibana/issues/81397 + describe.skip('GlobalSearchBar', function () { const { common } = getPageObjects(['common']); const find = getService('find'); const testSubjects = getService('testSubjects'); diff --git a/x-pack/test/plugin_functional/test_suites/global_search/index.ts b/x-pack/test/plugin_functional/test_suites/global_search/index.ts index a54e6933be69b..f43e293c30fd6 100644 --- a/x-pack/test/plugin_functional/test_suites/global_search/index.ts +++ b/x-pack/test/plugin_functional/test_suites/global_search/index.ts @@ -7,7 +7,8 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { - describe('GlobalSearch API', function () { + // See https://github.com/elastic/kibana/issues/81397 + describe.skip('GlobalSearch API', function () { this.tags('ciGroup7'); loadTestFile(require.resolve('./global_search_api')); loadTestFile(require.resolve('./global_search_providers')); diff --git a/x-pack/test/plugin_functional/test_suites/resolver/index.ts b/x-pack/test/plugin_functional/test_suites/resolver/index.ts index 9cc2751a4287d..8cdf54a50bc53 100644 --- a/x-pack/test/plugin_functional/test_suites/resolver/index.ts +++ b/x-pack/test/plugin_functional/test_suites/resolver/index.ts @@ -10,18 +10,18 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const pageObjects = getPageObjects(['common']); const testSubjects = getService('testSubjects'); - describe('Resolver embeddable test app', function () { + describe('Resolver test app', function () { this.tags('ciGroup7'); beforeEach(async function () { await pageObjects.common.navigateToApp('resolverTest'); }); - it('renders a container div for the embeddable', async function () { - await testSubjects.existOrFail('resolverEmbeddableContainer'); - }); - it('renders resolver', async function () { - await testSubjects.existOrFail('resolverEmbeddable'); + it('renders at least one node, one node-list, one edge line, and graph controls', async function () { + await testSubjects.existOrFail('resolver:node'); + await testSubjects.existOrFail('resolver:node-list'); + await testSubjects.existOrFail('resolver:graph:edgeline'); + await testSubjects.existOrFail('resolver:graph-controls'); }); }); } From 333f8732de2ea962dda8020d82aa4f57eb0a3591 Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Wed, 28 Oct 2020 10:38:23 -0500 Subject: [PATCH 02/80] APM Experiments settings (#81554) * Add advanced settings for APM * Register advanced settings in server startup that show in the Kibana advanced settings UI. (Fixes #81396.) * Format settings pages to be more consistent. --- x-pack/plugins/apm/common/ui_settings_keys.ts | 8 +++ .../app/ServiceDetails/ServiceDetailTabs.tsx | 49 ++++++++++++------- .../Settings/AgentConfigurations/index.tsx | 11 ++++- .../app/Settings/ApmIndices/index.test.tsx | 6 +-- .../app/Settings/ApmIndices/index.tsx | 46 ++++++++--------- .../CustomLink/CreateCustomLinkButton.tsx | 2 +- .../Settings/CustomizeUI/CustomLink/Title.tsx | 23 ++------- .../Settings/CustomizeUI/CustomLink/index.tsx | 24 ++++++--- .../Settings/anomaly_detection/jobs_list.tsx | 2 +- x-pack/plugins/apm/readme.md | 41 +++++++++++----- x-pack/plugins/apm/server/plugin.ts | 4 ++ x-pack/plugins/apm/server/ui_settings.ts | 48 ++++++++++++++++++ 12 files changed, 180 insertions(+), 84 deletions(-) create mode 100644 x-pack/plugins/apm/common/ui_settings_keys.ts create mode 100644 x-pack/plugins/apm/server/ui_settings.ts diff --git a/x-pack/plugins/apm/common/ui_settings_keys.ts b/x-pack/plugins/apm/common/ui_settings_keys.ts new file mode 100644 index 0000000000000..38922fa445a47 --- /dev/null +++ b/x-pack/plugins/apm/common/ui_settings_keys.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export const enableCorrelations = 'apm:enableCorrelations'; +export const enableServiceOverview = 'apm:enableServiceOverview'; 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 cbb6d9a8fbe41..76c8a289b830c 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx @@ -8,6 +8,7 @@ import { EuiTabs } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; import { isJavaAgentName, isRumAgentName } from '../../../../common/agent_name'; +import { enableServiceOverview } from '../../../../common/ui_settings_keys'; import { useAgentName } from '../../../hooks/useAgentName'; import { useApmPluginContext } from '../../../hooks/useApmPluginContext'; import { EuiTabLink } from '../../shared/EuiTabLink'; @@ -29,7 +30,19 @@ interface Props { export function ServiceDetailTabs({ serviceName, tab }: Props) { const { agentName } = useAgentName(); - const { serviceMapEnabled } = useApmPluginContext().config; + const { uiSettings } = useApmPluginContext().core; + + const overviewTab = { + link: ( + + {i18n.translate('xpack.apm.serviceDetails.overviewTabLabel', { + defaultMessage: 'Overview', + })} + + ), + render: () => <>, + name: 'overview', + }; const transactionsTab = { link: ( @@ -57,7 +70,23 @@ export function ServiceDetailTabs({ serviceName, tab }: Props) { name: 'errors', }; - const tabs = [transactionsTab, errorsTab]; + const serviceMapTab = { + link: ( + + {i18n.translate('xpack.apm.home.serviceMapTabLabel', { + defaultMessage: 'Service Map', + })} + + ), + render: () => , + name: 'service-map', + }; + + const tabs = [transactionsTab, errorsTab, serviceMapTab]; + + if (uiSettings.get(enableServiceOverview)) { + tabs.unshift(overviewTab); + } if (isJavaAgentName(agentName)) { const nodesListTab = { @@ -89,22 +118,6 @@ export function ServiceDetailTabs({ serviceName, tab }: Props) { tabs.push(metricsTab); } - const serviceMapTab = { - link: ( - - {i18n.translate('xpack.apm.home.serviceMapTabLabel', { - defaultMessage: 'Service Map', - })} - - ), - render: () => , - name: 'service-map', - }; - - if (serviceMapEnabled) { - tabs.push(serviceMapTab); - } - const selectedTab = tabs.find((serviceTab) => serviceTab.name === tab); return ( diff --git a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/index.tsx index 8e32c55da9161..dfc78028c3596 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/index.tsx @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - import { EuiButton, EuiFlexGroup, @@ -37,6 +36,14 @@ export function AgentConfigurations() { return ( <> + +

+ {i18n.translate('xpack.apm.agentConfig.titleText', { + defaultMessage: 'Agent remote configuration', + })} +

+
+ @@ -44,7 +51,7 @@ export function AgentConfigurations() {

{i18n.translate( 'xpack.apm.agentConfig.configurationsPanelTitle', - { defaultMessage: 'Agent remote configuration' } + { defaultMessage: 'Configurations' } )}

diff --git a/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.test.tsx b/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.test.tsx index 68e75d595363d..53794ca9965ff 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.test.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.test.tsx @@ -24,11 +24,11 @@ describe('ApmIndices', () => { ); expect(getByText('Indices')).toMatchInlineSnapshot(` -

Indices -

+ `); expect(spy).toHaveBeenCalledTimes(2); diff --git a/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.tsx index 145fb9683cb61..fac947b3ec68e 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/ApmIndices/index.tsx @@ -163,23 +163,24 @@ export function ApmIndices() { }; return ( - - - - -

- {i18n.translate('xpack.apm.settings.apmIndices.title', { - defaultMessage: 'Indices', - })} -

-
- - -

- {i18n.translate('xpack.apm.settings.apmIndices.description', { - defaultMessage: `The APM UI uses index patterns to query your APM indices. If you've customized the index names that APM Server writes events to, you may need to update these patterns for the APM UI to work. Settings here take precedence over those set in kibana.yml.`, - })} -

+ <> + +

+ {i18n.translate('xpack.apm.settings.apmIndices.title', { + defaultMessage: 'Indices', + })} +

+
+ + + {i18n.translate('xpack.apm.settings.apmIndices.description', { + defaultMessage: `The APM UI uses index patterns to query your APM indices. If you've customized the index names that APM Server writes events to, you may need to update these patterns for the APM UI to work. Settings here take precedence over those set in kibana.yml.`, + })} + + + + + {APM_INDEX_LABELS.map(({ configurationName, label }) => { const matchedConfiguration = data.find( @@ -239,11 +240,10 @@ export function ApmIndices() { -
-
-
- - -
+
+
+ +
+ ); } diff --git a/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/CreateCustomLinkButton.tsx b/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/CreateCustomLinkButton.tsx index 2e860ebe22c0f..56b3eaf425af7 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/CreateCustomLinkButton.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/CreateCustomLinkButton.tsx @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; export function CreateCustomLinkButton({ onClick }: { onClick: () => void }) { return ( - + {i18n.translate( 'xpack.apm.settings.customizeUI.customLink.createCustomLink', { defaultMessage: 'Create custom link' } diff --git a/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/Title.tsx b/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/Title.tsx index 22d8749d78834..2017aa42e1c5a 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/Title.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/Title.tsx @@ -3,7 +3,8 @@ * 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, EuiIconTip, EuiTitle } from '@elastic/eui'; + +import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; @@ -11,28 +12,14 @@ export function Title() { return ( - + -

+

{i18n.translate('xpack.apm.settings.customizeUI.customLink', { defaultMessage: 'Custom Links', })} -

-
- - - +
diff --git a/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/index.tsx index 45a7fa2a118f2..a7d7cf40ba849 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/CustomizeUI/CustomLink/index.tsx @@ -4,19 +4,26 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiPanel, EuiSpacer, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiPanel, + EuiSpacer, + EuiText, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import { isEmpty } from 'lodash'; import React, { useEffect, useState } from 'react'; import { INVALID_LICENSE } from '../../../../../../common/custom_link'; import { CustomLink } from '../../../../../../common/custom_link/custom_link_types'; +import { FETCH_STATUS, useFetcher } from '../../../../../hooks/useFetcher'; import { useLicense } from '../../../../../hooks/useLicense'; -import { useFetcher, FETCH_STATUS } from '../../../../../hooks/useFetcher'; +import { LicensePrompt } from '../../../../shared/LicensePrompt'; +import { CreateCustomLinkButton } from './CreateCustomLinkButton'; import { CustomLinkFlyout } from './CustomLinkFlyout'; import { CustomLinkTable } from './CustomLinkTable'; import { EmptyPrompt } from './EmptyPrompt'; import { Title } from './Title'; -import { CreateCustomLinkButton } from './CreateCustomLinkButton'; -import { LicensePrompt } from '../../../../shared/LicensePrompt'; export function CustomLinkOverview() { const license = useLicense(); @@ -82,8 +89,13 @@ export function CustomLinkOverview() {
)}
- - + + + {i18n.translate('xpack.apm.settings.customizeUI.customLink.info', { + defaultMessage: + 'These links will be shown in the Actions context menu for transactions.', + })} + {hasValidLicense ? ( showEmptyPrompt ? ( diff --git a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx index 6e95df0dddd84..137dcfcdbb4f0 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx @@ -80,7 +80,7 @@ export function JobsList({ data, status, onAddEnvironments }: Props) { - + {i18n.translate( 'xpack.apm.settings.anomalyDetection.jobList.addEnvironments', { diff --git a/x-pack/plugins/apm/readme.md b/x-pack/plugins/apm/readme.md index d6fdb5f52291c..0adfb99e7164e 100644 --- a/x-pack/plugins/apm/readme.md +++ b/x-pack/plugins/apm/readme.md @@ -1,8 +1,8 @@ # Documentation for APM UI developers -### Setup local environment +## Local environment setup -#### Kibana +### Kibana ``` git clone git@github.com:elastic/kibana.git @@ -11,15 +11,15 @@ yarn kbn bootstrap yarn start --no-base-path ``` -#### APM Server, Elasticsearch and data +### APM Server, Elasticsearch and data To access an elasticsearch instance that has live data you have two options: -##### A. Connect to Elasticsearch on Cloud (internal devs only) +#### A. Connect to Elasticsearch on Cloud (internal devs only) Find the credentials for the cluster [here](https://github.com/elastic/apm-dev/blob/master/docs/credentials/apm-ui-clusters.md#apmelstcco) -##### B. Start Elastic Stack and APM data generators +#### B. Start Elastic Stack and APM data generators ``` git clone git@github.com:elastic/apm-integration-testing.git @@ -29,6 +29,8 @@ cd apm-integration-testing/ _Docker Compose is required_ +## Testing + ### E2E (Cypress) tests ```sh @@ -109,23 +111,23 @@ The API tests for "trial" are located in `x-pack/test/apm_api_integration/trial/ For debugging access Elasticsearch on http://localhost:9220` (elastic/changeme) -### Linting +## Linting _Note: Run the following commands from `kibana/`._ -#### Prettier +### Prettier ``` yarn prettier "./x-pack/plugins/apm/**/*.{tsx,ts,js}" --write ``` -#### ESLint +### ESLint ``` yarn eslint ./x-pack/plugins/apm --fix ``` -### Setup default APM users +## Setup default APM users APM behaves differently depending on which the role and permissions a logged in user has. For testing purposes APM uses 3 custom users: @@ -144,20 +146,35 @@ node x-pack/plugins/apm/scripts/setup-kibana-security.js --role-suffix Advanced Settings > Observability. + +## Further resources - [Cypress integration tests](./e2e/README.md) - [VSCode setup instructions](./dev_docs/vscode_setup.md) diff --git a/x-pack/plugins/apm/server/plugin.ts b/x-pack/plugins/apm/server/plugin.ts index b417f8689b229..d3341b6c1b163 100644 --- a/x-pack/plugins/apm/server/plugin.ts +++ b/x-pack/plugins/apm/server/plugin.ts @@ -3,6 +3,7 @@ * 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'; import { combineLatest, Observable } from 'rxjs'; import { map, take } from 'rxjs/operators'; @@ -36,6 +37,7 @@ import { createApmCustomLinkIndex } from './lib/settings/custom_link/create_cust import { createApmApi } from './routes/create_apm_api'; import { apmIndices, apmTelemetry } from './saved_objects'; import { createElasticCloudInstructions } from './tutorial/elastic_cloud'; +import { uiSettings } from './ui_settings'; export interface APMPluginSetup { config$: Observable; @@ -75,6 +77,8 @@ export class APMPlugin implements Plugin { core.savedObjects.registerType(apmIndices); core.savedObjects.registerType(apmTelemetry); + core.uiSettings.register(uiSettings); + if (plugins.actions && plugins.alerts) { registerApmAlerts({ alerts: plugins.alerts, diff --git a/x-pack/plugins/apm/server/ui_settings.ts b/x-pack/plugins/apm/server/ui_settings.ts new file mode 100644 index 0000000000000..fe5b11d89d716 --- /dev/null +++ b/x-pack/plugins/apm/server/ui_settings.ts @@ -0,0 +1,48 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { i18n } from '@kbn/i18n'; +import { UiSettingsParams } from '../../../../src/core/types'; +import { + enableCorrelations, + enableServiceOverview, +} from '../common/ui_settings_keys'; + +/** + * uiSettings definitions for APM. + */ +export const uiSettings: Record> = { + [enableCorrelations]: { + category: ['Observability'], + name: i18n.translate('xpack.apm.enableCorrelationsExperimentName', { + defaultMessage: 'APM Correlations', + }), + value: false, + description: i18n.translate( + 'xpack.apm.enableCorrelationsExperimentDescription', + { + defaultMessage: + 'Enable the experimental correlations UI and API endpoint in APM.', + } + ), + schema: schema.boolean(), + }, + [enableServiceOverview]: { + category: ['Observability'], + name: i18n.translate('xpack.apm.enableServiceOverviewExperimentName', { + defaultMessage: 'APM Service overview', + }), + value: false, + description: i18n.translate( + 'xpack.apm.enableServiceOverviewExperimentDescription', + { + defaultMessage: 'Enable the Overview tab for services in APM.', + } + ), + schema: schema.boolean(), + }, +}; From ac70e1e944b82a7d73272fa3e1b496bb32234122 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Wed, 28 Oct 2020 17:10:49 +0100 Subject: [PATCH 03/80] [ILM] Migrate Cold phase to Form Lib (#81754) * use form lib fields and start updating deserializer * delete legacy data tier allocation field * finished deserialization * delete legacy serialization, validation and deserialization * fix type issue and remove propertyOf for now * fix legacy tests and create another number validator * added serialization test coverage * fix https://github.com/elastic/kibana/issues/81697 * clean up remaining legacy tests and slight update to existing test * remove legacy unused components * fix copy to be clearer for more scenarios * remove remaining coldphase interface use and clean up unused i18n * update default index priority for cold phase * updated cold phase index priority to 0 Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../edit_policy/constants.ts | 25 ++ .../edit_policy/edit_policy.helpers.tsx | 22 +- .../edit_policy/edit_policy.test.ts | 184 +++++++++++--- .../client_integration/helpers/index.ts | 1 + .../__jest__/components/edit_policy.test.tsx | 47 ++-- .../common/types/policies.ts | 9 - .../public/application/constants/policy.ts | 13 +- .../cloud_data_tier_callout.tsx | 54 ---- .../data_tier_allocation.scss | 9 - .../data_tier_allocation.tsx | 184 -------------- .../default_allocation_notice.tsx | 106 -------- .../components/data_tier_allocation/index.ts | 13 - .../no_node_attributes_warning.tsx | 50 ---- .../data_tier_allocation/node_allocation.tsx | 121 --------- .../node_attrs_details.tsx | 106 -------- .../node_data_provider.tsx | 70 ------ .../components/data_tier_allocation/types.ts | 28 --- .../components/forcemerge_legacy.tsx | 131 ---------- .../sections/edit_policy/components/index.ts | 9 - .../components/phases/cold_phase.tsx | 233 ------------------ .../phases/cold_phase/cold_phase.tsx | 187 ++++++++++++++ .../components/phases/cold_phase}/index.ts | 2 +- .../components/no_node_attributes_warning.tsx | 4 +- .../data_tier_allocation_legacy_field.tsx | 141 ----------- .../components/phases/shared/index.ts | 2 - .../phases/warm_phase/warm_phase.tsx | 15 +- .../components/policy_json_flyout.tsx | 1 + .../components/set_priority_input_legacy.tsx | 85 ------- .../sections/edit_policy/deserializer.ts | 39 ++- .../sections/edit_policy/edit_policy.tsx | 14 +- .../sections/edit_policy/form_schema.ts | 75 +++++- .../sections/edit_policy/form_validations.ts | 38 ++- .../sections/edit_policy/serializer.ts | 36 +++ .../application/sections/edit_policy/types.ts | 22 +- .../services/policies/cold_phase.ts | 154 ------------ .../policies/policy_serialization.test.ts | 123 +-------- .../services/policies/policy_serialization.ts | 13 +- .../services/policies/policy_validation.ts | 14 +- .../shared/serialize_phase_with_allocation.ts | 42 ---- .../application/services/ui_metric.test.ts | 5 +- .../public/application/services/ui_metric.ts | 4 +- .../translations/translations/ja-JP.json | 3 - .../translations/translations/zh-CN.json | 3 - 43 files changed, 614 insertions(+), 1823 deletions(-) delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/cloud_data_tier_callout.tsx delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/data_tier_allocation.scss delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/data_tier_allocation.tsx delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_notice.tsx delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/index.ts delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/no_node_attributes_warning.tsx delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/node_allocation.tsx delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/node_attrs_details.tsx delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/node_data_provider.tsx delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/types.ts delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/forcemerge_legacy.tsx delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase.tsx create mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase/cold_phase.tsx rename x-pack/plugins/index_lifecycle_management/public/application/{services/policies/shared => sections/edit_policy/components/phases/cold_phase}/index.ts (74%) delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared/data_tier_allocation_legacy_field.tsx delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/set_priority_input_legacy.tsx delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/services/policies/cold_phase.ts delete mode 100644 x-pack/plugins/index_lifecycle_management/public/application/services/policies/shared/serialize_phase_with_allocation.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts index 0a96146339a58..3d430cf31621e 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts @@ -30,6 +30,31 @@ export const DEFAULT_POLICY: PolicyFromES = { name: 'my_policy', }; +export const POLICY_WITH_MIGRATE_OFF: PolicyFromES = { + version: 1, + modified_date: Date.now().toString(), + policy: { + name: 'my_policy', + phases: { + hot: { + min_age: '0ms', + actions: { + rollover: { + max_age: '30d', + max_size: '50gb', + }, + }, + }, + warm: { + actions: { + migrate: { enabled: false }, + }, + }, + }, + }, + name: 'my_policy', +}; + export const POLICY_WITH_INCLUDE_EXCLUDE: PolicyFromES = { version: 1, modified_date: Date.now().toString(), diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx index 1716f124b0c83..ad61641ea1e36 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.helpers.tsx @@ -154,12 +154,12 @@ export const setup = async () => { component.update(); }; - const setSelectedNodeAttribute = (phase: string) => + const setSelectedNodeAttribute = (phase: Phases) => createFormSetValueAction(`${phase}-selectedNodeAttrs`); - const setReplicas = async (value: string) => { - await createFormToggleAction('warm-setReplicasSwitch')(true); - await createFormSetValueAction('warm-selectedReplicaCount')(value); + const setReplicas = (phase: Phases) => async (value: string) => { + await createFormToggleAction(`${phase}-setReplicasSwitch`)(true); + await createFormSetValueAction(`${phase}-selectedReplicaCount`)(value); }; const setShrink = async (value: string) => { @@ -167,6 +167,8 @@ export const setup = async () => { await createFormSetValueAction('warm-selectedPrimaryShardCount')(value); }; + const setFreeze = createFormToggleAction('freezeSwitch'); + return { ...testBed, actions: { @@ -189,13 +191,23 @@ export const setup = async () => { setMinAgeUnits: setMinAgeUnits('warm'), setDataAllocation: setDataAllocation('warm'), setSelectedNodeAttribute: setSelectedNodeAttribute('warm'), - setReplicas, + setReplicas: setReplicas('warm'), setShrink, toggleForceMerge: toggleForceMerge('warm'), setForcemergeSegments: setForcemergeSegmentsCount('warm'), setBestCompression: setBestCompression('warm'), setIndexPriority: setIndexPriority('warm'), }, + cold: { + enable: enable('cold'), + setMinAgeValue: setMinAgeValue('cold'), + setMinAgeUnits: setMinAgeUnits('cold'), + setDataAllocation: setDataAllocation('cold'), + setSelectedNodeAttribute: setSelectedNodeAttribute('cold'), + setReplicas: setReplicas('cold'), + setFreeze, + setIndexPriority: setIndexPriority('cold'), + }, }, }; }; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts index fccffde3f793f..11fadf51f27f8 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts @@ -15,6 +15,7 @@ import { NEW_SNAPSHOT_POLICY_NAME, SNAPSHOT_POLICY_NAME, DEFAULT_POLICY, + POLICY_WITH_MIGRATE_OFF, POLICY_WITH_INCLUDE_EXCLUDE, POLICY_WITH_NODE_ATTR_AND_OFF_ALLOCATION, POLICY_WITH_NODE_ROLE_ALLOCATION, @@ -199,26 +200,6 @@ describe('', () => { `); }); - test('default allocation with replicas set', async () => { - const { actions } = testBed; - await actions.warm.enable(true); - await actions.warm.setReplicas('123'); - await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const warmPhaseActions = JSON.parse(JSON.parse(latestRequest.requestBody).body).phases.warm - .actions; - expect(warmPhaseActions).toMatchInlineSnapshot(` - Object { - "allocate": Object { - "number_of_replicas": 123, - }, - "set_priority": Object { - "priority": 50, - }, - } - `); - }); - test('setting warm phase on rollover to "true"', async () => { const { actions } = testBed; await actions.warm.enable(true); @@ -252,6 +233,7 @@ describe('', () => { test('preserves include, exclude allocation settings', async () => { const { actions } = testBed; await actions.warm.setDataAllocation('node_attrs'); + await actions.warm.setSelectedNodeAttribute('test:123'); await actions.savePolicy(); const latestRequest = server.requests[server.requests.length - 1]; const warmPhaseAllocate = JSON.parse(JSON.parse(latestRequest.requestBody).body).phases.warm @@ -264,6 +246,101 @@ describe('', () => { "include": Object { "abc": "123", }, + "require": Object { + "test": "123", + }, + } + `); + }); + }); + }); + + describe('cold phase', () => { + describe('serialization', () => { + beforeEach(async () => { + httpRequestsMockHelpers.setLoadPolicies([DEFAULT_POLICY]); + httpRequestsMockHelpers.setListNodes({ + nodesByRoles: {}, + nodesByAttributes: { test: ['123'] }, + isUsingDeprecatedDataRoleConfig: false, + }); + httpRequestsMockHelpers.setLoadSnapshotPolicies([]); + + await act(async () => { + testBed = await setup(); + }); + + const { component } = testBed; + component.update(); + }); + + test('default values', async () => { + const { actions } = testBed; + + await actions.cold.enable(true); + await actions.savePolicy(); + const latestRequest = server.requests[server.requests.length - 1]; + const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); + expect(entirePolicy.phases.cold).toMatchInlineSnapshot(` + Object { + "actions": Object { + "set_priority": Object { + "priority": 0, + }, + }, + "min_age": "0d", + } + `); + }); + + test('setting all values', async () => { + const { actions } = testBed; + + await actions.cold.enable(true); + await actions.cold.setMinAgeValue('123'); + await actions.cold.setMinAgeUnits('s'); + await actions.cold.setDataAllocation('node_attrs'); + await actions.cold.setSelectedNodeAttribute('test:123'); + await actions.cold.setReplicas('123'); + await actions.cold.setFreeze(true); + await actions.cold.setIndexPriority('123'); + + await actions.savePolicy(); + const latestRequest = server.requests[server.requests.length - 1]; + const entirePolicy = JSON.parse(JSON.parse(latestRequest.requestBody).body); + + expect(entirePolicy).toMatchInlineSnapshot(` + Object { + "name": "my_policy", + "phases": Object { + "cold": Object { + "actions": Object { + "allocate": Object { + "number_of_replicas": 123, + "require": Object { + "test": "123", + }, + }, + "freeze": Object {}, + "set_priority": Object { + "priority": 123, + }, + }, + "min_age": "123s", + }, + "hot": Object { + "actions": Object { + "rollover": Object { + "max_age": "30d", + "max_size": "50gb", + }, + "set_priority": Object { + "priority": 100, + }, + }, + "min_age": "0ms", + }, + }, } `); }); @@ -385,6 +462,33 @@ describe('', () => { }); describe('data allocation', () => { + beforeEach(async () => { + httpRequestsMockHelpers.setLoadPolicies([POLICY_WITH_MIGRATE_OFF]); + httpRequestsMockHelpers.setListNodes({ + nodesByRoles: {}, + nodesByAttributes: { test: ['123'] }, + isUsingDeprecatedDataRoleConfig: false, + }); + httpRequestsMockHelpers.setLoadSnapshotPolicies([]); + + await act(async () => { + testBed = await setup(); + }); + + const { component } = testBed; + component.update(); + }); + + test('setting node_attr based allocation, but not selecting node attribute', async () => { + const { actions } = testBed; + await actions.warm.setDataAllocation('node_attrs'); + await actions.savePolicy(); + const latestRequest = server.requests[server.requests.length - 1]; + const warmPhase = JSON.parse(JSON.parse(latestRequest.requestBody).body).phases.warm; + + expect(warmPhase.actions.migrate).toEqual({ enabled: false }); + }); + describe('node roles', () => { beforeEach(async () => { httpRequestsMockHelpers.setLoadPolicies([POLICY_WITH_NODE_ROLE_ALLOCATION]); @@ -401,15 +505,32 @@ describe('', () => { const { component } = testBed; component.update(); }); - test('showing "default" type', () => { + + test('detecting use of the recommended allocation type', () => { const { find } = testBed; - expect(find('warm-dataTierAllocationControls.dataTierSelect').text()).toContain( - 'recommended' - ); - expect(find('warm-dataTierAllocationControls.dataTierSelect').text()).not.toContain( - 'Custom' - ); - expect(find('warm-dataTierAllocationControls.dataTierSelect').text()).not.toContain('Off'); + const selectedDataAllocation = find( + 'warm-dataTierAllocationControls.dataTierSelect' + ).text(); + expect(selectedDataAllocation).toBe('Use warm nodes (recommended)'); + }); + + test('setting replicas serialization', async () => { + const { actions } = testBed; + await actions.warm.setReplicas('123'); + await actions.savePolicy(); + const latestRequest = server.requests[server.requests.length - 1]; + const warmPhaseActions = JSON.parse(JSON.parse(latestRequest.requestBody).body).phases.warm + .actions; + expect(warmPhaseActions).toMatchInlineSnapshot(` + Object { + "allocate": Object { + "number_of_replicas": 123, + }, + "set_priority": Object { + "priority": 50, + }, + } + `); }); }); describe('node attr and none', () => { @@ -429,9 +550,12 @@ describe('', () => { component.update(); }); - test('showing "custom" and "off" types', () => { + test('detecting use of the custom allocation type', () => { + const { find } = testBed; + expect(find('warm-dataTierAllocationControls.dataTierSelect').text()).toBe('Custom'); + }); + test('detecting use of the "off" allocation type', () => { const { find } = testBed; - expect(find('warm-dataTierAllocationControls.dataTierSelect').text()).toContain('Custom'); expect(find('cold-dataTierAllocationControls.dataTierSelect').text()).toContain('Off'); }); }); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts index c6d27ca890b54..e8ebc2963d16a 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts @@ -17,4 +17,5 @@ export type TestSubjects = | 'hot-selectedMaxDocuments' | 'hot-selectedMaxAge' | 'hot-selectedMaxAgeUnits' + | 'freezeSwitch' | string; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx index 4ba6cee7b027f..4a3fedfb264ac 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx @@ -119,9 +119,6 @@ const noRollover = async (rendered: ReactWrapper) => { }); rendered.update(); }; -const getNodeAttributeSelectLegacy = (rendered: ReactWrapper, phase: string) => { - return rendered.find(`select#${phase}-selectedNodeAttrs`); -}; const getNodeAttributeSelect = (rendered: ReactWrapper, phase: string) => { return findTestSubject(rendered, `${phase}-selectedNodeAttrs`); }; @@ -142,15 +139,6 @@ const setPhaseAfter = async (rendered: ReactWrapper, phase: string, after: strin }); rendered.update(); }; -const setPhaseIndexPriorityLegacy = ( - rendered: ReactWrapper, - phase: string, - priority: string | number -) => { - const priorityInput = rendered.find(`input#${phase}-phaseIndexPriority`); - priorityInput.simulate('change', { target: { value: priority } }); - rendered.update(); -}; const setPhaseIndexPriority = async ( rendered: ReactWrapper, phase: string, @@ -184,7 +172,7 @@ describe('edit policy', () => { */ const waitForFormLibValidation = (rendered: ReactWrapper) => { act(() => { - jest.advanceTimersByTime(1000); + jest.runAllTimers(); }); rendered.update(); }; @@ -394,7 +382,7 @@ describe('edit policy', () => { setPolicyName(rendered, 'mypolicy'); await setPhaseIndexPriority(rendered, 'hot', '-1'); waitForFormLibValidation(rendered); - expectedErrorMessages(rendered, [i18nTexts.editPolicy.errors.numberGreatThan0Required]); + expectedErrorMessages(rendered, [i18nTexts.editPolicy.errors.nonNegativeNumberRequired]); }); }); describe('warm phase', () => { @@ -519,7 +507,7 @@ describe('edit policy', () => { await activatePhase(rendered, 'warm'); expect(rendered.find('.euiLoadingSpinner').exists()).toBeTruthy(); expect(rendered.find('.euiCallOut--warning').exists()).toBeFalsy(); - expect(getNodeAttributeSelectLegacy(rendered, 'warm').exists()).toBeFalsy(); + expect(getNodeAttributeSelect(rendered, 'warm').exists()).toBeFalsy(); }); test('should show warning instead of node attributes input when none exist', async () => { http.setupNodeListResponse({ @@ -534,7 +522,7 @@ describe('edit policy', () => { expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); await openNodeAttributesSection(rendered, 'warm'); expect(findTestSubject(rendered, 'noNodeAttributesWarning').exists()).toBeTruthy(); - expect(getNodeAttributeSelectLegacy(rendered, 'warm').exists()).toBeFalsy(); + expect(getNodeAttributeSelect(rendered, 'warm').exists()).toBeFalsy(); }); test('should show node attributes input when attributes exist', async () => { const rendered = mountWithIntl(component); @@ -625,8 +613,9 @@ describe('edit policy', () => { await noRollover(rendered); setPolicyName(rendered, 'mypolicy'); await activatePhase(rendered, 'cold'); - setPhaseAfterLegacy(rendered, 'cold', '0'); - await save(rendered); + await setPhaseAfter(rendered, 'cold', '0'); + waitForFormLibValidation(rendered); + rendered.update(); expectedErrorMessages(rendered, []); }); test('should show positive number required error when trying to save cold phase with -1 for after', async () => { @@ -634,9 +623,9 @@ describe('edit policy', () => { await noRollover(rendered); setPolicyName(rendered, 'mypolicy'); await activatePhase(rendered, 'cold'); - setPhaseAfterLegacy(rendered, 'cold', '-1'); - await save(rendered); - expectedErrorMessages(rendered, [positiveNumberRequiredMessage]); + await setPhaseAfter(rendered, 'cold', '-1'); + waitForFormLibValidation(rendered); + expectedErrorMessages(rendered, [i18nTexts.editPolicy.errors.nonNegativeNumberRequired]); }); test('should show spinner for node attributes input when loading', async () => { server.respondImmediately = false; @@ -646,7 +635,7 @@ describe('edit policy', () => { await activatePhase(rendered, 'cold'); expect(rendered.find('.euiLoadingSpinner').exists()).toBeTruthy(); expect(rendered.find('.euiCallOut--warning').exists()).toBeFalsy(); - expect(getNodeAttributeSelectLegacy(rendered, 'cold').exists()).toBeFalsy(); + expect(getNodeAttributeSelect(rendered, 'cold').exists()).toBeFalsy(); }); test('should show warning instead of node attributes input when none exist', async () => { http.setupNodeListResponse({ @@ -661,7 +650,7 @@ describe('edit policy', () => { expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); await openNodeAttributesSection(rendered, 'cold'); expect(findTestSubject(rendered, 'noNodeAttributesWarning').exists()).toBeTruthy(); - expect(getNodeAttributeSelectLegacy(rendered, 'cold').exists()).toBeFalsy(); + expect(getNodeAttributeSelect(rendered, 'cold').exists()).toBeFalsy(); }); test('should show node attributes input when attributes exist', async () => { const rendered = mountWithIntl(component); @@ -671,7 +660,7 @@ describe('edit policy', () => { expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); await openNodeAttributesSection(rendered, 'cold'); expect(findTestSubject(rendered, 'noNodeAttributesWarning').exists()).toBeFalsy(); - const nodeAttributesSelect = getNodeAttributeSelectLegacy(rendered, 'cold'); + const nodeAttributesSelect = getNodeAttributeSelect(rendered, 'cold'); expect(nodeAttributesSelect.exists()).toBeTruthy(); expect(nodeAttributesSelect.find('option').length).toBe(2); }); @@ -683,7 +672,7 @@ describe('edit policy', () => { expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); await openNodeAttributesSection(rendered, 'cold'); expect(findTestSubject(rendered, 'noNodeAttributesWarning').exists()).toBeFalsy(); - const nodeAttributesSelect = getNodeAttributeSelectLegacy(rendered, 'cold'); + const nodeAttributesSelect = getNodeAttributeSelect(rendered, 'cold'); expect(nodeAttributesSelect.exists()).toBeTruthy(); expect(findTestSubject(rendered, 'cold-viewNodeDetailsFlyoutButton').exists()).toBeFalsy(); expect(nodeAttributesSelect.find('option').length).toBe(2); @@ -702,10 +691,10 @@ describe('edit policy', () => { await noRollover(rendered); setPolicyName(rendered, 'mypolicy'); await activatePhase(rendered, 'cold'); - setPhaseAfterLegacy(rendered, 'cold', '1'); - setPhaseIndexPriorityLegacy(rendered, 'cold', '-1'); - await save(rendered); - expectedErrorMessages(rendered, [positiveNumberRequiredMessage]); + await setPhaseAfter(rendered, 'cold', '1'); + await setPhaseIndexPriority(rendered, 'cold', '-1'); + waitForFormLibValidation(rendered); + expectedErrorMessages(rendered, [i18nTexts.editPolicy.errors.nonNegativeNumberRequired]); }); test('should show default allocation warning when no node roles are found', async () => { http.setupNodeListResponse({ diff --git a/x-pack/plugins/index_lifecycle_management/common/types/policies.ts b/x-pack/plugins/index_lifecycle_management/common/types/policies.ts index 813fcd9c253f1..5692decbbf7a8 100644 --- a/x-pack/plugins/index_lifecycle_management/common/types/policies.ts +++ b/x-pack/plugins/index_lifecycle_management/common/types/policies.ts @@ -116,7 +116,6 @@ export interface ForcemergeAction { export interface LegacyPolicy { name: string; phases: { - cold: ColdPhase; delete: DeletePhase; }; } @@ -159,14 +158,6 @@ export interface PhaseWithForcemergeAction { bestCompressionEnabled: boolean; } -export interface ColdPhase - extends CommonPhaseSettings, - PhaseWithMinAge, - PhaseWithAllocationAction, - PhaseWithIndexPriority { - freezeEnabled: boolean; -} - export interface DeletePhase extends CommonPhaseSettings, PhaseWithMinAge { waitForSnapshotPolicy: string; } diff --git a/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts b/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts index 136b68727672a..23d7387aa7076 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SerializedPhase, ColdPhase, DeletePhase, SerializedPolicy } from '../../../common/types'; +import { SerializedPhase, DeletePhase, SerializedPolicy } from '../../../common/types'; export const defaultSetPriority: string = '100'; @@ -24,17 +24,6 @@ export const defaultPolicy: SerializedPolicy = { }, }; -export const defaultNewColdPhase: ColdPhase = { - phaseEnabled: false, - selectedMinimumAge: '0', - selectedMinimumAgeUnits: 'd', - selectedNodeAttrs: '', - selectedReplicaCount: '', - freezeEnabled: false, - phaseIndexPriority: '0', - dataTierAllocationType: 'default', -}; - export const defaultNewDeletePhase: DeletePhase = { phaseEnabled: false, selectedMinimumAge: '0', diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/cloud_data_tier_callout.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/cloud_data_tier_callout.tsx deleted file mode 100644 index fc87b553ba521..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/cloud_data_tier_callout.tsx +++ /dev/null @@ -1,54 +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'; -import { FormattedMessage } from '@kbn/i18n/react'; -import React, { FunctionComponent } from 'react'; -import { EuiCallOut, EuiLink } from '@elastic/eui'; - -import { useKibana } from '../../../../../shared_imports'; - -const deployment = i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.cloudDataTierCallout.body.elasticDeploymentLink', - { - defaultMessage: 'deployment', - } -); - -const i18nTexts = { - title: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.cloudDataTierCallout.coldTierTitle', { - defaultMessage: 'Create a cold tier', - }), - body: (deploymentUrl?: string) => { - return ( - - {deployment} - - ) : ( - deployment - ), - }} - /> - ); - }, -}; - -export const CloudDataTierCallout: FunctionComponent = () => { - const { - services: { cloud }, - } = useKibana(); - - return ( - - {i18nTexts.body(cloud?.cloudDeploymentUrl)} - - ); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/data_tier_allocation.scss b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/data_tier_allocation.scss deleted file mode 100644 index 62ec3f303e1e8..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/data_tier_allocation.scss +++ /dev/null @@ -1,9 +0,0 @@ -.indexLifecycleManagement__phase__dataTierAllocation { - &__controlSection { - background-color: $euiColorLightestShade; - padding-top: $euiSizeM; - padding-left: $euiSizeM; - padding-right: $euiSizeM; - padding-bottom: $euiSizeM; - } -} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/data_tier_allocation.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/data_tier_allocation.tsx deleted file mode 100644 index f58f36fc45a0c..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/data_tier_allocation.tsx +++ /dev/null @@ -1,184 +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 React, { FunctionComponent, useEffect } from 'react'; -import { i18n } from '@kbn/i18n'; -import { EuiText, EuiFormRow, EuiSpacer, EuiSuperSelect, EuiSuperSelectOption } from '@elastic/eui'; - -import { DataTierAllocationType } from '../../../../../../common/types'; -import { NodeAllocation } from './node_allocation'; -import { SharedProps } from './types'; - -import './data_tier_allocation.scss'; - -type SelectOptions = EuiSuperSelectOption; - -const i18nTexts = { - allocationFieldLabel: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.allocationFieldLabel', - { defaultMessage: 'Data tier options' } - ), - allocationOptions: { - warm: { - default: { - input: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.warm.defaultOption.input', - { defaultMessage: 'Use warm nodes (recommended)' } - ), - helpText: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.warm.defaultOption.helpText', - { defaultMessage: 'Move data to nodes in the warm tier.' } - ), - }, - none: { - inputDisplay: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.warm.noneOption.input', - { defaultMessage: 'Off' } - ), - helpText: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.warm.noneOption.helpText', - { defaultMessage: 'Do not move data in the warm phase.' } - ), - }, - custom: { - inputDisplay: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.warm.customOption.input', - { defaultMessage: 'Custom' } - ), - helpText: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.warm.customOption.helpText', - { defaultMessage: 'Move data based on node attributes.' } - ), - }, - }, - cold: { - default: { - input: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.defaultOption.input', - { defaultMessage: 'Use cold nodes (recommended)' } - ), - helpText: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.defaultOption.helpText', - { defaultMessage: 'Move data to nodes in the cold tier.' } - ), - }, - none: { - inputDisplay: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.noneOption.input', - { defaultMessage: 'Off' } - ), - helpText: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.noneOption.helpText', - { defaultMessage: 'Do not move data in the cold phase.' } - ), - }, - custom: { - inputDisplay: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.customOption.input', - { defaultMessage: 'Custom' } - ), - helpText: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.customOption.helpText', - { defaultMessage: 'Move data based on node attributes.' } - ), - }, - }, - }, -}; - -export const DataTierAllocation: FunctionComponent = (props) => { - const { phaseData, setPhaseData, phase, hasNodeAttributes, disableDataTierOption } = props; - - useEffect(() => { - if (disableDataTierOption && phaseData.dataTierAllocationType === 'default') { - /** - * @TODO - * This is a slight hack because we only know we should disable the "default" option further - * down the component tree (i.e., after the policy has been deserialized). - * - * We reset the value to "custom" if we deserialized to "default". - * - * It would be better if we had all the information we needed before deserializing and - * were able to handle this at the deserialization step instead of patching further down - * the component tree - this should be a future refactor. - */ - setPhaseData('dataTierAllocationType', 'custom'); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - return ( -
- - setPhaseData('dataTierAllocationType', value)} - options={ - [ - disableDataTierOption - ? undefined - : { - 'data-test-subj': 'defaultDataAllocationOption', - value: 'default', - inputDisplay: i18nTexts.allocationOptions[phase].default.input, - dropdownDisplay: ( - <> - {i18nTexts.allocationOptions[phase].default.input} - -

- {i18nTexts.allocationOptions[phase].default.helpText} -

-
- - ), - }, - { - 'data-test-subj': 'customDataAllocationOption', - value: 'custom', - inputDisplay: i18nTexts.allocationOptions[phase].custom.inputDisplay, - dropdownDisplay: ( - <> - {i18nTexts.allocationOptions[phase].custom.inputDisplay} - -

- {i18nTexts.allocationOptions[phase].custom.helpText} -

-
- - ), - }, - { - 'data-test-subj': 'noneDataAllocationOption', - value: 'none', - inputDisplay: i18nTexts.allocationOptions[phase].none.inputDisplay, - dropdownDisplay: ( - <> - {i18nTexts.allocationOptions[phase].none.inputDisplay} - -

- {i18nTexts.allocationOptions[phase].none.helpText} -

-
- - ), - }, - ].filter(Boolean) as SelectOptions[] - } - /> -
- {phaseData.dataTierAllocationType === 'custom' && hasNodeAttributes && ( - <> - -
- -
- - )} -
- ); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_notice.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_notice.tsx deleted file mode 100644 index 3d0052c69607b..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_notice.tsx +++ /dev/null @@ -1,106 +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'; -import React, { FunctionComponent } from 'react'; -import { EuiCallOut } from '@elastic/eui'; - -import { PhaseWithAllocation, DataTierRole } from '../../../../../../common/types'; - -import { AllocationNodeRole } from '../../../../lib'; - -const i18nTextsNodeRoleToDataTier: Record = { - data_hot: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.dataTierHotLabel', { - defaultMessage: 'hot', - }), - data_warm: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.dataTierWarmLabel', { - defaultMessage: 'warm', - }), - data_cold: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.dataTierColdLabel', { - defaultMessage: 'cold', - }), -}; - -const i18nTexts = { - notice: { - warm: { - title: i18n.translate( - 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm.title', - { defaultMessage: 'No nodes assigned to the warm tier' } - ), - body: (nodeRole: DataTierRole) => - i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm', { - defaultMessage: - 'This policy will move data in the warm phase to {tier} tier nodes instead.', - values: { tier: i18nTextsNodeRoleToDataTier[nodeRole] }, - }), - }, - cold: { - title: i18n.translate( - 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold.title', - { defaultMessage: 'No nodes assigned to the cold tier' } - ), - body: (nodeRole: DataTierRole) => - i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold', { - defaultMessage: - 'This policy will move data in the cold phase to {tier} tier nodes instead.', - values: { tier: i18nTextsNodeRoleToDataTier[nodeRole] }, - }), - }, - }, - warning: { - warm: { - title: i18n.translate( - 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableTitle', - { defaultMessage: 'No nodes assigned to the warm tier' } - ), - body: i18n.translate( - 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableBody', - { - defaultMessage: - 'Assign at least one node to the warm or hot tier to use role-based allocation. The policy will fail to complete allocation if there are no available nodes.', - } - ), - }, - cold: { - title: i18n.translate( - 'xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableTitle', - { defaultMessage: 'No nodes assigned to the cold tier' } - ), - body: i18n.translate( - 'xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableBody', - { - defaultMessage: - 'Assign at least one node to the cold, warm, or hot tier to use role-based allocation. The policy will fail to complete allocation if there are no available nodes.', - } - ), - }, - }, -}; - -interface Props { - phase: PhaseWithAllocation; - targetNodeRole: AllocationNodeRole; -} - -export const DefaultAllocationNotice: FunctionComponent = ({ phase, targetNodeRole }) => { - const content = - targetNodeRole === 'none' ? ( - - {i18nTexts.warning[phase].body} - - ) : ( - - {i18nTexts.notice[phase].body(targetNodeRole)} - - ); - - return content; -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/index.ts deleted file mode 100644 index 937e3dd28da97..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/index.ts +++ /dev/null @@ -1,13 +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. - */ - -export { NodesDataProvider } from './node_data_provider'; -export { NodeAllocation } from './node_allocation'; -export { NodeAttrsDetails } from './node_attrs_details'; -export { DataTierAllocation } from './data_tier_allocation'; -export { DefaultAllocationNotice } from './default_allocation_notice'; -export { NoNodeAttributesWarning } from './no_node_attributes_warning'; -export { CloudDataTierCallout } from './cloud_data_tier_callout'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/no_node_attributes_warning.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/no_node_attributes_warning.tsx deleted file mode 100644 index 69185277f64ce..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/no_node_attributes_warning.tsx +++ /dev/null @@ -1,50 +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 React, { FunctionComponent } from 'react'; -import { EuiCallOut } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -import { PhaseWithAllocation } from '../../../../../../common/types'; - -const i18nTexts = { - title: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingLabel', { - defaultMessage: 'No custom node attributes configured', - }), - warm: { - body: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.warm.nodeAttributesMissingDescription', - { - defaultMessage: - 'Define custom node attributes in elasticsearch.yml to use attribute-based allocation. Warm nodes will be used instead.', - } - ), - }, - cold: { - body: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.cold.nodeAttributesMissingDescription', - { - defaultMessage: - 'Define custom node attributes in elasticsearch.yml to use attribute-based allocation. Cold nodes will be used instead.', - } - ), - }, -}; - -export const NoNodeAttributesWarning: FunctionComponent<{ phase: PhaseWithAllocation }> = ({ - phase, -}) => { - return ( - - {i18nTexts[phase].body} - - ); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/node_allocation.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/node_allocation.tsx deleted file mode 100644 index a57a6ba4ff2c6..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/node_allocation.tsx +++ /dev/null @@ -1,121 +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 React, { useState, FunctionComponent } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; -import { EuiSelect, EuiButtonEmpty, EuiText, EuiSpacer } from '@elastic/eui'; - -import { PhaseWithAllocationAction } from '../../../../../../common/types'; -import { propertyof } from '../../../../services/policies/policy_validation'; - -import { ErrableFormRow } from '../form_errors'; - -import { NodeAttrsDetails } from './node_attrs_details'; -import { SharedProps } from './types'; -import { LearnMoreLink } from '../learn_more_link'; - -const learnMoreLink = ( - - } - docPath="modules-cluster.html#cluster-shard-allocation-settings" - /> -); - -const i18nTexts = { - doNotModifyAllocationOption: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.doNotModifyAllocationOption', - { defaultMessage: 'Do not modify allocation configuration' } - ), -}; - -export const NodeAllocation: FunctionComponent = ({ - phase, - setPhaseData, - errors, - phaseData, - isShowingErrors, - nodes, -}) => { - const [selectedNodeAttrsForDetails, setSelectedNodeAttrsForDetails] = useState( - null - ); - - const nodeOptions = Object.keys(nodes).map((attrs) => ({ - text: `${attrs} (${nodes[attrs].length})`, - value: attrs, - })); - - nodeOptions.sort((a, b) => a.value.localeCompare(b.value)); - - // check that this string is a valid property - const nodeAttrsProperty = propertyof('selectedNodeAttrs'); - - return ( - <> - -

- -

-
- - - {/* - TODO: this field component must be revisited to support setting multiple require values and to support - setting `include and exclude values on ILM policies. See https://github.com/elastic/kibana/issues/77344 - */} - setSelectedNodeAttrsForDetails(phaseData.selectedNodeAttrs)} - > - - - ) : null - } - > - { - setPhaseData(nodeAttrsProperty, e.target.value); - }} - /> - - - {selectedNodeAttrsForDetails ? ( - setSelectedNodeAttrsForDetails(null)} - /> - ) : null} - - ); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/node_attrs_details.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/node_attrs_details.tsx deleted file mode 100644 index c29495d13eb8e..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/node_attrs_details.tsx +++ /dev/null @@ -1,106 +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 React from 'react'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; - -import { - EuiFlyoutBody, - EuiFlyout, - EuiTitle, - EuiInMemoryTable, - EuiSpacer, - EuiPortal, - EuiLoadingContent, - EuiCallOut, - EuiButton, -} from '@elastic/eui'; - -import { useLoadNodeDetails } from '../../../../services/api'; - -interface Props { - close: () => void; - selectedNodeAttrs: string; -} - -export const NodeAttrsDetails: React.FunctionComponent = ({ close, selectedNodeAttrs }) => { - const { data, isLoading, error, resendRequest } = useLoadNodeDetails(selectedNodeAttrs); - let content; - if (isLoading) { - content = ; - } else if (error) { - const { statusCode, message } = error; - content = ( - - } - color="danger" - > -

- {message} ({statusCode}) -

- - - -
- ); - } else { - content = ( - - ); - } - return ( - - - - -

- -

-
- - {content} -
-
-
- ); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/node_data_provider.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/node_data_provider.tsx deleted file mode 100644 index a7c0f3ec7c866..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/node_data_provider.tsx +++ /dev/null @@ -1,70 +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 React from 'react'; -import { EuiButton, EuiCallOut, EuiLoadingSpinner, EuiSpacer } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; - -import { ListNodesRouteResponse } from '../../../../../../common/types'; -import { useLoadNodes } from '../../../../services/api'; - -interface Props { - children: (data: ListNodesRouteResponse) => JSX.Element; -} - -export const NodesDataProvider = ({ children }: Props): JSX.Element => { - const { isLoading, data, error, resendRequest } = useLoadNodes(); - - if (isLoading) { - return ( - <> - - - - ); - } - - const renderError = () => { - if (error) { - const { statusCode, message } = error; - return ( - <> - - } - color="danger" - > -

- {message} ({statusCode}) -

- - - -
- - - - ); - } - return null; - }; - - return ( - <> - {renderError()} - {/* `data` will always be defined because we use an initial value when loading */} - {children(data!)} - - ); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/types.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/types.ts deleted file mode 100644 index d3dd536d97df0..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/types.ts +++ /dev/null @@ -1,28 +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 { - ListNodesRouteResponse, - PhaseWithAllocation, - PhaseWithAllocationAction, -} from '../../../../../../common/types'; -import { PhaseValidationErrors } from '../../../../services/policies/policy_validation'; - -export interface SharedProps { - phase: PhaseWithAllocation; - errors?: PhaseValidationErrors; - phaseData: PhaseWithAllocationAction; - setPhaseData: (dataKey: keyof PhaseWithAllocationAction, value: string) => void; - isShowingErrors: boolean; - nodes: ListNodesRouteResponse['nodesByAttributes']; - hasNodeAttributes: boolean; - /** - * When on Cloud we want to disable the data tier allocation option when we detect that we are not - * using node roles in our Node config yet. See {@link ListNodesRouteResponse} for information about how this is - * detected. - */ - disableDataTierOption: boolean; -} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/forcemerge_legacy.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/forcemerge_legacy.tsx deleted file mode 100644 index 0b0dbe273c024..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/forcemerge_legacy.tsx +++ /dev/null @@ -1,131 +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. - */ - -/** - * PLEASE NOTE: This component is currently duplicated. A version of this component wired up with - * the form lib lives in ./phases/shared - */ - -import { FormattedMessage } from '@kbn/i18n/react'; -import { - EuiDescribedFormGroup, - EuiFieldNumber, - EuiFormRow, - EuiSpacer, - EuiSwitch, - EuiTextColor, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import React from 'react'; -import { LearnMoreLink } from './learn_more_link'; -import { ErrableFormRow } from './form_errors'; -import { Phases, PhaseWithForcemergeAction } from '../../../../../common/types'; -import { PhaseValidationErrors } from '../../../services/policies/policy_validation'; - -const forcemergeLabel = i18n.translate('xpack.indexLifecycleMgmt.forcemerge.enableLabel', { - defaultMessage: 'Force merge data', -}); - -const bestCompressionLabel = i18n.translate( - 'xpack.indexLifecycleMgmt.forcemerge.bestCompressionLabel', - { - defaultMessage: 'Compress stored fields', - } -); - -interface Props { - errors?: PhaseValidationErrors; - phase: keyof Phases & string; - phaseData: PhaseWithForcemergeAction; - setPhaseData: (dataKey: keyof PhaseWithForcemergeAction, value: boolean | string) => void; - isShowingErrors: boolean; -} - -export const Forcemerge: React.FunctionComponent = ({ - errors, - phaseData, - phase, - setPhaseData, - isShowingErrors, -}) => { - return ( - - - - } - description={ - - {' '} - - - } - titleSize="xs" - fullWidth - > - { - setPhaseData('forceMergeEnabled', e.target.checked); - }} - aria-controls="forcemergeContent" - /> - - -
- {phaseData.forceMergeEnabled ? ( - <> - - { - setPhaseData('selectedForceMergeSegments', e.target.value); - }} - min={1} - /> - - - } - > - { - setPhaseData('bestCompressionEnabled', e.target.checked); - }} - /> - - - ) : null} -
-
- ); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/index.ts index 2b774b00b98a9..a04608338718e 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/index.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/index.ts @@ -11,16 +11,7 @@ export { MinAgeInput } from './min_age_input_legacy'; export { OptionalLabel } from './optional_label'; export { PhaseErrorMessage } from './phase_error_message'; export { PolicyJsonFlyout } from './policy_json_flyout'; -export { SetPriorityInput } from './set_priority_input_legacy'; export { SnapshotPolicies } from './snapshot_policies'; -export { - DataTierAllocation, - NodeAllocation, - NodeAttrsDetails, - NodesDataProvider, - DefaultAllocationNotice, -} from './data_tier_allocation'; export { DescribedFormField } from './described_form_field'; -export { Forcemerge } from './forcemerge_legacy'; export * from './phases'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase.tsx deleted file mode 100644 index da6c358aa67c1..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase.tsx +++ /dev/null @@ -1,233 +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 React, { FunctionComponent, Fragment } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; -import { get } from 'lodash'; - -import { EuiFieldNumber, EuiDescribedFormGroup, EuiSwitch, EuiTextColor } from '@elastic/eui'; - -import { ColdPhase as ColdPhaseInterface, Phases } from '../../../../../../common/types'; - -import { useFormData } from '../../../../../shared_imports'; - -import { PhaseValidationErrors } from '../../../../services/policies/policy_validation'; - -import { - LearnMoreLink, - ActiveBadge, - PhaseErrorMessage, - OptionalLabel, - ErrableFormRow, - SetPriorityInput, - MinAgeInput, - DescribedFormField, -} from '../'; - -import { DataTierAllocationFieldLegacy, useRolloverPath } from './shared'; - -const i18nTexts = { - freezeLabel: i18n.translate('xpack.indexLifecycleMgmt.coldPhase.freezeIndexLabel', { - defaultMessage: 'Freeze index', - }), - dataTierAllocation: { - description: i18n.translate('xpack.indexLifecycleMgmt.coldPhase.dataTier.description', { - defaultMessage: - 'Move data to nodes optimized for less frequent, read-only access. Store data in the cold phase on less-expensive hardware.', - }), - }, -}; - -const coldProperty: keyof Phases = 'cold'; -const phaseProperty = (propertyName: keyof ColdPhaseInterface) => propertyName; - -interface Props { - setPhaseData: (key: keyof ColdPhaseInterface & string, value: string | boolean) => void; - phaseData: ColdPhaseInterface; - isShowingErrors: boolean; - errors?: PhaseValidationErrors; -} -export const ColdPhase: FunctionComponent = ({ - setPhaseData, - phaseData, - errors, - isShowingErrors, -}) => { - const [formData] = useFormData({ - watch: [useRolloverPath], - }); - - const hotPhaseRolloverEnabled = get(formData, useRolloverPath); - - return ( -
- <> - {/* Section title group; containing min age */} - -

- -

{' '} - {phaseData.phaseEnabled && !isShowingErrors ? : null} - -
- } - titleSize="s" - description={ - -

- -

- - } - id={`${coldProperty}-${phaseProperty('phaseEnabled')}`} - checked={phaseData.phaseEnabled} - onChange={(e) => { - setPhaseData(phaseProperty('phaseEnabled'), e.target.checked); - }} - aria-controls="coldPhaseContent" - /> -
- } - fullWidth - > - {phaseData.phaseEnabled ? ( - - errors={errors} - phaseData={phaseData} - phase={coldProperty} - isShowingErrors={isShowingErrors} - setPhaseData={setPhaseData} - rolloverEnabled={hotPhaseRolloverEnabled} - /> - ) : null} - - {phaseData.phaseEnabled ? ( - - {/* Data tier allocation section */} - - - {/* Replicas section */} - - {i18n.translate('xpack.indexLifecycleMgmt.coldPhase.replicasTitle', { - defaultMessage: 'Replicas', - })} - - } - description={i18n.translate( - 'xpack.indexLifecycleMgmt.coldPhase.numberOfReplicasDescription', - { - defaultMessage: - 'Set the number of replicas. Remains the same as the previous phase by default.', - } - )} - switchProps={{ - label: i18n.translate( - 'xpack.indexLifecycleMgmt.editPolicy.coldPhase.numberOfReplicas.switchLabel', - { defaultMessage: 'Set replicas' } - ), - initialValue: Boolean(phaseData.selectedReplicaCount), - onChange: (v) => { - if (!v) { - setPhaseData('selectedReplicaCount', ''); - } - }, - }} - fullWidth - > - - - - - } - isShowingErrors={isShowingErrors} - errors={errors?.selectedReplicaCount} - > - { - setPhaseData(phaseProperty('selectedReplicaCount'), e.target.value); - }} - min={0} - /> - - - {/* Freeze section */} - - - - } - description={ - - {' '} - - - } - fullWidth - titleSize="xs" - > - { - setPhaseData(phaseProperty('freezeEnabled'), e.target.checked); - }} - label={i18nTexts.freezeLabel} - aria-label={i18nTexts.freezeLabel} - /> - - - errors={errors} - phaseData={phaseData} - phase={coldProperty} - isShowingErrors={isShowingErrors} - setPhaseData={setPhaseData} - /> - - ) : null} - - - ); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase/cold_phase.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase/cold_phase.tsx new file mode 100644 index 0000000000000..84e955a91ad7c --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase/cold_phase.tsx @@ -0,0 +1,187 @@ +/* + * 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, { FunctionComponent } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; +import { get } from 'lodash'; + +import { EuiDescribedFormGroup, EuiTextColor } from '@elastic/eui'; + +import { Phases } from '../../../../../../../common/types'; + +import { + useFormData, + useFormContext, + UseField, + ToggleField, + NumericField, +} from '../../../../../../shared_imports'; + +import { useEditPolicyContext } from '../../../edit_policy_context'; + +import { LearnMoreLink, ActiveBadge, PhaseErrorMessage, DescribedFormField } from '../../'; + +import { MinAgeInputField, DataTierAllocationField, SetPriorityInput } from '../shared'; + +const i18nTexts = { + dataTierAllocation: { + description: i18n.translate('xpack.indexLifecycleMgmt.coldPhase.dataTier.description', { + defaultMessage: + 'Move data to nodes optimized for less frequent, read-only access. Store data in the cold phase on less-expensive hardware.', + }), + }, +}; + +const coldProperty: keyof Phases = 'cold'; + +const formFieldPaths = { + enabled: '_meta.cold.enabled', +}; + +export const ColdPhase: FunctionComponent = () => { + const { originalPolicy } = useEditPolicyContext(); + const form = useFormContext(); + + const [formData] = useFormData({ + watch: [formFieldPaths.enabled], + }); + + const enabled = get(formData, formFieldPaths.enabled); + const isShowingErrors = form.isValid === false; + + return ( +
+ <> + {/* Section title group; containing min age */} + +

+ +

{' '} + {enabled && !isShowingErrors ? : null} + +
+ } + titleSize="s" + description={ + <> +

+ +

+ + + } + fullWidth + > + {enabled && } + + {enabled && ( + <> + {/* Data tier allocation section */} + + + {/* Replicas section */} + + {i18n.translate('xpack.indexLifecycleMgmt.coldPhase.replicasTitle', { + defaultMessage: 'Replicas', + })} + + } + description={i18n.translate( + 'xpack.indexLifecycleMgmt.coldPhase.numberOfReplicasDescription', + { + defaultMessage: + 'Set the number of replicas. Remains the same as the previous phase by default.', + } + )} + switchProps={{ + 'data-test-subj': 'cold-setReplicasSwitch', + label: i18n.translate( + 'xpack.indexLifecycleMgmt.editPolicy.coldPhase.numberOfReplicas.switchLabel', + { defaultMessage: 'Set replicas' } + ), + initialValue: Boolean( + originalPolicy.phases.cold?.actions?.allocate?.number_of_replicas + ), + }} + fullWidth + > + + + {/* Freeze section */} + + + + } + description={ + + {' '} + + + } + fullWidth + titleSize="xs" + > + + + + + )} + + + ); +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/shared/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase/index.ts similarity index 74% rename from x-pack/plugins/index_lifecycle_management/public/application/services/policies/shared/index.ts rename to x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase/index.ts index fe97b85778a53..df79607f33dbc 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/shared/index.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/cold_phase/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { serializePhaseWithAllocation } from './serialize_phase_with_allocation'; +export { ColdPhase } from './cold_phase'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared/data_tier_allocation_field/components/no_node_attributes_warning.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared/data_tier_allocation_field/components/no_node_attributes_warning.tsx index 338e5367a1d0d..56a59270b18af 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared/data_tier_allocation_field/components/no_node_attributes_warning.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared/data_tier_allocation_field/components/no_node_attributes_warning.tsx @@ -19,7 +19,7 @@ const i18nTexts = { 'xpack.indexLifecycleMgmt.editPolicy.warm.nodeAttributesMissingDescription', { defaultMessage: - 'Define custom node attributes in elasticsearch.yml to use attribute-based allocation. Warm nodes will be used instead.', + 'Define custom node attributes in elasticsearch.yml to use attribute-based allocation.', } ), }, @@ -28,7 +28,7 @@ const i18nTexts = { 'xpack.indexLifecycleMgmt.editPolicy.cold.nodeAttributesMissingDescription', { defaultMessage: - 'Define custom node attributes in elasticsearch.yml to use attribute-based allocation. Cold nodes will be used instead.', + 'Define custom node attributes in elasticsearch.yml to use attribute-based allocation.', } ), }, diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared/data_tier_allocation_legacy_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared/data_tier_allocation_legacy_field.tsx deleted file mode 100644 index d64df468620e6..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared/data_tier_allocation_legacy_field.tsx +++ /dev/null @@ -1,141 +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 React, { FunctionComponent } from 'react'; -import { i18n } from '@kbn/i18n'; -import { EuiDescribedFormGroup, EuiFormRow, EuiSpacer } from '@elastic/eui'; - -import { useKibana } from '../../../../../../shared_imports'; -import { PhaseWithAllocationAction, PhaseWithAllocation } from '../../../../../../../common/types'; -import { PhaseValidationErrors } from '../../../../../services/policies/policy_validation'; -import { getAvailableNodeRoleForPhase, isNodeRoleFirstPreference } from '../../../../../lib'; - -import { - DataTierAllocation, - DefaultAllocationNotice, - NoNodeAttributesWarning, - NodesDataProvider, - CloudDataTierCallout, -} from '../../data_tier_allocation'; - -const i18nTexts = { - title: i18n.translate('xpack.indexLifecycleMgmt.common.dataTier.title', { - defaultMessage: 'Data allocation', - }), -}; - -interface Props { - description: React.ReactNode; - phase: PhaseWithAllocation; - setPhaseData: (dataKey: keyof PhaseWithAllocationAction, value: string) => void; - isShowingErrors: boolean; - errors?: PhaseValidationErrors; - phaseData: PhaseWithAllocationAction; -} - -/** - * Top-level layout control for the data tier allocation field. - */ -export const DataTierAllocationFieldLegacy: FunctionComponent = ({ - description, - phase, - phaseData, - setPhaseData, - isShowingErrors, - errors, -}) => { - const { - services: { cloud }, - } = useKibana(); - - return ( - - {({ nodesByRoles, nodesByAttributes, isUsingDeprecatedDataRoleConfig }) => { - const hasDataNodeRoles = Object.keys(nodesByRoles).some((nodeRole) => - // match any of the "data_" roles, including data_content. - nodeRole.trim().startsWith('data_') - ); - const hasNodeAttrs = Boolean(Object.keys(nodesByAttributes ?? {}).length); - - const renderNotice = () => { - switch (phaseData.dataTierAllocationType) { - case 'default': - const isCloudEnabled = cloud?.isCloudEnabled ?? false; - if (isCloudEnabled && phase === 'cold') { - const isUsingNodeRolesAllocation = - !isUsingDeprecatedDataRoleConfig && hasDataNodeRoles; - const hasNoNodesWithNodeRole = !nodesByRoles.data_cold?.length; - - if (isUsingNodeRolesAllocation && hasNoNodesWithNodeRole) { - // Tell cloud users they can deploy nodes on cloud. - return ( - <> - - - - ); - } - } - - const allocationNodeRole = getAvailableNodeRoleForPhase(phase, nodesByRoles); - if ( - allocationNodeRole === 'none' || - !isNodeRoleFirstPreference(phase, allocationNodeRole) - ) { - return ( - <> - - - - ); - } - break; - case 'custom': - if (!hasNodeAttrs) { - return ( - <> - - - - ); - } - break; - default: - return null; - } - }; - - return ( - {i18nTexts.title}} - description={description} - fullWidth - > - - <> - - - {/* Data tier related warnings and call-to-action notices */} - {renderNotice()} - - - - ); - }} - - ); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared/index.ts index 0cae3eea6316b..6355dab89771d 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared/index.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared/index.ts @@ -6,8 +6,6 @@ export { useRolloverPath } from '../../../constants'; -export { DataTierAllocationFieldLegacy } from './data_tier_allocation_legacy_field'; - export { DataTierAllocationField } from './data_tier_allocation_field'; export { Forcemerge } from './forcemerge_field'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/warm_phase/warm_phase.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/warm_phase/warm_phase.tsx index 7b1a4f44b5de6..06c16e8bdd5ab 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/warm_phase/warm_phase.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/warm_phase/warm_phase.tsx @@ -48,16 +48,21 @@ const i18nTexts = { const warmProperty: keyof Phases = 'warm'; +const formFieldPaths = { + enabled: '_meta.warm.enabled', + warmPhaseOnRollover: '_meta.warm.warmPhaseOnRollover', +}; + export const WarmPhase: FunctionComponent = () => { const { originalPolicy } = useEditPolicyContext(); const form = useFormContext(); const [formData] = useFormData({ - watch: [useRolloverPath, '_meta.warm.enabled', '_meta.warm.warmPhaseOnRollover'], + watch: [useRolloverPath, formFieldPaths.enabled, formFieldPaths.warmPhaseOnRollover], }); - const enabled = get(formData, '_meta.warm.enabled'); + const enabled = get(formData, formFieldPaths.enabled); const hotPhaseRolloverEnabled = get(formData, useRolloverPath); - const warmPhaseOnRollover = get(formData, '_meta.warm.warmPhaseOnRollover'); + const warmPhaseOnRollover = get(formData, formFieldPaths.warmPhaseOnRollover); const isShowingErrors = form.isValid === false; return ( @@ -88,7 +93,7 @@ export const WarmPhase: FunctionComponent = () => { />

{ {hotPhaseRolloverEnabled && ( = ({ ...legacyPolicy.phases, hot: p.phases.hot, warm: p.phases.warm, + cold: p.phases.cold, }, }); } else { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/set_priority_input_legacy.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/set_priority_input_legacy.tsx deleted file mode 100644 index 5efbfabdf093d..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/set_priority_input_legacy.tsx +++ /dev/null @@ -1,85 +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. - */ - -/** - * PLEASE NOTE: This component is currently duplicated. A version of this component wired up with - * the form lib lives in ./phases/shared - */ - -import React, { Fragment } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiFieldNumber, EuiTextColor, EuiDescribedFormGroup } from '@elastic/eui'; - -import { LearnMoreLink } from './'; -import { OptionalLabel } from './'; -import { ErrableFormRow } from './'; -import { PhaseWithIndexPriority, Phases } from '../../../../../common/types'; -import { PhaseValidationErrors, propertyof } from '../../../services/policies/policy_validation'; - -interface Props { - errors?: PhaseValidationErrors; - phase: keyof Phases & string; - phaseData: T; - setPhaseData: (dataKey: keyof T & string, value: any) => void; - isShowingErrors: boolean; -} -export const SetPriorityInput = ({ - errors, - phaseData, - phase, - setPhaseData, - isShowingErrors, -}: React.PropsWithChildren>) => { - const phaseIndexPriorityProperty = propertyof('phaseIndexPriority'); - return ( - - - - } - description={ - - {' '} - - - } - titleSize="xs" - fullWidth - > - - - - - } - isShowingErrors={isShowingErrors} - errors={errors?.phaseIndexPriority} - > - { - setPhaseData(phaseIndexPriorityProperty, e.target.value); - }} - min={0} - /> - - - ); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/deserializer.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/deserializer.ts index 760c6ad713ea0..f0294a5391d21 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/deserializer.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/deserializer.ts @@ -15,18 +15,27 @@ import { determineDataTierAllocationType } from '../../lib'; import { FormInternal } from './types'; export const deserializer = (policy: SerializedPolicy): FormInternal => { + const { + phases: { hot, warm, cold }, + } = policy; + const _meta: FormInternal['_meta'] = { hot: { - useRollover: Boolean(policy.phases.hot?.actions?.rollover), - forceMergeEnabled: Boolean(policy.phases.hot?.actions?.forcemerge), - bestCompression: policy.phases.hot?.actions?.forcemerge?.index_codec === 'best_compression', + useRollover: Boolean(hot?.actions?.rollover), + forceMergeEnabled: Boolean(hot?.actions?.forcemerge), + bestCompression: hot?.actions?.forcemerge?.index_codec === 'best_compression', }, warm: { - enabled: Boolean(policy.phases.warm), - warmPhaseOnRollover: Boolean(policy.phases.warm?.min_age === '0ms'), - forceMergeEnabled: Boolean(policy.phases.warm?.actions?.forcemerge), - bestCompression: policy.phases.warm?.actions?.forcemerge?.index_codec === 'best_compression', - dataTierAllocationType: determineDataTierAllocationType(policy.phases.warm?.actions), + enabled: Boolean(warm), + warmPhaseOnRollover: Boolean(warm?.min_age === '0ms'), + forceMergeEnabled: Boolean(warm?.actions?.forcemerge), + bestCompression: warm?.actions?.forcemerge?.index_codec === 'best_compression', + dataTierAllocationType: determineDataTierAllocationType(warm?.actions), + }, + cold: { + enabled: Boolean(cold), + dataTierAllocationType: determineDataTierAllocationType(cold?.actions), + freezeEnabled: Boolean(cold?.actions?.freeze), }, }; @@ -63,6 +72,20 @@ export const deserializer = (policy: SerializedPolicy): FormInternal => { draft._meta.warm.minAgeUnit = minAge.units; } } + + if (draft.phases.cold) { + if (draft.phases.cold.actions?.allocate?.require) { + Object.entries(draft.phases.cold.actions.allocate.require).forEach((entry) => { + draft._meta.cold.allocationNodeAttribute = entry.join(':'); + }); + } + + if (draft.phases.cold.min_age) { + const minAge = splitSizeAndUnits(draft.phases.cold.min_age); + draft.phases.cold.min_age = minAge.size; + draft._meta.cold.minAgeUnit = minAge.units; + } + } } ); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx index eecdfb4871a67..5397f5da2d6bb 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx @@ -92,6 +92,7 @@ const mergeAllSerializedPolicies = ( ...legacySerializedPolicy.phases, hot: serializedPolicy.phases.hot, warm: serializedPolicy.phases.warm, + cold: serializedPolicy.phases.cold, }, }; }; @@ -195,10 +196,6 @@ export const EditPolicy: React.FunctionComponent = ({ [setPolicy] ); - const setColdPhaseData = useCallback( - (key: string, value: any) => setPhaseData('cold', key, value), - [setPhaseData] - ); const setDeletePhaseData = useCallback( (key: string, value: any) => setPhaseData('delete', key, value), [setPhaseData] @@ -342,14 +339,7 @@ export const EditPolicy: React.FunctionComponent = ({ - 0 - } - setPhaseData={setColdPhaseData} - phaseData={policy.phases.cold} - /> + diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_schema.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_schema.ts index a80382e87539c..070f03f74b954 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_schema.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_schema.ts @@ -11,7 +11,11 @@ import { defaultSetPriority, defaultPhaseIndexPriority } from '../../constants'; import { FormInternal } from './types'; -import { ifExistsNumberGreaterThanZero, rolloverThresholdsValidator } from './form_validations'; +import { + ifExistsNumberGreaterThanZero, + ifExistsNumberNonNegative, + rolloverThresholdsValidator, +} from './form_validations'; import { i18nTexts } from './i18n_texts'; @@ -69,6 +73,30 @@ export const schema: FormSchema = { label: i18nTexts.editPolicy.allocationNodeAttributeFieldLabel, }, }, + cold: { + enabled: { + defaultValue: false, + label: i18n.translate( + 'xpack.indexLifecycleMgmt.editPolicy.coldPhase.activateColdPhaseSwitchLabel', + { defaultMessage: 'Activate cold phase' } + ), + }, + freezeEnabled: { + defaultValue: false, + label: i18n.translate('xpack.indexLifecycleMgmt.coldPhase.freezeIndexLabel', { + defaultMessage: 'Freeze index', + }), + }, + minAgeUnit: { + defaultValue: 'd', + }, + dataTierAllocationType: { + label: i18nTexts.editPolicy.allocationTypeOptionsFieldLabel, + }, + allocationNodeAttribute: { + label: i18nTexts.editPolicy.allocationNodeAttributeFieldLabel, + }, + }, }, phases: { hot: { @@ -138,7 +166,7 @@ export const schema: FormSchema = { priority: { defaultValue: defaultSetPriority as any, label: i18nTexts.editPolicy.setPriorityFieldLabel, - validations: [{ validator: ifExistsNumberGreaterThanZero }], + validations: [{ validator: ifExistsNumberNonNegative }], serializer: serializers.stringToNumber, }, }, @@ -217,7 +245,48 @@ export const schema: FormSchema = { priority: { defaultValue: defaultPhaseIndexPriority as any, label: i18nTexts.editPolicy.setPriorityFieldLabel, - validations: [{ validator: ifExistsNumberGreaterThanZero }], + validations: [{ validator: ifExistsNumberNonNegative }], + serializer: serializers.stringToNumber, + }, + }, + }, + }, + cold: { + min_age: { + defaultValue: '0', + validations: [ + { + validator: (arg) => + numberGreaterThanField({ + than: 0, + allowEquality: true, + message: i18nTexts.editPolicy.errors.nonNegativeNumberRequired, + })({ + ...arg, + value: arg.value === '' ? -Infinity : parseInt(arg.value, 10), + }), + }, + ], + }, + actions: { + allocate: { + number_of_replicas: { + label: i18n.translate('xpack.indexLifecycleMgmt.coldPhase.numberOfReplicasLabel', { + defaultMessage: 'Number of replicas (optional)', + }), + validations: [ + { + validator: ifExistsNumberGreaterThanZero, + }, + ], + serializer: serializers.stringToNumber, + }, + }, + set_priority: { + priority: { + defaultValue: '0' as any, + label: i18nTexts.editPolicy.setPriorityFieldLabel, + validations: [{ validator: ifExistsNumberNonNegative }], serializer: serializers.stringToNumber, }, }, diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_validations.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_validations.ts index 37ca4e9def340..9c855ccb41624 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_validations.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form_validations.ts @@ -12,18 +12,36 @@ import { i18nTexts } from './i18n_texts'; const { numberGreaterThanField } = fieldValidators; -export const ifExistsNumberGreaterThanZero: ValidationFunc = (arg) => { - if (arg.value) { - return numberGreaterThanField({ - than: 0, - message: i18nTexts.editPolicy.errors.numberGreatThan0Required, - })({ - ...arg, - value: parseInt(arg.value, 10), - }); - } +const createIfNumberExistsValidator = ({ + than, + message, +}: { + than: number; + message: string; +}): ValidationFunc => { + return (arg) => { + if (arg.value) { + return numberGreaterThanField({ + than, + message, + })({ + ...arg, + value: parseInt(arg.value, 10), + }); + } + }; }; +export const ifExistsNumberGreaterThanZero = createIfNumberExistsValidator({ + than: 0, + message: i18nTexts.editPolicy.errors.numberGreatThan0Required, +}); + +export const ifExistsNumberNonNegative = createIfNumberExistsValidator({ + than: -1, + message: i18nTexts.editPolicy.errors.nonNegativeNumberRequired, +}); + /** * A special validation type used to keep track of validation errors for * the rollover threshold values not being set (e.g., age and doc count) diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/serializer.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/serializer.ts index 90e81528f5afe..564b5a2c4e397 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/serializer.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/serializer.ts @@ -31,6 +31,11 @@ const serializeAllocateAction = ( [name]: value, }, }; + } else { + // The form has been configured to use node attribute based allocation but no node attribute + // was selected. We fall back to what was originally selected in this case. This might be + // migrate.enabled: "false" + actions.migrate = originalActions.migrate; } // copy over the original include and exclude values until we can set them in the form. @@ -129,5 +134,36 @@ export const createSerializer = (originalPolicy?: SerializedPolicy) => ( } } + /** + * COLD PHASE SERIALIZATION + */ + if (policy.phases.cold) { + if (policy.phases.cold.min_age) { + policy.phases.cold.min_age = `${policy.phases.cold.min_age}${_meta.cold.minAgeUnit}`; + } + + policy.phases.cold.actions = serializeAllocateAction( + _meta.cold, + policy.phases.cold.actions, + originalPolicy?.phases.cold?.actions + ); + + if ( + policy.phases.cold.actions.allocate && + !policy.phases.cold.actions.allocate.require && + !isNumber(policy.phases.cold.actions.allocate.number_of_replicas) && + isEmpty(policy.phases.cold.actions.allocate.include) && + isEmpty(policy.phases.cold.actions.allocate.exclude) + ) { + // remove allocate action if it does not define require or number of nodes + // and both include and exclude are empty objects (ES will fail to parse if we don't) + delete policy.phases.cold.actions.allocate; + } + + if (_meta.cold.freezeEnabled) { + policy.phases.cold.actions.freeze = {}; + } + } + return policy; }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/types.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/types.ts index 6fcfbd050c69d..1884f8dbc0619 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/types.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/types.ts @@ -13,20 +13,29 @@ export interface DataAllocationMetaFields { allocationNodeAttribute?: string; } -interface HotPhaseMetaFields { - useRollover: boolean; +export interface MinAgeField { + minAgeUnit?: string; +} + +export interface ForcemergeFields { forceMergeEnabled: boolean; bestCompression: boolean; +} + +interface HotPhaseMetaFields extends ForcemergeFields { + useRollover: boolean; maxStorageSizeUnit?: string; maxAgeUnit?: string; } -interface WarmPhaseMetaFields extends DataAllocationMetaFields { +interface WarmPhaseMetaFields extends DataAllocationMetaFields, MinAgeField, ForcemergeFields { enabled: boolean; - forceMergeEnabled: boolean; - bestCompression: boolean; warmPhaseOnRollover: boolean; - minAgeUnit?: string; +} + +interface ColdPhaseMetaFields extends DataAllocationMetaFields, MinAgeField { + enabled: boolean; + freezeEnabled: boolean; } /** @@ -40,5 +49,6 @@ export interface FormInternal extends SerializedPolicy { _meta: { hot: HotPhaseMetaFields; warm: WarmPhaseMetaFields; + cold: ColdPhaseMetaFields; }; } diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/cold_phase.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/cold_phase.ts deleted file mode 100644 index faf3954f93fd8..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/cold_phase.ts +++ /dev/null @@ -1,154 +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 { isEmpty } from 'lodash'; -import { AllocateAction, ColdPhase, SerializedColdPhase } from '../../../../common/types'; -import { serializedPhaseInitialization } from '../../constants'; -import { isNumber, splitSizeAndUnits } from './policy_serialization'; -import { - numberRequiredMessage, - PhaseValidationErrors, - positiveNumberRequiredMessage, -} from './policy_validation'; -import { determineDataTierAllocationTypeLegacy } from '../../lib'; -import { serializePhaseWithAllocation } from './shared'; - -export const coldPhaseInitialization: ColdPhase = { - phaseEnabled: false, - selectedMinimumAge: '0', - selectedMinimumAgeUnits: 'd', - selectedNodeAttrs: '', - selectedReplicaCount: '', - freezeEnabled: false, - phaseIndexPriority: '', - dataTierAllocationType: 'default', -}; - -export const coldPhaseFromES = (phaseSerialized?: SerializedColdPhase): ColdPhase => { - const phase = { ...coldPhaseInitialization }; - if (phaseSerialized === undefined || phaseSerialized === null) { - return phase; - } - - phase.phaseEnabled = true; - - if (phaseSerialized.actions) { - phase.dataTierAllocationType = determineDataTierAllocationTypeLegacy(phaseSerialized.actions); - } - - if (phaseSerialized.min_age) { - const { size: minAge, units: minAgeUnits } = splitSizeAndUnits(phaseSerialized.min_age); - phase.selectedMinimumAge = minAge; - phase.selectedMinimumAgeUnits = minAgeUnits; - } - - if (phaseSerialized.actions) { - const actions = phaseSerialized.actions; - if (actions.allocate) { - const allocate = actions.allocate; - if (allocate.require) { - Object.entries(allocate.require).forEach((entry) => { - phase.selectedNodeAttrs = entry.join(':'); - }); - if (allocate.number_of_replicas) { - phase.selectedReplicaCount = allocate.number_of_replicas.toString(); - } - } - } - - if (actions.freeze) { - phase.freezeEnabled = true; - } - - if (actions.set_priority) { - phase.phaseIndexPriority = actions.set_priority.priority - ? actions.set_priority.priority.toString() - : ''; - } - } - - return phase; -}; - -export const coldPhaseToES = ( - phase: ColdPhase, - originalPhase: SerializedColdPhase | undefined -): SerializedColdPhase => { - if (!originalPhase) { - originalPhase = { ...serializedPhaseInitialization }; - } - - const esPhase = { ...originalPhase }; - - if (isNumber(phase.selectedMinimumAge)) { - esPhase.min_age = `${phase.selectedMinimumAge}${phase.selectedMinimumAgeUnits}`; - } - - esPhase.actions = serializePhaseWithAllocation(phase, esPhase.actions); - - if (isNumber(phase.selectedReplicaCount)) { - esPhase.actions.allocate = esPhase.actions.allocate || ({} as AllocateAction); - esPhase.actions.allocate.number_of_replicas = parseInt(phase.selectedReplicaCount, 10); - } else { - if (esPhase.actions.allocate) { - delete esPhase.actions.allocate.number_of_replicas; - } - } - - if ( - esPhase.actions.allocate && - !esPhase.actions.allocate.require && - !isNumber(esPhase.actions.allocate.number_of_replicas) && - isEmpty(esPhase.actions.allocate.include) && - isEmpty(esPhase.actions.allocate.exclude) - ) { - // remove allocate action if it does not define require or number of nodes - // and both include and exclude are empty objects (ES will fail to parse if we don't) - delete esPhase.actions.allocate; - } - - if (phase.freezeEnabled) { - esPhase.actions.freeze = {}; - } else { - delete esPhase.actions.freeze; - } - - if (isNumber(phase.phaseIndexPriority)) { - esPhase.actions.set_priority = { - priority: parseInt(phase.phaseIndexPriority, 10), - }; - } else { - delete esPhase.actions.set_priority; - } - - return esPhase; -}; - -export const validateColdPhase = (phase: ColdPhase): PhaseValidationErrors => { - if (!phase.phaseEnabled) { - return {}; - } - - const phaseErrors = {} as PhaseValidationErrors; - - // index priority is optional, but if it's set, it needs to be a positive number - if (phase.phaseIndexPriority) { - if (!isNumber(phase.phaseIndexPriority)) { - phaseErrors.phaseIndexPriority = [numberRequiredMessage]; - } else if (parseInt(phase.phaseIndexPriority, 10) < 0) { - phaseErrors.phaseIndexPriority = [positiveNumberRequiredMessage]; - } - } - - // min age needs to be a positive number - if (!isNumber(phase.selectedMinimumAge)) { - phaseErrors.selectedMinimumAge = [numberRequiredMessage]; - } else if (parseInt(phase.selectedMinimumAge, 10) < 0) { - phaseErrors.selectedMinimumAge = [positiveNumberRequiredMessage]; - } - - return { ...phaseErrors }; -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_serialization.test.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_serialization.test.ts index 0be6ab3521736..19481b39a2c80 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_serialization.test.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_serialization.test.ts @@ -7,9 +7,7 @@ // eslint-disable-next-line no-restricted-imports import cloneDeep from 'lodash/cloneDeep'; import { deserializePolicy, legacySerializePolicy } from './policy_serialization'; -import { defaultNewColdPhase, defaultNewDeletePhase } from '../../constants'; -import { DataTierAllocationType } from '../../../../common/types'; -import { coldPhaseInitialization } from './cold_phase'; +import { defaultNewDeletePhase } from '../../constants'; describe('Policy serialization', () => { test('serialize a policy using "default" data allocation', () => { @@ -18,12 +16,6 @@ describe('Policy serialization', () => { { name: 'test', phases: { - cold: { - ...defaultNewColdPhase, - dataTierAllocationType: 'default', - selectedNodeAttrs: 'another:thing', - phaseEnabled: true, - }, delete: { ...defaultNewDeletePhase }, }, }, @@ -31,24 +23,12 @@ describe('Policy serialization', () => { name: 'test', phases: { hot: { actions: {} }, - cold: { - actions: { allocate: { include: {}, exclude: {}, require: { something: 'here' } } }, - }, }, } ) ).toEqual({ name: 'test', - phases: { - cold: { - actions: { - set_priority: { - priority: 0, - }, - }, - min_age: '0d', - }, - }, + phases: {}, }); }); @@ -58,12 +38,6 @@ describe('Policy serialization', () => { { name: 'test', phases: { - cold: { - ...defaultNewColdPhase, - dataTierAllocationType: 'custom', - selectedNodeAttrs: 'another:thing', - phaseEnabled: true, - }, delete: { ...defaultNewDeletePhase }, }, }, @@ -71,37 +45,12 @@ describe('Policy serialization', () => { name: 'test', phases: { hot: { actions: {} }, - cold: { - actions: { - allocate: { - include: { keep: 'this' }, - exclude: { keep: 'this' }, - require: { something: 'here' }, - }, - }, - }, }, } ) ).toEqual({ name: 'test', - phases: { - cold: { - actions: { - allocate: { - include: { keep: 'this' }, - exclude: { keep: 'this' }, - require: { - another: 'thing', - }, - }, - set_priority: { - priority: 0, - }, - }, - min_age: '0d', - }, - }, + phases: {}, }); }); @@ -111,12 +60,6 @@ describe('Policy serialization', () => { { name: 'test', phases: { - cold: { - ...defaultNewColdPhase, - dataTierAllocationType: 'custom', - selectedNodeAttrs: '', - phaseEnabled: true, - }, delete: { ...defaultNewDeletePhase }, }, }, @@ -124,26 +67,13 @@ describe('Policy serialization', () => { name: 'test', phases: { hot: { actions: {} }, - cold: { - actions: { allocate: { include: {}, exclude: {}, require: { something: 'here' } } }, - }, }, } ) ).toEqual({ // There should be no allocation action in any phases... name: 'test', - phases: { - cold: { - actions: { - allocate: { include: {}, exclude: {}, require: { something: 'here' } }, - set_priority: { - priority: 0, - }, - }, - min_age: '0d', - }, - }, + phases: {}, }); }); @@ -153,12 +83,6 @@ describe('Policy serialization', () => { { name: 'test', phases: { - cold: { - ...defaultNewColdPhase, - dataTierAllocationType: 'none', - selectedNodeAttrs: 'ignore:this', - phaseEnabled: true, - }, delete: { ...defaultNewDeletePhase }, }, }, @@ -166,39 +90,20 @@ describe('Policy serialization', () => { name: 'test', phases: { hot: { actions: {} }, - cold: { - actions: { allocate: { include: {}, exclude: {}, require: { something: 'here' } } }, - }, }, } ) ).toEqual({ // There should be no allocation action in any phases... name: 'test', - phases: { - cold: { - actions: { - migrate: { - enabled: false, - }, - set_priority: { - priority: 0, - }, - }, - min_age: '0d', - }, - }, + phases: {}, }); }); test('serialization does not alter the original policy', () => { const originalPolicy = { name: 'test', - phases: { - cold: { - actions: { allocate: { include: {}, exclude: {}, require: { something: 'here' } } }, - }, - }, + phases: {}, }; const originalClone = cloneDeep(originalPolicy); @@ -206,13 +111,6 @@ describe('Policy serialization', () => { const deserializedPolicy = { name: 'test', phases: { - cold: { - ...defaultNewColdPhase, - dataTierAllocationType: 'none' as DataTierAllocationType, - selectedNodeAttrs: 'ignore:this', - phaseEnabled: true, - }, - delete: { ...defaultNewDeletePhase }, }, }; @@ -227,9 +125,6 @@ describe('Policy serialization', () => { { name: 'test', phases: { - cold: { - ...defaultNewColdPhase, - }, delete: { ...defaultNewDeletePhase }, }, }, @@ -276,9 +171,6 @@ describe('Policy serialization', () => { ).toEqual({ name: 'test', phases: { - cold: { - ...coldPhaseInitialization, - }, delete: { ...defaultNewDeletePhase }, }, }); @@ -290,9 +182,6 @@ describe('Policy serialization', () => { { name: 'test', phases: { - cold: { - ...defaultNewColdPhase, - }, delete: { ...defaultNewDeletePhase }, }, }, diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_serialization.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_serialization.ts index 32c7e698b0920..55e9d88dcd383 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_serialization.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_serialization.ts @@ -6,13 +6,8 @@ import { LegacyPolicy, PolicyFromES, SerializedPolicy } from '../../../../common/types'; -import { - defaultNewColdPhase, - defaultNewDeletePhase, - serializedPhaseInitialization, -} from '../../constants'; +import { defaultNewDeletePhase, serializedPhaseInitialization } from '../../constants'; -import { coldPhaseFromES, coldPhaseToES } from './cold_phase'; import { deletePhaseFromES, deletePhaseToES } from './delete_phase'; export const splitSizeAndUnits = (field: string): { size: string; units: string } => { @@ -46,7 +41,6 @@ export const initializeNewPolicy = (newPolicyName: string = ''): LegacyPolicy => return { name: newPolicyName, phases: { - cold: { ...defaultNewColdPhase }, delete: { ...defaultNewDeletePhase }, }, }; @@ -61,7 +55,6 @@ export const deserializePolicy = (policy: PolicyFromES): LegacyPolicy => { return { name, phases: { - cold: coldPhaseFromES(phases.cold), delete: deletePhaseFromES(phases.delete), }, }; @@ -79,10 +72,6 @@ export const legacySerializePolicy = ( phases: {}, } as SerializedPolicy; - if (policy.phases.cold.phaseEnabled) { - serializedPolicy.phases.cold = coldPhaseToES(policy.phases.cold, originalEsPolicy.phases.cold); - } - if (policy.phases.delete.phaseEnabled) { serializedPolicy.phases.delete = deletePhaseToES( policy.phases.delete, diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_validation.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_validation.ts index a113cb68a2349..79c909c433f33 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_validation.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_validation.ts @@ -5,8 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { ColdPhase, DeletePhase, LegacyPolicy, PolicyFromES } from '../../../../common/types'; -import { validateColdPhase } from './cold_phase'; +import { DeletePhase, LegacyPolicy, PolicyFromES } from '../../../../common/types'; import { validateDeletePhase } from './delete_phase'; export const propertyof = (propertyName: keyof T & string) => propertyName; @@ -82,7 +81,6 @@ export type PhaseValidationErrors = { }; export interface ValidationErrors { - cold: PhaseValidationErrors; delete: PhaseValidationErrors; policyName: string[]; } @@ -120,17 +118,12 @@ export const validatePolicy = ( } } - const coldPhaseErrors = validateColdPhase(policy.phases.cold); const deletePhaseErrors = validateDeletePhase(policy.phases.delete); - const isValid = - policyNameErrors.length === 0 && - Object.keys(coldPhaseErrors).length === 0 && - Object.keys(deletePhaseErrors).length === 0; + const isValid = policyNameErrors.length === 0 && Object.keys(deletePhaseErrors).length === 0; return [ isValid, { policyName: [...policyNameErrors], - cold: coldPhaseErrors, delete: deletePhaseErrors, }, ]; @@ -145,9 +138,6 @@ export const findFirstError = (errors?: ValidationErrors): string | undefined => return propertyof('policyName'); } - if (Object.keys(errors.cold).length > 0) { - return `${propertyof('cold')}.${Object.keys(errors.cold)[0]}`; - } if (Object.keys(errors.delete).length > 0) { return `${propertyof('delete')}.${Object.keys(errors.delete)[0]}`; } diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/shared/serialize_phase_with_allocation.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/shared/serialize_phase_with_allocation.ts deleted file mode 100644 index c29ae3ab22831..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/shared/serialize_phase_with_allocation.ts +++ /dev/null @@ -1,42 +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. - */ - -// Prefer importing entire lodash library, e.g. import { get } from "lodash" -// eslint-disable-next-line no-restricted-imports -import cloneDeep from 'lodash/cloneDeep'; - -import { - AllocateAction, - PhaseWithAllocationAction, - SerializedPhase, -} from '../../../../../common/types'; - -export const serializePhaseWithAllocation = ( - phase: PhaseWithAllocationAction, - originalPhaseActions: SerializedPhase['actions'] = {} -): SerializedPhase['actions'] => { - const esPhaseActions: SerializedPhase['actions'] = cloneDeep(originalPhaseActions); - - if (phase.dataTierAllocationType === 'custom' && phase.selectedNodeAttrs) { - const [name, value] = phase.selectedNodeAttrs.split(':'); - esPhaseActions.allocate = esPhaseActions.allocate || ({} as AllocateAction); - esPhaseActions.allocate.require = { - [name]: value, - }; - } else if (phase.dataTierAllocationType === 'none') { - esPhaseActions.migrate = { enabled: false }; - if (esPhaseActions.allocate) { - delete esPhaseActions.allocate; - } - } else if (phase.dataTierAllocationType === 'default') { - if (esPhaseActions.allocate) { - delete esPhaseActions.allocate.require; - } - delete esPhaseActions.migrate; - } - - return esPhaseActions; -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.test.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.test.ts index c77e3d22f0e37..2f1c7798e7a4d 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.test.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.test.ts @@ -9,7 +9,6 @@ import { UIM_CONFIG_WARM_PHASE, UIM_CONFIG_SET_PRIORITY, UIM_CONFIG_FREEZE_INDEX, - defaultNewColdPhase, defaultPhaseIndexPriority, } from '../constants/'; @@ -23,7 +22,7 @@ describe('getUiMetricsForPhases', () => { min_age: '0ms', actions: { set_priority: { - priority: parseInt(defaultNewColdPhase.phaseIndexPriority, 10), + priority: parseInt(defaultPhaseIndexPriority, 10), }, }, }, @@ -69,7 +68,7 @@ describe('getUiMetricsForPhases', () => { actions: { freeze: {}, set_priority: { - priority: parseInt(defaultNewColdPhase.phaseIndexPriority, 10), + priority: parseInt(defaultPhaseIndexPriority, 10), }, }, }, diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.ts index 305b35b23e4d8..274d3d1ca97f3 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/ui_metric.ts @@ -13,7 +13,6 @@ import { UIM_CONFIG_FREEZE_INDEX, UIM_CONFIG_SET_PRIORITY, UIM_CONFIG_WARM_PHASE, - defaultNewColdPhase, defaultSetPriority, defaultPhaseIndexPriority, } from '../constants'; @@ -55,8 +54,7 @@ export function getUiMetricsForPhases(phases: Phases): string[] { const isColdPhasePriorityChanged = phases.cold && phases.cold.actions.set_priority && - phases.cold.actions.set_priority.priority !== - parseInt(defaultNewColdPhase.phaseIndexPriority, 10); + phases.cold.actions.set_priority.priority !== parseInt(defaultPhaseIndexPriority, 10); // If the priority is different than the default, we'll consider it a user interaction, // even if the user has set it to undefined. return ( diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index d953a47620000..58ee36507cb73 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -9079,7 +9079,6 @@ "xpack.indexLifecycleMgmt.editPolicy.coldPhase.freezeIndexExplanationText": "インデックスを読み取り専用にし、メモリー消費量を最小化します。", "xpack.indexLifecycleMgmt.editPolicy.coldPhase.freezeText": "凍結", "xpack.indexLifecycleMgmt.editPolicy.coldPhase.numberOfReplicas.switchLabel": "レプリカを設定", - "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.allocationFieldLabel": "データティアオプション", "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.customOption.helpText": "ノード属性に基づいてデータを移動します。", "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.customOption.input": "カスタム", "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.defaultOption.helpText": "コールドティアのノードにデータを移動します。", @@ -9143,7 +9142,6 @@ "xpack.indexLifecycleMgmt.editPolicy.nameLabel": "名前", "xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.customOption.description": "ノード属性を使用して、シャード割り当てを制御します。{learnMoreLink}。", "xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.doNotModifyAllocationOption": "割り当て構成を修正しない", - "xpack.indexLifecycleMgmt.editPolicy.nodeAllocationLabel": "ノード属性を選択", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesLoadingFailedTitle": "ノード属性を読み込めません", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingLabel": "カスタムノード属性が構成されていません", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesReloadButton": "再試行", @@ -9261,7 +9259,6 @@ "xpack.indexLifecycleMgmt.indexMgmtFilter.managedLabel": "管理中", "xpack.indexLifecycleMgmt.indexMgmtFilter.unmanagedLabel": "管理対象外", "xpack.indexLifecycleMgmt.indexMgmtFilter.warmLabel": "ウォーム", - "xpack.indexLifecycleMgmt.indexPriorityLabel": "インデックスの優先順位", "xpack.indexLifecycleMgmt.learnMore": "その他のリソース", "xpack.indexLifecycleMgmt.licenseCheckErrorMessage": "ライセンス確認失敗", "xpack.indexLifecycleMgmt.nodeAttrDetails.hostField": "ホスト", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 98e79e784e880..832b716934bca 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -9088,7 +9088,6 @@ "xpack.indexLifecycleMgmt.editPolicy.coldPhase.freezeIndexExplanationText": "使索引只读,并最大限度减小其内存占用。", "xpack.indexLifecycleMgmt.editPolicy.coldPhase.freezeText": "冻结", "xpack.indexLifecycleMgmt.editPolicy.coldPhase.numberOfReplicas.switchLabel": "设置副本", - "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.allocationFieldLabel": "数据层选项", "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.customOption.helpText": "根据节点属性移动数据。", "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.customOption.input": "定制", "xpack.indexLifecycleMgmt.editPolicy.common.dataTierAllocation.cold.defaultOption.helpText": "将数据移到冷层中的节点。", @@ -9152,7 +9151,6 @@ "xpack.indexLifecycleMgmt.editPolicy.nameLabel": "名称", "xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.customOption.description": "使用节点属性控制分片分配。{learnMoreLink}。", "xpack.indexLifecycleMgmt.editPolicy.nodeAllocation.doNotModifyAllocationOption": "不要修改分配配置", - "xpack.indexLifecycleMgmt.editPolicy.nodeAllocationLabel": "选择节点属性", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesLoadingFailedTitle": "无法加载节点属性", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesMissingLabel": "未配置定制节点属性", "xpack.indexLifecycleMgmt.editPolicy.nodeAttributesReloadButton": "重试", @@ -9270,7 +9268,6 @@ "xpack.indexLifecycleMgmt.indexMgmtFilter.managedLabel": "受管", "xpack.indexLifecycleMgmt.indexMgmtFilter.unmanagedLabel": "未受管", "xpack.indexLifecycleMgmt.indexMgmtFilter.warmLabel": "温", - "xpack.indexLifecycleMgmt.indexPriorityLabel": "索引优先级", "xpack.indexLifecycleMgmt.learnMore": "了解详情", "xpack.indexLifecycleMgmt.licenseCheckErrorMessage": "许可证检查失败", "xpack.indexLifecycleMgmt.nodeAttrDetails.hostField": "主机", From eb30e9513dc481008e7f2a384b4c0349c79dfabc Mon Sep 17 00:00:00 2001 From: Constance Date: Wed, 28 Oct 2020 09:23:35 -0700 Subject: [PATCH 04/80] [Enterprise Search] Add missing Enterprise Search Overview telemetry collectors/schema (#81858) * Add Enterprise Search cannot connect telemetry event * Add missing server-side telemetry collectors & schema --- .../error_connecting/error_connecting.tsx | 2 ++ .../enterprise_search/telemetry.test.ts | 10 ++++++++++ .../collectors/enterprise_search/telemetry.ts | 16 ++++++++++++++++ .../schema/xpack_plugins.json | 10 ++++++++++ 4 files changed, 38 insertions(+) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/error_connecting/error_connecting.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/error_connecting/error_connecting.tsx index 567c77792583d..7af3a1d1272e3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/error_connecting/error_connecting.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/error_connecting/error_connecting.tsx @@ -7,10 +7,12 @@ import React from 'react'; import { EuiPage, EuiPageContent } from '@elastic/eui'; +import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; import { ErrorStatePrompt } from '../../../shared/error_state'; export const ErrorConnecting: React.FC = () => ( + diff --git a/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.test.ts b/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.test.ts index c3e2aff6551c9..440f540ccc857 100644 --- a/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.test.ts +++ b/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.test.ts @@ -20,6 +20,8 @@ describe('Enterprise Search Telemetry Usage Collector', () => { get: () => ({ attributes: { 'ui_viewed.overview': 10, + 'ui_viewed.setup_guide': 5, + 'ui_error.cannot_connect': 1, 'ui_clicked.app_search': 2, 'ui_clicked.workplace_search': 3, }, @@ -53,6 +55,10 @@ describe('Enterprise Search Telemetry Usage Collector', () => { expect(savedObjectsCounts).toEqual({ ui_viewed: { overview: 10, + setup_guide: 5, + }, + ui_error: { + cannot_connect: 1, }, ui_clicked: { app_search: 2, @@ -74,6 +80,10 @@ describe('Enterprise Search Telemetry Usage Collector', () => { expect(savedObjectsCounts).toEqual({ ui_viewed: { overview: 0, + setup_guide: 0, + }, + ui_error: { + cannot_connect: 0, }, ui_clicked: { app_search: 0, diff --git a/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.ts b/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.ts index a124a185b9a34..d6bd8bd9305f5 100644 --- a/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.ts +++ b/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.ts @@ -13,6 +13,10 @@ import { getSavedObjectAttributesFromRepo } from '../lib/telemetry'; interface ITelemetry { ui_viewed: { overview: number; + setup_guide: number; + }; + ui_error: { + cannot_connect: number; }; ui_clicked: { app_search: number; @@ -38,6 +42,10 @@ export const registerTelemetryUsageCollector = ( schema: { ui_viewed: { overview: { type: 'long' }, + setup_guide: { type: 'long' }, + }, + ui_error: { + cannot_connect: { type: 'long' }, }, ui_clicked: { app_search: { type: 'long' }, @@ -63,6 +71,10 @@ const fetchTelemetryMetrics = async (savedObjects: SavedObjectsServiceStart, log const defaultTelemetrySavedObject: ITelemetry = { ui_viewed: { overview: 0, + setup_guide: 0, + }, + ui_error: { + cannot_connect: 0, }, ui_clicked: { app_search: 0, @@ -78,6 +90,10 @@ const fetchTelemetryMetrics = async (savedObjects: SavedObjectsServiceStart, log return { ui_viewed: { overview: get(savedObjectAttributes, 'ui_viewed.overview', 0), + setup_guide: get(savedObjectAttributes, 'ui_viewed.setup_guide', 0), + }, + ui_error: { + cannot_connect: get(savedObjectAttributes, 'ui_error.cannot_connect', 0), }, ui_clicked: { app_search: get(savedObjectAttributes, 'ui_clicked.app_search', 0), diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json index 396a06205eaa9..2b3ff6c8a0aef 100644 --- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json +++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @@ -1706,6 +1706,16 @@ "properties": { "overview": { "type": "long" + }, + "setup_guide": { + "type": "long" + } + } + }, + "ui_error": { + "properties": { + "cannot_connect": { + "type": "long" } } }, From d7a78229e4691a09316c42734ed201e9c66571d9 Mon Sep 17 00:00:00 2001 From: MadameSheema Date: Wed, 28 Oct 2020 17:35:56 +0100 Subject: [PATCH 05/80] [Security Solution] Unskips Alerts and Persistent timeline cypress tests (#81898) * unskips alerts tests * unskips persistent timeline tests --- .../security_solution/cypress/integration/alerts.spec.ts | 3 +-- .../cypress/integration/timeline_local_storage.spec.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/security_solution/cypress/integration/alerts.spec.ts b/x-pack/plugins/security_solution/cypress/integration/alerts.spec.ts index 07d0d63e57059..db841d2a732c4 100644 --- a/x-pack/plugins/security_solution/cypress/integration/alerts.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/alerts.spec.ts @@ -30,8 +30,7 @@ import { loginAndWaitForPage } from '../tasks/login'; import { DETECTIONS_URL } from '../urls/navigation'; -// FLAKY: https://github.com/elastic/kibana/issues/77957 -describe.skip('Alerts', () => { +describe('Alerts', () => { context('Closing alerts', () => { beforeEach(() => { esArchiverLoad('alerts'); diff --git a/x-pack/plugins/security_solution/cypress/integration/timeline_local_storage.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timeline_local_storage.spec.ts index c2ff2c58687f3..383ebe2220585 100644 --- a/x-pack/plugins/security_solution/cypress/integration/timeline_local_storage.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/timeline_local_storage.spec.ts @@ -13,8 +13,7 @@ import { TABLE_COLUMN_EVENTS_MESSAGE } from '../screens/hosts/external_events'; import { waitsForEventsToBeLoaded, openEventsViewerFieldsBrowser } from '../tasks/hosts/events'; import { removeColumn, resetFields } from '../tasks/timeline'; -// FLAKY: https://github.com/elastic/kibana/issues/75794 -describe.skip('persistent timeline', () => { +describe('persistent timeline', () => { before(() => { loginAndWaitForPage(HOSTS_URL); openEvents(); From 6272f4e0fdb0986f2e28e407cae0aa4a2cbafc2e Mon Sep 17 00:00:00 2001 From: Zacqary Adam Xeper Date: Wed, 28 Oct 2020 13:03:36 -0500 Subject: [PATCH 06/80] [Metrics UI] Fix a Chrome bug with Inventory View flickering at certain sizes (#81514) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../pages/metrics/inventory_view/components/waffle/map.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/map.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/map.tsx index 6621b110a6dfd..8023e3bf7da62 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/map.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/map.tsx @@ -45,8 +45,8 @@ export const Map: React.FC = ({ const sortedNodes = sortNodes(options.sort, nodes); const map = nodesToWaffleMap(sortedNodes); return ( - - {({ measureRef, content: { width = 0, height = 0 } }) => { + + {({ measureRef, bounds: { width = 0, height = 0 } }) => { const groupsWithLayout = applyWaffleMapLayout(map, width, height); return ( Date: Wed, 28 Oct 2020 14:21:41 -0400 Subject: [PATCH 07/80] Fixing flaky test (#81901) --- .../test_suites/task_manager/task_management.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_management.ts b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_management.ts index 348ff35b2968f..f34cb7594d288 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_management.ts +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_management.ts @@ -57,8 +57,7 @@ export default function ({ getService }: FtrProviderContext) { const testHistoryIndex = '.kibana_task_manager_test_result'; const supertest = supertestAsPromised(url.format(config.get('servers.kibana'))); - // Failing: See https://github.com/elastic/kibana/issues/81853 - describe.skip('scheduling and running tasks', () => { + describe('scheduling and running tasks', () => { beforeEach( async () => await supertest.delete('/api/sample_tasks').set('kbn-xsrf', 'xxx').expect(200) ); @@ -673,7 +672,7 @@ export default function ({ getService }: FtrProviderContext) { const [scheduledTask] = (await currentTasks()).docs; expect(scheduledTask.id).to.eql(task.id); expect(scheduledTask.status).to.eql('claiming'); - expect(scheduledTask.attempts).to.eql(4); + expect(scheduledTask.attempts).to.be.greaterThan(3); }); }); }); From 2a4337e8b50a445016084c9f120ef0d81a6c0d4a Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 28 Oct 2020 19:33:30 +0100 Subject: [PATCH 08/80] [UX] Fix core vitals empty state (#81781) --- .../RumDashboard/UXMetrics/KeyUXMetrics.tsx | 9 +- .../UXMetrics/__tests__/KeyUXMetrics.test.tsx | 1 + .../app/RumDashboard/UXMetrics/index.tsx | 14 +- .../app/RumDashboard/UserPercentile/index.tsx | 2 - .../__snapshots__/queries.test.ts.snap | 12 +- .../lib/rum_client/get_web_core_vitals.ts | 61 ++++---- .../app/section/ux/mock_data/ux.mock.ts | 1 + .../core_web_vitals/core_vital_item.tsx | 6 +- .../shared/core_web_vitals/index.tsx | 37 +++-- .../core_web_vitals/web_core_vitals_title.tsx | 134 ++++++++++++++---- .../observability/public/data_handler.test.ts | 2 + .../trial/tests/csm/web_core_vitals.ts | 21 ++- 12 files changed, 209 insertions(+), 91 deletions(-) diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx index 793c9619edb3d..e91f129195366 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx @@ -37,8 +37,9 @@ interface Props { loading: boolean; } -function formatTitle(unit: string, value?: number) { - if (typeof value === 'undefined') return DATA_UNDEFINED_LABEL; +function formatTitle(unit: string, value?: number | null) { + if (typeof value === 'undefined' || value === null) + return DATA_UNDEFINED_LABEL; return formatToSec(value, unit); } @@ -85,8 +86,8 @@ export function KeyUXMetrics({ data, loading }: Props) { { lcpRanks: [69, 17, 14], fidRanks: [83, 6, 11], clsRanks: [90, 7, 3], + coreVitalPages: 1000, }} /> ); diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/index.tsx index 521cb6cdf116f..983e3be1c21a9 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { useContext } from 'react'; import { EuiFlexGroup, EuiFlexItem, @@ -18,6 +18,7 @@ import { KeyUXMetrics } from './KeyUXMetrics'; import { useFetcher } from '../../../../hooks/useFetcher'; import { useUxQuery } from '../hooks/useUxQuery'; import { CoreVitals } from '../../../../../../observability/public'; +import { CsmSharedContext } from '../CsmSharedContext'; import { useUrlParams } from '../../../../hooks/useUrlParams'; import { getPercentileLabel } from './translations'; @@ -43,6 +44,10 @@ export function UXMetrics() { [uxQuery] ); + const { + sharedData: { totalPageViews }, + } = useContext(CsmSharedContext); + return ( @@ -62,7 +67,12 @@ export function UXMetrics() { - + diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/UserPercentile/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/UserPercentile/index.tsx index 18cd7d79cc69f..04c7e3cc00287 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/UserPercentile/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/UserPercentile/index.tsx @@ -45,13 +45,11 @@ export function UserPercentile() { { value: '50', text: I18LABELS.percentile50thMedian, - dropdownDisplay: I18LABELS.percentile50thMedian, 'data-test-subj': 'p50Percentile', }, { value: '75', text: I18LABELS.percentile75th, - dropdownDisplay: I18LABELS.percentile75th, 'data-test-subj': 'p75Percentile', }, { 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 index eedc3a83cd376..53dcd2f469148 100644 --- 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 @@ -580,6 +580,13 @@ Object { ], }, }, + "coreVitalPages": Object { + "filter": Object { + "exists": Object { + "field": "transaction.experience", + }, + }, + }, "fcp": Object { "percentiles": Object { "field": "transaction.marks.agent.firstContentfulPaint", @@ -660,11 +667,6 @@ Object { "service.environment": "test", }, }, - Object { - "term": Object { - "user_agent.name": "Chrome", - }, - }, ], }, }, diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_web_core_vitals.ts b/x-pack/plugins/apm/server/lib/rum_client/get_web_core_vitals.ts index c5baf0b529eb4..76a718bbb2a02 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_web_core_vitals.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_web_core_vitals.ts @@ -12,7 +12,6 @@ import { FCP_FIELD, FID_FIELD, LCP_FIELD, - USER_AGENT_NAME, TBT_FIELD, } from '../../../common/elasticsearch_fieldnames'; @@ -35,17 +34,17 @@ export async function getWebCoreVitals({ size: 0, query: { bool: { - filter: [ - ...projection.body.query.bool.filter, - { - term: { - [USER_AGENT_NAME]: 'Chrome', - }, - }, - ], + filter: [...projection.body.query.bool.filter], }, }, aggs: { + coreVitalPages: { + filter: { + exists: { + field: 'transaction.experience', + }, + }, + }, lcp: { percentiles: { field: LCP_FIELD, @@ -104,13 +103,22 @@ export async function getWebCoreVitals({ const { apmEventClient } = setup; const response = await apmEventClient.search(params); - const { lcp, cls, fid, tbt, fcp, lcpRanks, fidRanks, clsRanks } = - response.aggregations ?? {}; + const { + lcp, + cls, + fid, + tbt, + fcp, + lcpRanks, + fidRanks, + clsRanks, + coreVitalPages, + } = response.aggregations ?? {}; const getRanksPercentages = ( - ranks: Array<{ key: number; value: number }> + ranks?: Array<{ key: number; value: number }> ) => { - const ranksVal = ranks.map(({ value }) => value?.toFixed(0) ?? 0); + const ranksVal = ranks?.map(({ value }) => value?.toFixed(0) ?? 0) ?? []; return [ Number(ranksVal?.[0]), Number(ranksVal?.[1]) - Number(ranksVal?.[0]), @@ -118,23 +126,26 @@ export async function getWebCoreVitals({ ]; }; - const defaultRanks = [ - { value: 0, key: 0 }, - { value: 0, key: 0 }, - ]; + const defaultRanks = [100, 0, 0]; const pkey = percentile.toFixed(1); - // Divide by 1000 to convert ms into seconds return { - cls: String(cls?.values[pkey]?.toFixed(2) || 0), - fid: fid?.values[pkey] ?? 0, - lcp: lcp?.values[pkey] ?? 0, + coreVitalPages: coreVitalPages?.doc_count ?? 0, + cls: cls?.values[pkey]?.toFixed(3) || null, + fid: fid?.values[pkey], + lcp: lcp?.values[pkey], tbt: tbt?.values[pkey] ?? 0, - fcp: fcp?.values[pkey] ?? 0, + fcp: fcp?.values[pkey], - lcpRanks: getRanksPercentages(lcpRanks?.values ?? defaultRanks), - fidRanks: getRanksPercentages(fidRanks?.values ?? defaultRanks), - clsRanks: getRanksPercentages(clsRanks?.values ?? defaultRanks), + lcpRanks: lcp?.values[pkey] + ? getRanksPercentages(lcpRanks?.values) + : defaultRanks, + fidRanks: fid?.values[pkey] + ? getRanksPercentages(fidRanks?.values) + : defaultRanks, + clsRanks: cls?.values[pkey] + ? getRanksPercentages(clsRanks?.values) + : defaultRanks, }; } diff --git a/x-pack/plugins/observability/public/components/app/section/ux/mock_data/ux.mock.ts b/x-pack/plugins/observability/public/components/app/section/ux/mock_data/ux.mock.ts index e61564f9df753..017f385d36735 100644 --- a/x-pack/plugins/observability/public/components/app/section/ux/mock_data/ux.mock.ts +++ b/x-pack/plugins/observability/public/components/app/section/ux/mock_data/ux.mock.ts @@ -14,6 +14,7 @@ export const response: UxFetchDataResponse = { lcp: 1942.6666666666667, tbt: 281.55833333333334, fcp: 1487, + coreVitalPages: 100, lcpRanks: [65, 19, 16], fidRanks: [73, 11, 16], clsRanks: [86, 8, 6], diff --git a/x-pack/plugins/observability/public/components/shared/core_web_vitals/core_vital_item.tsx b/x-pack/plugins/observability/public/components/shared/core_web_vitals/core_vital_item.tsx index 0d0a388855ff2..18831565b8784 100644 --- a/x-pack/plugins/observability/public/components/shared/core_web_vitals/core_vital_item.tsx +++ b/x-pack/plugins/observability/public/components/shared/core_web_vitals/core_vital_item.tsx @@ -34,7 +34,7 @@ export interface Thresholds { interface Props { title: string; - value?: string; + value?: string | null; ranks?: number[]; loading: boolean; thresholds: Thresholds; @@ -88,14 +88,14 @@ export function CoreVitalItem({ const biggestValIndex = ranks.indexOf(Math.max(...ranks)); - if (value === undefined && ranks[0] === 100 && !loading) { + if ((value === null || value !== undefined) && ranks[0] === 100 && !loading) { return ; } return ( <> {title} diff --git a/x-pack/plugins/observability/public/components/shared/core_web_vitals/index.tsx b/x-pack/plugins/observability/public/components/shared/core_web_vitals/index.tsx index 6a507176e55f6..f5683310c3b7c 100644 --- a/x-pack/plugins/observability/public/components/shared/core_web_vitals/index.tsx +++ b/x-pack/plugins/observability/public/components/shared/core_web_vitals/index.tsx @@ -18,11 +18,12 @@ import { WebCoreVitalsTitle } from './web_core_vitals_title'; import { ServiceName } from './service_name'; export interface UXMetrics { - cls: string; - fid: number; - lcp: number; + cls: string | null; + fid?: number | null; + lcp?: number | null; tbt: number; - fcp: number; + fcp?: number | null; + coreVitalPages: number; lcpRanks: number[]; fidRanks: number[]; clsRanks: number[]; @@ -48,21 +49,35 @@ interface Props { data?: UXMetrics | null; displayServiceName?: boolean; serviceName?: string; + totalPageViews?: number; + displayTrafficMetric?: boolean; } -function formatValue(value?: number) { - if (typeof value === 'undefined') { - return undefined; +function formatValue(value?: number | null) { + if (typeof value === 'undefined' || value === null) { + return null; } return formatToSec(value, 'ms'); } -export function CoreVitals({ data, loading, displayServiceName, serviceName }: Props) { - const { lcp, lcpRanks, fid, fidRanks, cls, clsRanks } = data || {}; +export function CoreVitals({ + data, + loading, + displayServiceName, + serviceName, + totalPageViews, + displayTrafficMetric = false, +}: Props) { + const { lcp, lcpRanks, fid, fidRanks, cls, clsRanks, coreVitalPages } = data || {}; return ( <> - + {displayServiceName && } @@ -90,7 +105,7 @@ export function CoreVitals({ data, loading, displayServiceName, serviceName }: P setIsPopoverOpen(false); + const closeBrowserPopover = () => setIsBrowserPopoverOpen(false); return ( - -

- {CORE_WEB_VITALS} - setIsPopoverOpen(true)} - color={'text'} - iconType={'questionInCircle'} - /> - } - closePopover={closePopover} - > -
- + + + +

+ {CORE_WEB_VITALS} + setIsPopoverOpen(true)} + color={'text'} + iconType={'questionInCircle'} + /> + } + closePopover={closePopover} + > +
+ + {' '} + + {CORE_WEB_VITALS} + + +
+
+

+
+
+ {displayTrafficMetric && totalPageViews > 0 && ( + + {loading ? ( + + ) : ( + {(((coreVitalPages || 0) / totalPageViews) * 100).toFixed(0)}% + ), + }} /> - - {' '} - {CORE_WEB_VITALS} - + + setIsBrowserPopoverOpen(true)} + color={'text'} + iconType={'questionInCircle'} + /> + } + closePopover={closeBrowserPopover} + > +
+ + {' '} + + {BROWSER_CORE_WEB_VITALS} + + +
+
-
-
-

-
+ )} +
+ )} + ); } diff --git a/x-pack/plugins/observability/public/data_handler.test.ts b/x-pack/plugins/observability/public/data_handler.test.ts index dae2f62777d30..8fdfc2bc622ca 100644 --- a/x-pack/plugins/observability/public/data_handler.test.ts +++ b/x-pack/plugins/observability/public/data_handler.test.ts @@ -287,6 +287,7 @@ describe('registerDataHandler', () => { lcp: 1464.3333333333333, tbt: 232.92166666666665, fcp: 1154.8, + coreVitalPages: 100, lcpRanks: [73, 16, 11], fidRanks: [85, 4, 11], clsRanks: [88, 7, 5], @@ -314,6 +315,7 @@ describe('registerDataHandler', () => { lcp: 1464.3333333333333, tbt: 232.92166666666665, fcp: 1154.8, + coreVitalPages: 100, lcpRanks: [73, 16, 11], fidRanks: [85, 4, 11], clsRanks: [88, 7, 5], diff --git a/x-pack/test/apm_api_integration/trial/tests/csm/web_core_vitals.ts b/x-pack/test/apm_api_integration/trial/tests/csm/web_core_vitals.ts index efbdb75c47cc1..5dbe266deeb81 100644 --- a/x-pack/test/apm_api_integration/trial/tests/csm/web_core_vitals.ts +++ b/x-pack/test/apm_api_integration/trial/tests/csm/web_core_vitals.ts @@ -21,14 +21,12 @@ export default function rumServicesApiTests({ getService }: FtrProviderContext) expect(response.status).to.be(200); expect(response.body).to.eql({ - cls: '0', - fid: '0.00', - lcp: '0.00', - tbt: '0.00', - fcp: 0, - lcpRanks: [0, 0, 100], - fidRanks: [0, 0, 100], - clsRanks: [0, 0, 100], + coreVitalPages: 0, + cls: null, + tbt: 0, + lcpRanks: [100, 0, 0], + fidRanks: [100, 0, 0], + clsRanks: [100, 0, 0], }); }); }); @@ -52,20 +50,21 @@ export default function rumServicesApiTests({ getService }: FtrProviderContext) expectSnapshot(response.body).toMatchInline(` Object { - "cls": "0.00", + "cls": "0.000", "clsRanks": Array [ 100, 0, 0, ], - "fcp": 1072, + "coreVitalPages": 6, + "fcp": 817.5, "fid": 1352.13, "fidRanks": Array [ 0, 0, 100, ], - "lcp": 1270.5, + "lcp": 1019, "lcpRanks": Array [ 100, 0, From f88c66446119971f759315dbb9c29be9d578ca96 Mon Sep 17 00:00:00 2001 From: nnamdifrankie <56440728+nnamdifrankie@users.noreply.github.com> Date: Wed, 28 Oct 2020 15:35:53 -0400 Subject: [PATCH 09/80] [Fleet]: add log statement when deleting transform (#81927) [Fleet]: add log statement when deleting transform --- .../server/services/epm/elasticsearch/transform/install.ts | 5 +++++ .../server/services/epm/elasticsearch/transform/remove.ts | 6 ++++-- .../services/epm/elasticsearch/transform/transform.test.ts | 4 ++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/install.ts index 89811783a7f79..1002eedc48740 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/install.ts @@ -17,6 +17,7 @@ import { CallESAsCurrentUser } from '../../../../types'; import { getInstallation } from '../../packages'; import { deleteTransforms, deleteTransformRefs } from './remove'; import { getAsset } from './common'; +import { appContextService } from '../../../app_context'; interface TransformInstallation { installationName: string; @@ -29,6 +30,7 @@ export const installTransform = async ( callCluster: CallESAsCurrentUser, savedObjectsClient: SavedObjectsClientContract ) => { + const logger = appContextService.getLogger(); const installation = await getInstallation({ savedObjectsClient, pkgName: installablePackage.name, @@ -38,6 +40,9 @@ export const installTransform = async ( previousInstalledTransformEsAssets = installation.installed_es.filter( ({ type, id }) => type === ElasticsearchAssetType.transform ); + logger.info( + `Found previous transform references:\n ${JSON.stringify(previousInstalledTransformEsAssets)}` + ); } // delete all previous transform diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.ts index 5b5583a121e5d..de7aeb816f76e 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.ts @@ -24,6 +24,8 @@ export const deleteTransforms = async ( callCluster: CallESAsCurrentUser, transformIds: string[] ) => { + const logger = appContextService.getLogger(); + logger.info(`Deleting currently installed transform ids ${transformIds}`); await Promise.all( transformIds.map(async (transformId) => { // get the index the transform @@ -47,7 +49,7 @@ export const deleteTransforms = async ( path: `/_transform/${transformId}`, ignore: [404], }); - + logger.info(`Deleted: ${transformId}`); if (transformResponse?.transforms) { // expect this to be 1 for (const transform of transformResponse.transforms) { @@ -58,7 +60,7 @@ export const deleteTransforms = async ( }); } } else { - appContextService.getLogger().warn(`cannot find transform for ${transformId}`); + logger.warn(`cannot find transform for ${transformId}`); } }) ); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/transform.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/transform.test.ts index 2bf0ad12856f8..7ca2a32cf770c 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/transform.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/transform.test.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { createAppContextStartContractMock } from '../../../../mocks'; + jest.mock('../../packages/get', () => { return { getInstallation: jest.fn(), getInstallationObject: jest.fn() }; }); @@ -21,11 +23,13 @@ import { getInstallation, getInstallationObject } from '../../packages'; import { getAsset } from './common'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { savedObjectsClientMock } from '../../../../../../../../src/core/server/saved_objects/service/saved_objects_client.mock'; +import { appContextService } from '../../../app_context'; describe('test transform install', () => { let legacyScopedClusterClient: jest.Mocked; let savedObjectsClient: jest.Mocked; beforeEach(() => { + appContextService.start(createAppContextStartContractMock()); legacyScopedClusterClient = { callAsInternalUser: jest.fn(), callAsCurrentUser: jest.fn(), From 2daa511b9f05a7537707e928aeefa8369d773f68 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Wed, 28 Oct 2020 16:23:36 -0400 Subject: [PATCH 10/80] [Fleet] Test creating|copying a policy create a correct POLICY_CHANGE action (#81661) --- .../agent_policy_with_agents_setup.ts | 137 ++++++++++++++++++ .../apis/agent_policy/index.js | 1 + 2 files changed, 138 insertions(+) create mode 100644 x-pack/test/ingest_manager_api_integration/apis/agent_policy/agent_policy_with_agents_setup.ts diff --git a/x-pack/test/ingest_manager_api_integration/apis/agent_policy/agent_policy_with_agents_setup.ts b/x-pack/test/ingest_manager_api_integration/apis/agent_policy/agent_policy_with_agents_setup.ts new file mode 100644 index 0000000000000..d99e6a69c5124 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/agent_policy/agent_policy_with_agents_setup.ts @@ -0,0 +1,137 @@ +/* + * 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 expect from '@kbn/expect'; +import { skipIfNoDockerRegistry } from '../../helpers'; +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; +import { setupIngest, getSupertestWithoutAuth } from '../fleet/agents/services'; + +export default function (providerContext: FtrProviderContext) { + const { getService } = providerContext; + const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + const supertestWithoutAuth = getSupertestWithoutAuth(providerContext); + const kibanaServer = getService('kibanaServer'); + + async function getEnrollmentKeyForPolicyId(policyId: string) { + const listRes = await supertest.get(`/api/fleet/enrollment-api-keys`).expect(200); + + const key = listRes.body.list.find( + (item: { policy_id: string; id: string }) => item.policy_id === policyId + ); + + expect(key).not.empty(); + + const res = await supertest.get(`/api/fleet/enrollment-api-keys/${key.id}`).expect(200); + + return res.body.item; + } + + // Enroll an agent to get the actions for an agent as encrypted saved object are not expose otherwise + async function getAgentActionsForEnrollmentKey(enrollmentAPIToken: string) { + const kibanaVersionAccessor = kibanaServer.version; + const kibanaVersion = await kibanaVersionAccessor.get(); + + const { body: enrollmentResponse } = await supertestWithoutAuth + .post(`/api/ingest_manager/fleet/agents/enroll`) + .set('kbn-xsrf', 'xxx') + .set('Authorization', `ApiKey ${enrollmentAPIToken}`) + .send({ + type: 'PERMANENT', + metadata: { + local: { + elastic: { agent: { version: kibanaVersion } }, + }, + user_provided: {}, + }, + }) + .expect(200); + + const agentAccessAPIKey = enrollmentResponse.item.access_api_key; + + // Agent checkin + const { body: checkinApiResponse } = await supertestWithoutAuth + .post(`/api/ingest_manager/fleet/agents/${enrollmentResponse.item.id}/checkin`) + .set('kbn-xsrf', 'xx') + .set('Authorization', `ApiKey ${agentAccessAPIKey}`) + .send({ + events: [], + }) + .expect(200); + + expect(checkinApiResponse.actions).length(1); + + return checkinApiResponse.actions[0]; + } + + // Test all the side effect that should occurs when we create|update an agent policy + describe('ingest_manager_agent_policies_with_agents_setup', () => { + skipIfNoDockerRegistry(providerContext); + + before(async () => { + await esArchiver.loadIfNeeded('fleet/agents'); + }); + after(async () => { + await esArchiver.unload('fleet/agents'); + }); + + setupIngest(providerContext); + + describe('POST /api/fleet/agent_policies', () => { + it('should create an enrollment key and an agent action `POLICY_CHANGE` for the policy', async () => { + const name = `test-${Date.now()}`; + + const res = await supertest + .post(`/api/fleet/agent_policies?sys_monitoring=true`) + .set('kbn-xsrf', 'xxxx') + .send({ + name, + namespace: 'default', + }) + .expect(200); + + const policyId = res.body.item.id; + const enrollmentKey = await getEnrollmentKeyForPolicyId(policyId); + expect(enrollmentKey).not.empty(); + + const action = await getAgentActionsForEnrollmentKey(enrollmentKey.api_key); + + expect(action.type).to.be('POLICY_CHANGE'); + const agentPolicy = action.data.policy; + expect(agentPolicy.id).to.be(policyId); + // should have system inputs + expect(agentPolicy.inputs).length(2); + // should have default output + expect(agentPolicy.outputs.default).not.empty(); + }); + }); + + describe('POST /api/fleet/agent_policies/copy', () => { + const TEST_POLICY_ID = `policy1`; + + it('should create an enrollment key and an agent action `POLICY_CHANGE` for the policy', async () => { + const name = `test-${Date.now()}`; + + const res = await supertest + .post(`/api/fleet/agent_policies/${TEST_POLICY_ID}/copy`) + .set('kbn-xsrf', 'xxxx') + .send({ + name, + description: 'Test', + }) + .expect(200); + + const policyId = res.body.item.id; + const enrollmentKey = await getEnrollmentKeyForPolicyId(policyId); + expect(enrollmentKey).not.empty(); + + const action = await getAgentActionsForEnrollmentKey(enrollmentKey.api_key); + expect(action.type).to.be('POLICY_CHANGE'); + expect(action.data.policy.id).to.be(policyId); + }); + }); + }); +} diff --git a/x-pack/test/ingest_manager_api_integration/apis/agent_policy/index.js b/x-pack/test/ingest_manager_api_integration/apis/agent_policy/index.js index a513e7991fa74..da608b7057c0a 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/agent_policy/index.js +++ b/x-pack/test/ingest_manager_api_integration/apis/agent_policy/index.js @@ -6,6 +6,7 @@ export default function loadTests({ loadTestFile }) { describe('Ingest Manager Endpoints', () => { + loadTestFile(require.resolve('./agent_policy_with_agents_setup')); loadTestFile(require.resolve('./agent_policy')); }); } From 526de26f034e43521c911e12899ce523a73be607 Mon Sep 17 00:00:00 2001 From: IgorG <56408662+IgorGuz2000@users.noreply.github.com> Date: Wed, 28 Oct 2020 14:02:29 -0700 Subject: [PATCH 11/80] [Feature:Resolver] enable_APM-ci branch fixes (#81658) * Added Test for event.library * renamed data directry and gzip data file * rename expectedData file * Changes per Charlie request * Changes for the enable_APM-ci branch * Update resolver.ts * Added comment per Charlie request * Update resolver.ts Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../apps/endpoint/resolver.ts | 12 +++++++++++- .../page_objects/hosts_page.ts | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/resolver.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/resolver.ts index 1af9ec88df852..b45c082423628 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/resolver.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/resolver.ts @@ -262,11 +262,21 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await esArchiver.load('endpoint/resolver_tree/library_events', { useCreate: true }); await queryBar.setQuery(''); await queryBar.submitQuery(); - const expectedLibraryData = ['329 network', '1 library', '1 library']; + const expectedLibraryData = [ + '1 authentication', + '1 session', + '329 network', + '1 library', + '1 library', + ]; await pageObjects.hosts.navigateToEventsPanel(); await pageObjects.hosts.executeQueryAndOpenResolver( 'event.dataset : endpoint.events.library' ); + // This lines will move the resolver view for clear visibility of the related events. + for (let i = 0; i < 7; i++) { + await (await testSubjects.find('resolver:graph-controls:west-button')).click(); + } await pageObjects.hosts.runNodeEvents(expectedLibraryData); }); }); diff --git a/x-pack/test/security_solution_endpoint/page_objects/hosts_page.ts b/x-pack/test/security_solution_endpoint/page_objects/hosts_page.ts index 3301217e41a90..988fadbbdfe33 100644 --- a/x-pack/test/security_solution_endpoint/page_objects/hosts_page.ts +++ b/x-pack/test/security_solution_endpoint/page_objects/hosts_page.ts @@ -127,6 +127,7 @@ export function SecurityHostsPageProvider({ getService, getPageObjects }: FtrPro expect(EventName).to.equal(linkText); expect(EventName).to.equal(expectedData[i]); } + await testSubjects.click('full-screen'); }, /** * Navigate to Events Panel @@ -146,7 +147,6 @@ export function SecurityHostsPageProvider({ getService, getPageObjects }: FtrPro await queryBar.submitQuery(); await testSubjects.click('full-screen'); await testSubjects.click('investigate-in-resolver-button'); - await testSubjects.click('full-screen'); }, }; } From 271a799ef8e4b02092f387bf3622bacabf9b51bd Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 28 Oct 2020 14:08:56 -0700 Subject: [PATCH 12/80] [jenkins] disable CI metrics for temporary feature branches (#81938) Co-authored-by: spalger --- vars/getCheckoutInfo.groovy | 5 +++++ vars/githubPr.groovy | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/vars/getCheckoutInfo.groovy b/vars/getCheckoutInfo.groovy index 32a7b054bfd15..f9d797f8127c7 100644 --- a/vars/getCheckoutInfo.groovy +++ b/vars/getCheckoutInfo.groovy @@ -2,6 +2,7 @@ def call(branchOverride) { def repoInfo = [ branch: branchOverride ?: env.ghprbSourceBranch, targetBranch: env.ghprbTargetBranch, + targetsTrackedBranch: true ] if (repoInfo.branch == null) { @@ -35,6 +36,10 @@ def call(branchOverride) { label: "determining merge point with '${repoInfo.targetBranch}' at origin", returnStdout: true ).trim() + + def pkgJson = readFile("package.json") + def releaseBranch = toJSON(pkgJson).branch + repoInfo.targetsTrackedBranch = releaseBranch == repoInfo.targetBranch } print "repoInfo: ${repoInfo}" diff --git a/vars/githubPr.groovy b/vars/githubPr.groovy index fd5412c905683..546a6785ac2f4 100644 --- a/vars/githubPr.groovy +++ b/vars/githubPr.groovy @@ -149,7 +149,7 @@ def getTestFailuresMessage() { def getBuildStatusIncludingMetrics() { def status = buildUtils.getBuildStatus() - if (status == 'SUCCESS' && !ciStats.getMetricsSuccess()) { + if (status == 'SUCCESS' && shouldCheckCiMetricSuccess() && !ciStats.getMetricsSuccess()) { return 'FAILURE' } @@ -297,3 +297,12 @@ def getFailedSteps() { step.displayName != 'Check out from version control' } } + +def shouldCheckCiMetricSuccess() { + // disable ciMetrics success check when a PR is targetting a non-tracked branch + if (buildState.has('checkoutInfo') && !buildState.get('checkoutInfo').targetsTrackedBranch) { + return false + } + + return true +} From 91a84d5d0fc40ce26bee2804c78d92e6f9ed24a1 Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Wed, 28 Oct 2020 17:20:55 -0500 Subject: [PATCH 13/80] Fix regression in our ml usage collection (#81945) A regression was introduced in #74965 that caused an error to be thrown while collecting telemetry on ML jobs. Because such exceptions are caught and we degrade to zeroing out those counts, this one was not caught until manual testing of telemetry. --- .../server/usage/detections/detections_helpers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/usage/detections/detections_helpers.ts b/x-pack/plugins/security_solution/server/usage/detections/detections_helpers.ts index 5cf17af2fa9c0..6387839db3bfe 100644 --- a/x-pack/plugins/security_solution/server/usage/detections/detections_helpers.ts +++ b/x-pack/plugins/security_solution/server/usage/detections/detections_helpers.ts @@ -172,7 +172,7 @@ export const getMlJobsUsage = async (ml: MlPluginSetup | undefined): Promise Date: Wed, 28 Oct 2020 17:58:05 -0500 Subject: [PATCH 14/80] [deb/rpm] kibana.service cleanup (#75219) --- .../systemd/etc/systemd/system/kibana.service | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/dev/build/tasks/os_packages/service_templates/systemd/etc/systemd/system/kibana.service b/src/dev/build/tasks/os_packages/service_templates/systemd/etc/systemd/system/kibana.service index e66e0e7c8dfb5..df33b82f1f967 100644 --- a/src/dev/build/tasks/os_packages/service_templates/systemd/etc/systemd/system/kibana.service +++ b/src/dev/build/tasks/os_packages/service_templates/systemd/etc/systemd/system/kibana.service @@ -1,21 +1,32 @@ [Unit] Description=Kibana +Documentation=https://www.elastic.co +Wants=network-online.target +After=network-online.target [Service] Type=simple User=kibana Group=kibana -# Load env vars from /etc/default/ and /etc/sysconfig/ if they exist. -# Prefixing the path with '-' makes it try to load, but if the file doesn't -# exist, it continues onward. + +Environment=KBN_HOME=/usr/share/kibana +Environment=KBN_PATH_CONF=/etc/kibana + EnvironmentFile=-/etc/default/kibana EnvironmentFile=-/etc/sysconfig/kibana + ExecStart=/usr/share/kibana/bin/kibana + Restart=on-failure RestartSec=3 + StartLimitBurst=3 StartLimitInterval=60 -WorkingDirectory=/ + +WorkingDirectory=/usr/share/kibana + +StandardOutput=journal +StandardError=inherit [Install] WantedBy=multi-user.target From bd64a0bb95ba109e0bb2b26157e63aecb5fa79de Mon Sep 17 00:00:00 2001 From: Brandon Kobel Date: Wed, 28 Oct 2020 16:30:11 -0700 Subject: [PATCH 15/80] Adding a comment about the NeededFor: label (#81939) --- .github/ISSUE_TEMPLATE/v8_breaking_change.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/v8_breaking_change.md b/.github/ISSUE_TEMPLATE/v8_breaking_change.md index c91b937586a09..42783808e32ed 100644 --- a/.github/ISSUE_TEMPLATE/v8_breaking_change.md +++ b/.github/ISSUE_TEMPLATE/v8_breaking_change.md @@ -7,6 +7,16 @@ assignees: '' --- + + ## Change description **Which release will ship the breaking change?** From 3af1099ba830bcccc04094c5e251f2b2d6f3309b Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Wed, 28 Oct 2020 16:38:59 -0700 Subject: [PATCH 16/80] [browserlist] Excludes browsers not supporting es6-class (#81431) * Updates browserlist to exclude those not supporting es6-class Signed-off-by: Tyler Smalley --- .browserslistrc | 2 ++ .../__snapshots__/basic_optimization.test.ts.snap | 2 +- .../maps/public/classes/tooltips/join_tooltip_property.ts | 6 ++++-- yarn.lock | 6 +++--- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.browserslistrc b/.browserslistrc index 04395b913c9c5..36298c0f8cb93 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -4,6 +4,8 @@ last 2 Chrome versions last 2 Safari versions > 0.25% not ie 11 +not op_mini all +not samsung 4 [dev] last 1 chrome versions diff --git a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap index cb5bb1e8fc529..ddb19c8cdc3d7 100644 --- a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap +++ b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap @@ -108,4 +108,4 @@ exports[`prepares assets for distribution: baz bundle 1`] = ` exports[`prepares assets for distribution: foo async bundle 1`] = `"(window[\\"foo_bundle_jsonpfunction\\"]=window[\\"foo_bundle_jsonpfunction\\"]||[]).push([[1],{3:function(module,__webpack_exports__,__webpack_require__){\\"use strict\\";__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,\\"foo\\",(function(){return foo}));function foo(){}}}]);"`; -exports[`prepares assets for distribution: foo bundle 1`] = `"(function(modules){function webpackJsonpCallback(data){var chunkIds=data[0];var moreModules=data[1];var moduleId,chunkId,i=0,resolves=[];for(;i { const esFilters = []; if (this._tooltipProperty.isFilterable()) { - esFilters.push(...(await this._tooltipProperty.getESFilters())); + const filters = await this._tooltipProperty.getESFilters(); + esFilters.push(...filters); } for (let i = 0; i < this._leftInnerJoins.length; i++) { @@ -51,7 +52,8 @@ export class JoinTooltipProperty implements ITooltipProperty { this._tooltipProperty.getRawValue() ); if (esTooltipProperty) { - esFilters.push(...(await esTooltipProperty.getESFilters())); + const filters = await esTooltipProperty.getESFilters(); + esFilters.push(...filters); } } catch (e) { // eslint-disable-next-line no-console diff --git a/yarn.lock b/yarn.lock index 8de8e0a8c0eb2..b2216537bbd7c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8153,9 +8153,9 @@ camelize@^1.0.0: integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= caniuse-lite@^1.0.30001035, caniuse-lite@^1.0.30001043, caniuse-lite@^1.0.30001097: - version "1.0.30001114" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001114.tgz#2e88119afb332ead5eaa330e332e951b1c4bfea9" - integrity sha512-ml/zTsfNBM+T1+mjglWRPgVsu2L76GAaADKX5f4t0pbhttEp0WMawJsHDYlFkVZkoA+89uvBRrVrEE4oqenzXQ== + version "1.0.30001150" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001150.tgz" + integrity sha512-kiNKvihW0m36UhAFnl7bOAv0i1K1f6wpfVtTF5O5O82XzgtBnb05V0XeV3oZ968vfg2sRNChsHw8ASH2hDfoYQ== capture-exit@^2.0.0: version "2.0.0" From 06c99bbf7e102683414809c99cffa636af54eaaf Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 28 Oct 2020 18:37:09 -0600 Subject: [PATCH 17/80] [Maps] consolidate map saved object loading into MapApp component (#81914) * [Maps] consolidate map saved object loading into MapApp component * tslint * more tslint cleanup * tslint * review feedback --- .../public/lazy_load_bundle/lazy/index.ts | 2 +- .../{maps_router.tsx => render_app.tsx} | 43 +++----- .../routing/routes/list/maps_list_view.tsx | 2 +- .../get_breadcrumbs.test.tsx | 2 +- .../{maps_app => map_app}/get_breadcrumbs.tsx | 2 +- .../routes/{maps_app => map_app}/index.ts | 6 +- .../maps_app_view.tsx => map_app/map_app.tsx} | 99 +++++++++++++------ .../{maps_app => map_app}/top_nav_config.tsx | 6 +- .../routes/maps_app/load_map_and_render.tsx | 86 ---------------- .../public/routing/state_syncing/app_sync.ts | 2 +- .../routing/state_syncing/global_sync.ts | 2 +- 11 files changed, 92 insertions(+), 160 deletions(-) rename x-pack/plugins/maps/public/routing/{maps_router.tsx => render_app.tsx} (81%) rename x-pack/plugins/maps/public/routing/routes/{maps_app => map_app}/get_breadcrumbs.test.tsx (96%) rename x-pack/plugins/maps/public/routing/routes/{maps_app => map_app}/get_breadcrumbs.tsx (96%) rename x-pack/plugins/maps/public/routing/routes/{maps_app => map_app}/index.ts (94%) rename x-pack/plugins/maps/public/routing/routes/{maps_app/maps_app_view.tsx => map_app/map_app.tsx} (85%) rename x-pack/plugins/maps/public/routing/routes/{maps_app => map_app}/top_nav_config.tsx (98%) delete mode 100644 x-pack/plugins/maps/public/routing/routes/maps_app/load_map_and_render.tsx diff --git a/x-pack/plugins/maps/public/lazy_load_bundle/lazy/index.ts b/x-pack/plugins/maps/public/lazy_load_bundle/lazy/index.ts index 782d645dc230a..067f213603fe3 100644 --- a/x-pack/plugins/maps/public/lazy_load_bundle/lazy/index.ts +++ b/x-pack/plugins/maps/public/lazy_load_bundle/lazy/index.ts @@ -15,7 +15,7 @@ export * from '../../actions'; export * from '../../selectors/map_selectors'; export * from '../../routing/bootstrap/get_initial_layers'; export * from '../../embeddable/merge_input_with_saved_map'; -export * from '../../routing/maps_router'; +export { renderApp } from '../../routing/render_app'; export * from '../../classes/layers/solution_layers/security'; export { registerLayerWizard } from '../../classes/layers/layer_wizard_registry'; export { registerSource } from '../../classes/sources/source_registry'; diff --git a/x-pack/plugins/maps/public/routing/maps_router.tsx b/x-pack/plugins/maps/public/routing/render_app.tsx similarity index 81% rename from x-pack/plugins/maps/public/routing/maps_router.tsx rename to x-pack/plugins/maps/public/routing/render_app.tsx index d7e6e6e079953..65cccc53f5047 100644 --- a/x-pack/plugins/maps/public/routing/maps_router.tsx +++ b/x-pack/plugins/maps/public/routing/render_app.tsx @@ -6,7 +6,7 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; -import { Router, Switch, Route, Redirect, RouteComponentProps } from 'react-router-dom'; +import { Router, Switch, Route, Redirect } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; import { Provider } from 'react-redux'; import { AppMountParameters } from 'kibana/public'; @@ -24,13 +24,12 @@ import { } from '../../../../../src/plugins/kibana_utils/public'; import { getStore } from './store_operations'; import { LoadListAndRender } from './routes/list/load_list_and_render'; -import { LoadMapAndRender } from './routes/maps_app/load_map_and_render'; +import { MapApp } from './routes/map_app'; export let goToSpecifiedPath: (path: string) => void; export let kbnUrlStateStorage: IKbnUrlStateStorage; export async function renderApp({ - appBasePath, element, history, onAppLeave, @@ -43,29 +42,6 @@ export async function renderApp({ ...withNotifyOnErrors(getToasts()), }); - render( - , - element - ); - - return () => { - unmountComponentAtNode(element); - }; -} - -interface Props { - history: AppMountParameters['history'] | RouteComponentProps['history']; - appBasePath: AppMountParameters['appBasePath']; - onAppLeave: AppMountParameters['onAppLeave']; - setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; -} - -const App: React.FC = ({ history, appBasePath, onAppLeave, setHeaderActionMenu }) => { const store = getStore(); const I18nContext = getCoreI18n().Context; @@ -88,7 +64,7 @@ const App: React.FC = ({ history, appBasePath, onAppLeave, setHeaderActio }); } - return ( + render( @@ -96,7 +72,7 @@ const App: React.FC = ({ history, appBasePath, onAppLeave, setHeaderActio ( - = ({ history, appBasePath, onAppLeave, setHeaderActio exact path={`/map`} render={() => ( - = ({ history, appBasePath, onAppLeave, setHeaderActio - + , + element ); -}; + + return () => { + unmountComponentAtNode(element); + }; +} diff --git a/x-pack/plugins/maps/public/routing/routes/list/maps_list_view.tsx b/x-pack/plugins/maps/public/routing/routes/list/maps_list_view.tsx index 3b0891a4fd44d..ca92442ae93e6 100644 --- a/x-pack/plugins/maps/public/routing/routes/list/maps_list_view.tsx +++ b/x-pack/plugins/maps/public/routing/routes/list/maps_list_view.tsx @@ -30,7 +30,7 @@ import { EuiBasicTableColumn, } from '@elastic/eui/src/components/basic_table/basic_table'; import { EuiTableSortingType } from '@elastic/eui'; -import { goToSpecifiedPath } from '../../maps_router'; +import { goToSpecifiedPath } from '../../render_app'; // @ts-expect-error import { addHelpMenuToAppChrome } from '../../../help_menu_util'; import { APP_ID, MAP_PATH } from '../../../../common/constants'; diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.test.tsx b/x-pack/plugins/maps/public/routing/routes/map_app/get_breadcrumbs.test.tsx similarity index 96% rename from x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.test.tsx rename to x-pack/plugins/maps/public/routing/routes/map_app/get_breadcrumbs.test.tsx index e8e0e583a7c6d..3516daf526968 100644 --- a/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.test.tsx +++ b/x-pack/plugins/maps/public/routing/routes/map_app/get_breadcrumbs.test.tsx @@ -7,7 +7,7 @@ import { getBreadcrumbs } from './get_breadcrumbs'; jest.mock('../../../kibana_services', () => {}); -jest.mock('../../maps_router', () => {}); +jest.mock('../../render_app', () => {}); const getHasUnsavedChanges = () => { return false; diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.tsx b/x-pack/plugins/maps/public/routing/routes/map_app/get_breadcrumbs.tsx similarity index 96% rename from x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.tsx rename to x-pack/plugins/maps/public/routing/routes/map_app/get_breadcrumbs.tsx index d9b60b670b93e..88dba0f83ec2f 100644 --- a/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.tsx +++ b/x-pack/plugins/maps/public/routing/routes/map_app/get_breadcrumbs.tsx @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n'; import { getCoreOverlays, getNavigateToApp } from '../../../kibana_services'; -import { goToSpecifiedPath } from '../../maps_router'; +import { goToSpecifiedPath } from '../../render_app'; import { getAppTitle } from '../../../../common/i18n_getters'; export const unsavedChangesWarning = i18n.translate( diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/index.ts b/x-pack/plugins/maps/public/routing/routes/map_app/index.ts similarity index 94% rename from x-pack/plugins/maps/public/routing/routes/maps_app/index.ts rename to x-pack/plugins/maps/public/routing/routes/map_app/index.ts index 812d7fcf30981..0b9f0cfe33e44 100644 --- a/x-pack/plugins/maps/public/routing/routes/maps_app/index.ts +++ b/x-pack/plugins/maps/public/routing/routes/map_app/index.ts @@ -8,7 +8,7 @@ import { connect } from 'react-redux'; import { ThunkDispatch } from 'redux-thunk'; import { AnyAction } from 'redux'; import { Filter, Query, TimeRange } from 'src/plugins/data/public'; -import { MapsAppView } from './maps_app_view'; +import { MapApp } from './map_app'; import { getFlyoutDisplay, getIsFullScreen } from '../../../selectors/ui_selectors'; import { getFilters, @@ -99,5 +99,5 @@ function mapDispatchToProps(dispatch: ThunkDispatch { +export class MapApp extends React.Component { _globalSyncUnsubscribe: (() => void) | null = null; _globalSyncChangeMonitorSubscription: Subscription | null = null; _appSyncUnsubscribe: (() => void) | null = null; @@ -134,8 +139,6 @@ export class MapsAppView extends React.Component { this._initMap(); - this._setBreadcrumbs(); - this.props.onAppLeave((actions) => { if (this._hasUnsavedChanges()) { return actions.confirm(unsavedChangesWarning, unsavedChangesTitle); @@ -165,7 +168,11 @@ export class MapsAppView extends React.Component { } _hasUnsavedChanges = () => { - const savedLayerList = this.props.savedMap.getLayerList(); + if (!this.state.savedMap) { + return false; + } + + const savedLayerList = this.state.savedMap.getLayerList(); return !savedLayerList ? !_.isEqual(this.props.layerListConfigOnly, this.state.initialLayerListConfig) : // savedMap stores layerList as a JSON string using JSON.stringify. @@ -176,9 +183,9 @@ export class MapsAppView extends React.Component { !_.isEqual(JSON.parse(JSON.stringify(this.props.layerListConfigOnly)), savedLayerList); }; - _setBreadcrumbs = () => { + _setBreadcrumbs = (title: string) => { const breadcrumbs = getBreadcrumbs({ - title: this.props.savedMap.title, + title, getHasUnsavedChanges: this._hasUnsavedChanges, originatingApp: this.state.originatingApp, getAppNameFromId: this.props.stateTransfer.getAppNameFromId, @@ -255,13 +262,12 @@ export class MapsAppView extends React.Component { updateGlobalState(updatedGlobalState, !this.state.initialized); }; - _initMapAndLayerSettings() { + _initMapAndLayerSettings(savedMap: ISavedGisMap) { const globalState: MapsGlobalState = getGlobalState(); - const mapStateJSON = this.props.savedMap.mapStateJSON; let savedObjectFilters = []; - if (mapStateJSON) { - const mapState = JSON.parse(mapStateJSON); + if (savedMap.mapStateJSON) { + const mapState = JSON.parse(savedMap.mapStateJSON); if (mapState.filters) { savedObjectFilters = mapState.filters; } @@ -269,7 +275,7 @@ export class MapsAppView extends React.Component { const appFilters = this._appStateManager.getFilters() || []; const query = getInitialQuery({ - mapStateJSON, + mapStateJSON: savedMap.mapStateJSON, appState: this._appStateManager.getAppState(), }); if (query) { @@ -280,22 +286,19 @@ export class MapsAppView extends React.Component { filters: [..._.get(globalState, 'filters', []), ...appFilters, ...savedObjectFilters], query, time: getInitialTimeFilters({ - mapStateJSON, + mapStateJSON: savedMap.mapStateJSON, globalState, }), }); this._onRefreshConfigChange( getInitialRefreshConfig({ - mapStateJSON, + mapStateJSON: savedMap.mapStateJSON, globalState, }) ); - const layerList = getInitialLayers( - this.props.savedMap.layerListJSON, - getInitialLayersFromUrlParam() - ); + const layerList = getInitialLayers(savedMap.layerListJSON, getInitialLayersFromUrlParam()); this.props.replaceLayerList(layerList); this.setState({ initialLayerListConfig: copyPersistentState(layerList), @@ -345,13 +348,43 @@ export class MapsAppView extends React.Component { }); }; - _initMap() { - this._initMapAndLayerSettings(); + async _loadSavedMap(): Promise { + let savedMap: ISavedGisMap | null = null; + try { + savedMap = await getMapsSavedObjectLoader().get(this.props.savedMapId); + } catch (err) { + if (this._isMounted) { + getToasts().addWarning({ + title: i18n.translate('xpack.maps.loadMap.errorAttemptingToLoadSavedMap', { + defaultMessage: `Unable to load map`, + }), + text: `${err.message}`, + }); + goToSpecifiedPath('/'); + } + } + + return savedMap; + } + + async _initMap() { + const savedMap = await this._loadSavedMap(); + if (!this._isMounted || !savedMap) { + return; + } + + this._setBreadcrumbs(savedMap.title); + getCoreChrome().docTitle.change(savedMap.title); + if (this.props.savedMapId) { + getCoreChrome().recentlyAccessed.add(savedMap.getFullPath(), savedMap.title, savedMap.id!); + } + + this._initMapAndLayerSettings(savedMap); this.props.clearUi(); - if (this.props.savedMap.mapStateJSON) { - const mapState = JSON.parse(this.props.savedMap.mapStateJSON); + if (savedMap.mapStateJSON) { + const mapState = JSON.parse(savedMap.mapStateJSON); this.props.setGotoWithCenter({ lat: mapState.center.lat, lon: mapState.center.lon, @@ -362,22 +395,22 @@ export class MapsAppView extends React.Component { } } - if (this.props.savedMap.uiStateJSON) { - const uiState = JSON.parse(this.props.savedMap.uiStateJSON); + if (savedMap.uiStateJSON) { + const uiState = JSON.parse(savedMap.uiStateJSON); this.props.setIsLayerTOCOpen(_.get(uiState, 'isLayerTOCOpen', DEFAULT_IS_LAYER_TOC_OPEN)); this.props.setOpenTOCDetails(_.get(uiState, 'openTOCDetails', [])); } - this.setState({ initialized: true }); + this.setState({ initialized: true, savedMap }); } _renderTopNav() { - if (this.props.isFullScreen) { + if (this.props.isFullScreen || !this.state.savedMap) { return null; } const topNavConfig = getTopNavConfig({ - savedMap: this.props.savedMap, + savedMap: this.state.savedMap, isOpenSettingsDisabled: this.props.isOpenSettingsDisabled, isSaveDisabled: this.props.isSaveDisabled, enableFullScreen: this.props.enableFullScreen, @@ -452,18 +485,22 @@ export class MapsAppView extends React.Component { }; render() { - return this.state.initialized ? ( + if (!this.state.initialized || !this.state.savedMap) { + return null; + } + + return (
{this._renderTopNav()}

{`screenTitle placeholder`}

- ) : null; + ); } } diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/top_nav_config.tsx b/x-pack/plugins/maps/public/routing/routes/map_app/top_nav_config.tsx similarity index 98% rename from x-pack/plugins/maps/public/routing/routes/maps_app/top_nav_config.tsx rename to x-pack/plugins/maps/public/routing/routes/map_app/top_nav_config.tsx index 917abebfb6b25..c60f44093541f 100644 --- a/x-pack/plugins/maps/public/routing/routes/maps_app/top_nav_config.tsx +++ b/x-pack/plugins/maps/public/routing/routes/map_app/top_nav_config.tsx @@ -21,7 +21,7 @@ import { showSaveModal, } from '../../../../../../../src/plugins/saved_objects/public'; import { MAP_SAVED_OBJECT_TYPE } from '../../../../common/constants'; -import { goToSpecifiedPath } from '../../maps_router'; +import { goToSpecifiedPath } from '../../render_app'; import { ISavedGisMap } from '../../bootstrap/services/saved_gis_map'; import { EmbeddableStateTransfer } from '../../../../../../../src/plugins/embeddable/public'; @@ -43,7 +43,7 @@ export function getTopNavConfig({ enableFullScreen: () => void; openMapSettings: () => void; inspectorAdapters: Adapters; - setBreadcrumbs: () => void; + setBreadcrumbs: (title: string) => void; stateTransfer?: EmbeddableStateTransfer; originatingApp?: string; cutOriginatingAppConnection: () => void; @@ -104,7 +104,7 @@ export function getTopNavConfig({ }); getCoreChrome().docTitle.change(savedMap.title); - setBreadcrumbs(); + setBreadcrumbs(savedMap.title); goToSpecifiedPath(`/map/${savedObjectId}${window.location.hash}`); const newlyCreated = newCopyOnSave || isNewMap; diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/load_map_and_render.tsx b/x-pack/plugins/maps/public/routing/routes/maps_app/load_map_and_render.tsx deleted file mode 100644 index b980756daad20..0000000000000 --- a/x-pack/plugins/maps/public/routing/routes/maps_app/load_map_and_render.tsx +++ /dev/null @@ -1,86 +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 React from 'react'; -import { i18n } from '@kbn/i18n'; -import { Redirect } from 'react-router-dom'; -import { AppMountParameters } from 'kibana/public'; -import { EmbeddableStateTransfer } from 'src/plugins/embeddable/public'; -import { getCoreChrome, getToasts } from '../../../kibana_services'; -import { getMapsSavedObjectLoader } from '../../bootstrap/services/gis_map_saved_object_loader'; -import { MapsAppView } from '.'; -import { ISavedGisMap } from '../../bootstrap/services/saved_gis_map'; - -interface Props { - savedMapId?: string; - onAppLeave: AppMountParameters['onAppLeave']; - stateTransfer: EmbeddableStateTransfer; - originatingApp?: string; - setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; -} - -interface State { - savedMap?: ISavedGisMap; - failedToLoad: boolean; -} - -export const LoadMapAndRender = class extends React.Component { - _isMounted: boolean = false; - state: State = { - savedMap: undefined, - failedToLoad: false, - }; - - componentDidMount() { - this._isMounted = true; - this._loadSavedMap(); - } - - componentWillUnmount() { - this._isMounted = false; - } - - async _loadSavedMap() { - try { - const savedMap = await getMapsSavedObjectLoader().get(this.props.savedMapId); - if (this._isMounted) { - getCoreChrome().docTitle.change(savedMap.title); - if (this.props.savedMapId) { - getCoreChrome().recentlyAccessed.add(savedMap.getFullPath(), savedMap.title, savedMap.id); - } - this.setState({ savedMap }); - } - } catch (err) { - if (this._isMounted) { - this.setState({ failedToLoad: true }); - getToasts().addWarning({ - title: i18n.translate('xpack.maps.loadMap.errorAttemptingToLoadSavedMap', { - defaultMessage: `Unable to load map`, - }), - text: `${err.message}`, - }); - } - } - } - - render() { - const { savedMap, failedToLoad } = this.state; - - if (failedToLoad) { - return ; - } - - return savedMap ? ( - - ) : null; - } -}; diff --git a/x-pack/plugins/maps/public/routing/state_syncing/app_sync.ts b/x-pack/plugins/maps/public/routing/state_syncing/app_sync.ts index b346822913bec..498442040681c 100644 --- a/x-pack/plugins/maps/public/routing/state_syncing/app_sync.ts +++ b/x-pack/plugins/maps/public/routing/state_syncing/app_sync.ts @@ -8,7 +8,7 @@ import { map } from 'rxjs/operators'; import { connectToQueryState, esFilters } from '../../../../../../src/plugins/data/public'; import { syncState, BaseStateContainer } from '../../../../../../src/plugins/kibana_utils/public'; import { getData } from '../../kibana_services'; -import { kbnUrlStateStorage } from '../maps_router'; +import { kbnUrlStateStorage } from '../render_app'; import { AppStateManager } from './app_state_manager'; export function startAppStateSyncing(appStateManager: AppStateManager) { diff --git a/x-pack/plugins/maps/public/routing/state_syncing/global_sync.ts b/x-pack/plugins/maps/public/routing/state_syncing/global_sync.ts index 1e779831c5e0c..3f370d9aa99b2 100644 --- a/x-pack/plugins/maps/public/routing/state_syncing/global_sync.ts +++ b/x-pack/plugins/maps/public/routing/state_syncing/global_sync.ts @@ -6,7 +6,7 @@ import { TimeRange, RefreshInterval, Filter } from 'src/plugins/data/public'; import { syncQueryStateWithUrl } from '../../../../../../src/plugins/data/public'; import { getData } from '../../kibana_services'; -import { kbnUrlStateStorage } from '../maps_router'; +import { kbnUrlStateStorage } from '../render_app'; export interface MapsGlobalState { time?: TimeRange; From 213469d5cd2192f91ab2b1f87c617f03323c6b85 Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Thu, 29 Oct 2020 10:56:17 +0100 Subject: [PATCH 18/80] Properly handle session index initialization failures. (#81894) --- .../server/session_management/session_index.test.ts | 11 +++++++++++ .../server/session_management/session_index.ts | 11 ++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security/server/session_management/session_index.test.ts b/x-pack/plugins/security/server/session_management/session_index.test.ts index f4ff5a8bddb74..cba63412bf502 100644 --- a/x-pack/plugins/security/server/session_management/session_index.test.ts +++ b/x-pack/plugins/security/server/session_management/session_index.test.ts @@ -155,6 +155,17 @@ describe('Session index', () => { await sessionIndex.initialize(); }); + + it('works properly after failure', async () => { + const unexpectedError = new Error('Uh! Oh!'); + mockClusterClient.callAsInternalUser.mockImplementationOnce(() => + Promise.reject(unexpectedError) + ); + mockClusterClient.callAsInternalUser.mockImplementationOnce(() => Promise.resolve(true)); + + await expect(sessionIndex.initialize()).rejects.toBe(unexpectedError); + await expect(sessionIndex.initialize()).resolves.toBe(undefined); + }); }); describe('cleanUp', () => { diff --git a/x-pack/plugins/security/server/session_management/session_index.ts b/x-pack/plugins/security/server/session_management/session_index.ts index 191e71f14d66d..ee503acc0d3a4 100644 --- a/x-pack/plugins/security/server/session_management/session_index.ts +++ b/x-pack/plugins/security/server/session_management/session_index.ts @@ -276,7 +276,7 @@ export class SessionIndex { } const sessionIndexTemplateName = `${this.options.kibanaIndexName}_security_session_index_template_${SESSION_INDEX_TEMPLATE_VERSION}`; - return (this.indexInitialization = new Promise(async (resolve) => { + return (this.indexInitialization = new Promise(async (resolve, reject) => { // Check if required index template exists. let indexTemplateExists = false; try { @@ -288,7 +288,7 @@ export class SessionIndex { this.options.logger.error( `Failed to check if session index template exists: ${err.message}` ); - throw err; + return reject(err); } // Create index template if it doesn't exist. @@ -303,7 +303,7 @@ export class SessionIndex { this.options.logger.debug('Successfully created session index template.'); } catch (err) { this.options.logger.error(`Failed to create session index template: ${err.message}`); - throw err; + return reject(err); } } @@ -316,7 +316,7 @@ export class SessionIndex { }); } catch (err) { this.options.logger.error(`Failed to check if session index exists: ${err.message}`); - throw err; + return reject(err); } // Create index if it doesn't exist. @@ -334,13 +334,14 @@ export class SessionIndex { this.options.logger.debug('Session index already exists.'); } else { this.options.logger.error(`Failed to create session index: ${err.message}`); - throw err; + return reject(err); } } } // Notify any consumers that are awaiting on this promise and immediately reset it. resolve(); + }).finally(() => { this.indexInitialization = undefined; })); } From 66d79ea2bf5c743298e2e71c1fb44caec4920d4a Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Thu, 29 Oct 2020 11:24:10 +0000 Subject: [PATCH 19/80] Reactively disable Task Manager lifecycle when core services become unavailable (#81779) Plugs the Task Manager polling lifecycle into the Kibana Services Status streams in order to ensure we reactively start and stop polling whenever the Elasticsearch or SavedObjects service switch between `available` and `unavailable`. This will prevent Task Manager from polling whenever these services switch to an `unavailable` state. --- .../task_manager/server/monitoring/index.ts | 10 +- .../monitoring/monitoring_stats_stream.ts | 2 + .../monitoring/workload_statistics.test.ts | 48 ++++++++- .../server/monitoring/workload_statistics.ts | 8 +- .../task_manager/server/plugin.test.ts | 100 +++++++++++++++++- x-pack/plugins/task_manager/server/plugin.ts | 48 ++++++--- .../server/polling_lifecycle.mock.ts | 2 - .../server/polling_lifecycle.test.ts | 57 +++++++++- .../task_manager/server/polling_lifecycle.ts | 100 ++++++++++-------- 9 files changed, 301 insertions(+), 74 deletions(-) diff --git a/x-pack/plugins/task_manager/server/monitoring/index.ts b/x-pack/plugins/task_manager/server/monitoring/index.ts index 8e71ce2519a7c..0a4c8c56a5a79 100644 --- a/x-pack/plugins/task_manager/server/monitoring/index.ts +++ b/x-pack/plugins/task_manager/server/monitoring/index.ts @@ -28,12 +28,20 @@ export { export function createMonitoringStats( taskPollingLifecycle: TaskPollingLifecycle, taskStore: TaskStore, + elasticsearchAndSOAvailability$: Observable, config: TaskManagerConfig, managedConfig: ManagedConfiguration, logger: Logger ): Observable { return createMonitoringStatsStream( - createAggregators(taskPollingLifecycle, taskStore, config, managedConfig, logger), + createAggregators( + taskPollingLifecycle, + taskStore, + elasticsearchAndSOAvailability$, + config, + managedConfig, + logger + ), config ); } diff --git a/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.ts b/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.ts index 374660a257c59..524afb8d78e21 100644 --- a/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.ts +++ b/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.ts @@ -63,6 +63,7 @@ export interface RawMonitoringStats { export function createAggregators( taskPollingLifecycle: TaskPollingLifecycle, taskStore: TaskStore, + elasticsearchAndSOAvailability$: Observable, config: TaskManagerConfig, managedConfig: ManagedConfiguration, logger: Logger @@ -72,6 +73,7 @@ export function createAggregators( createTaskRunAggregator(taskPollingLifecycle, config.monitored_stats_running_average_window), createWorkloadAggregator( taskStore, + elasticsearchAndSOAvailability$, config.monitored_aggregated_stats_refresh_rate, config.poll_interval, logger diff --git a/x-pack/plugins/task_manager/server/monitoring/workload_statistics.test.ts b/x-pack/plugins/task_manager/server/monitoring/workload_statistics.test.ts index d9af3307e75cb..cb6e48530b027 100644 --- a/x-pack/plugins/task_manager/server/monitoring/workload_statistics.test.ts +++ b/x-pack/plugins/task_manager/server/monitoring/workload_statistics.test.ts @@ -17,6 +17,8 @@ import { ESSearchResponse } from '../../../apm/typings/elasticsearch'; import { AggregationResultOf } from '../../../apm/typings/elasticsearch/aggregations'; import { times } from 'lodash'; import { taskStoreMock } from '../task_store.mock'; +import { of, Subject } from 'rxjs'; +import { sleep } from '../test_utils'; type MockESResult = ESSearchResponse< ConcreteTaskInstance, @@ -75,6 +77,7 @@ describe('Workload Statistics Aggregator', () => { const workloadAggregator = createWorkloadAggregator( taskStore, + of(true), 10, 3000, loggingSystemMock.create().get() @@ -231,6 +234,7 @@ describe('Workload Statistics Aggregator', () => { const workloadAggregator = createWorkloadAggregator( taskStore, + of(true), 10, 3000, loggingSystemMock.create().get() @@ -252,12 +256,51 @@ describe('Workload Statistics Aggregator', () => { }); }); + test('skips summary of the workload when services are unavailable', async () => { + const taskStore = taskStoreMock.create({}); + taskStore.aggregate.mockResolvedValue(mockAggregatedResult()); + + const availability$ = new Subject(); + + const workloadAggregator = createWorkloadAggregator( + taskStore, + availability$, + 10, + 3000, + loggingSystemMock.create().get() + ); + + return new Promise(async (resolve) => { + workloadAggregator.pipe(first()).subscribe((result) => { + expect(result.key).toEqual('workload'); + expect(result.value).toMatchObject({ + count: 4, + task_types: { + actions_telemetry: { count: 2, status: { idle: 2 } }, + alerting_telemetry: { count: 1, status: { idle: 1 } }, + session_cleanup: { count: 1, status: { idle: 1 } }, + }, + }); + resolve(); + }); + + availability$.next(false); + + await sleep(10); + expect(taskStore.aggregate).not.toHaveBeenCalled(); + await sleep(10); + expect(taskStore.aggregate).not.toHaveBeenCalled(); + availability$.next(true); + }); + }); + test('returns a count of the overdue workload', async () => { const taskStore = taskStoreMock.create({}); taskStore.aggregate.mockResolvedValue(mockAggregatedResult()); const workloadAggregator = createWorkloadAggregator( taskStore, + of(true), 10, 3000, loggingSystemMock.create().get() @@ -280,6 +323,7 @@ describe('Workload Statistics Aggregator', () => { const workloadAggregator = createWorkloadAggregator( taskStore, + of(true), 10, 3000, loggingSystemMock.create().get() @@ -307,6 +351,7 @@ describe('Workload Statistics Aggregator', () => { const workloadAggregator = createWorkloadAggregator( taskStore, + of(true), 60 * 1000, 3000, loggingSystemMock.create().get() @@ -344,6 +389,7 @@ describe('Workload Statistics Aggregator', () => { const workloadAggregator = createWorkloadAggregator( taskStore, + of(true), 15 * 60 * 1000, 3000, loggingSystemMock.create().get() @@ -392,7 +438,7 @@ describe('Workload Statistics Aggregator', () => { }) ); const logger = loggingSystemMock.create().get(); - const workloadAggregator = createWorkloadAggregator(taskStore, 10, 3000, logger); + const workloadAggregator = createWorkloadAggregator(taskStore, of(true), 10, 3000, logger); return new Promise((resolve, reject) => { workloadAggregator.pipe(take(2), bufferCount(2)).subscribe((results) => { diff --git a/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts b/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts index fe70f24684ad9..17448ea412ae6 100644 --- a/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts +++ b/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { timer } from 'rxjs'; -import { mergeMap, map, catchError } from 'rxjs/operators'; +import { combineLatest, Observable, timer } from 'rxjs'; +import { mergeMap, map, filter, catchError } from 'rxjs/operators'; import { Logger } from 'src/core/server'; import { JsonObject } from 'src/plugins/kibana_utils/common'; import { keyBy, mapValues } from 'lodash'; @@ -94,6 +94,7 @@ const MAX_SHCEDULE_DENSITY_BUCKETS = 50; export function createWorkloadAggregator( taskStore: TaskStore, + elasticsearchAndSOAvailability$: Observable, refreshInterval: number, pollInterval: number, logger: Logger @@ -105,7 +106,8 @@ export function createWorkloadAggregator( MAX_SHCEDULE_DENSITY_BUCKETS ); - return timer(0, refreshInterval).pipe( + return combineLatest([timer(0, refreshInterval), elasticsearchAndSOAvailability$]).pipe( + filter(([, areElasticsearchAndSOAvailable]) => areElasticsearchAndSOAvailable), mergeMap(() => taskStore.aggregate({ aggs: { diff --git a/x-pack/plugins/task_manager/server/plugin.test.ts b/x-pack/plugins/task_manager/server/plugin.test.ts index 8388468164a4f..9a1d83f6195ab 100644 --- a/x-pack/plugins/task_manager/server/plugin.test.ts +++ b/x-pack/plugins/task_manager/server/plugin.test.ts @@ -4,9 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { TaskManagerPlugin } from './plugin'; +import { TaskManagerPlugin, getElasticsearchAndSOAvailability } from './plugin'; import { coreMock } from '../../../../src/core/server/mocks'; import { TaskManagerConfig } from './config'; +import { Subject } from 'rxjs'; +import { bufferCount, take } from 'rxjs/operators'; +import { CoreStatus, ServiceStatusLevels } from 'src/core/server'; describe('TaskManagerPlugin', () => { describe('setup', () => { @@ -88,4 +91,99 @@ describe('TaskManagerPlugin', () => { ); }); }); + + describe('getElasticsearchAndSOAvailability', () => { + test('returns true when both services are available', async () => { + const core$ = new Subject(); + + const availability = getElasticsearchAndSOAvailability(core$) + .pipe(take(1), bufferCount(1)) + .toPromise(); + + core$.next(mockCoreStatusAvailability({ elasticsearch: true, savedObjects: true })); + + expect(await availability).toEqual([true]); + }); + + test('returns false when both services are unavailable', async () => { + const core$ = new Subject(); + + const availability = getElasticsearchAndSOAvailability(core$) + .pipe(take(1), bufferCount(1)) + .toPromise(); + + core$.next(mockCoreStatusAvailability({ elasticsearch: false, savedObjects: false })); + + expect(await availability).toEqual([false]); + }); + + test('returns false when one service is unavailable but the other is available', async () => { + const core$ = new Subject(); + + const availability = getElasticsearchAndSOAvailability(core$) + .pipe(take(1), bufferCount(1)) + .toPromise(); + + core$.next(mockCoreStatusAvailability({ elasticsearch: true, savedObjects: false })); + + expect(await availability).toEqual([false]); + }); + + test('shift back and forth between values as status changes', async () => { + const core$ = new Subject(); + + const availability = getElasticsearchAndSOAvailability(core$) + .pipe(take(3), bufferCount(3)) + .toPromise(); + + core$.next(mockCoreStatusAvailability({ elasticsearch: true, savedObjects: false })); + + core$.next(mockCoreStatusAvailability({ elasticsearch: true, savedObjects: true })); + + core$.next(mockCoreStatusAvailability({ elasticsearch: false, savedObjects: false })); + + expect(await availability).toEqual([false, true, false]); + }); + + test(`skips values when the status hasn't changed`, async () => { + const core$ = new Subject(); + + const availability = getElasticsearchAndSOAvailability(core$) + .pipe(take(3), bufferCount(3)) + .toPromise(); + + core$.next(mockCoreStatusAvailability({ elasticsearch: true, savedObjects: false })); + + // still false, so shouldn't emit a second time + core$.next(mockCoreStatusAvailability({ elasticsearch: false, savedObjects: true })); + + core$.next(mockCoreStatusAvailability({ elasticsearch: true, savedObjects: true })); + + // shouldn't emit as already true + core$.next(mockCoreStatusAvailability({ elasticsearch: true, savedObjects: true })); + + core$.next(mockCoreStatusAvailability({ elasticsearch: false, savedObjects: false })); + + expect(await availability).toEqual([false, true, false]); + }); + }); }); + +function mockCoreStatusAvailability({ + elasticsearch, + savedObjects, +}: { + elasticsearch: boolean; + savedObjects: boolean; +}) { + return { + elasticsearch: { + level: elasticsearch ? ServiceStatusLevels.available : ServiceStatusLevels.unavailable, + summary: '', + }, + savedObjects: { + level: savedObjects ? ServiceStatusLevels.available : ServiceStatusLevels.unavailable, + summary: '', + }, + }; +} diff --git a/x-pack/plugins/task_manager/server/plugin.ts b/x-pack/plugins/task_manager/server/plugin.ts index 0e7abb817490a..70688cd169d7e 100644 --- a/x-pack/plugins/task_manager/server/plugin.ts +++ b/x-pack/plugins/task_manager/server/plugin.ts @@ -3,9 +3,17 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { PluginInitializerContext, Plugin, CoreSetup, Logger, CoreStart } from 'src/core/server'; -import { combineLatest, Subject } from 'rxjs'; -import { first, map } from 'rxjs/operators'; +import { combineLatest, Observable, Subject } from 'rxjs'; +import { first, map, distinctUntilChanged } from 'rxjs/operators'; +import { + PluginInitializerContext, + Plugin, + CoreSetup, + Logger, + CoreStart, + ServiceStatusLevels, + CoreStatus, +} from '../../../../src/core/server'; import { TaskDefinition } from './task'; import { TaskPollingLifecycle } from './polling_lifecycle'; import { TaskManagerConfig } from './config'; @@ -37,6 +45,7 @@ export class TaskManagerPlugin private logger: Logger; private definitions: TaskTypeDictionary; private middleware: Middleware = createInitialMiddleware(); + private elasticsearchAndSOAvailability$?: Observable; private monitoringStats$ = new Subject(); constructor(private readonly initContext: PluginInitializerContext) { @@ -51,6 +60,8 @@ export class TaskManagerPlugin .pipe(first()) .toPromise(); + this.elasticsearchAndSOAvailability$ = getElasticsearchAndSOAvailability(core.status.core$); + setupSavedObjects(core.savedObjects, this.config); this.taskManagerId = this.initContext.env.instanceUuid; @@ -115,19 +126,20 @@ export class TaskManagerPlugin startingPollInterval: this.config!.poll_interval, }); - const taskPollingLifecycle = new TaskPollingLifecycle({ + this.taskPollingLifecycle = new TaskPollingLifecycle({ config: this.config!, definitions: this.definitions, logger: this.logger, taskStore, middleware: this.middleware, + elasticsearchAndSOAvailability$: this.elasticsearchAndSOAvailability$!, ...managedConfiguration, }); - this.taskPollingLifecycle = taskPollingLifecycle; createMonitoringStats( - taskPollingLifecycle, + this.taskPollingLifecycle, taskStore, + this.elasticsearchAndSOAvailability$!, this.config!, managedConfiguration, this.logger @@ -137,12 +149,9 @@ export class TaskManagerPlugin logger: this.logger, taskStore, middleware: this.middleware, - taskPollingLifecycle, + taskPollingLifecycle: this.taskPollingLifecycle, }); - // start polling for work - taskPollingLifecycle.start(); - return { fetch: (opts: SearchOpts): Promise => taskStore.fetch(opts), get: (id: string) => taskStore.get(id), @@ -153,12 +162,6 @@ export class TaskManagerPlugin }; } - public stop() { - if (this.taskPollingLifecycle) { - this.taskPollingLifecycle.stop(); - } - } - /** * Ensures task manager hasn't started * @@ -171,3 +174,16 @@ export class TaskManagerPlugin } } } + +export function getElasticsearchAndSOAvailability( + core$: Observable +): Observable { + return core$.pipe( + map( + ({ elasticsearch, savedObjects }) => + elasticsearch.level === ServiceStatusLevels.available && + savedObjects.level === ServiceStatusLevels.available + ), + distinctUntilChanged() + ); +} diff --git a/x-pack/plugins/task_manager/server/polling_lifecycle.mock.ts b/x-pack/plugins/task_manager/server/polling_lifecycle.mock.ts index 9df1e06165bc6..286e29194d6e6 100644 --- a/x-pack/plugins/task_manager/server/polling_lifecycle.mock.ts +++ b/x-pack/plugins/task_manager/server/polling_lifecycle.mock.ts @@ -10,7 +10,6 @@ import { of, Observable } from 'rxjs'; export const taskPollingLifecycleMock = { create(opts: { isStarted?: boolean; events$?: Observable }) { return ({ - start: jest.fn(), attemptToRun: jest.fn(), get isStarted() { return opts.isStarted ?? true; @@ -18,7 +17,6 @@ export const taskPollingLifecycleMock = { get events() { return opts.events$ ?? of(); }, - stop: jest.fn(), } as unknown) as jest.Mocked; }, }; diff --git a/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts b/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts index 5f2e774177fd4..0f807976970cf 100644 --- a/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts +++ b/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts @@ -6,7 +6,7 @@ import _ from 'lodash'; import sinon from 'sinon'; -import { of } from 'rxjs'; +import { of, Subject } from 'rxjs'; import { TaskPollingLifecycle, claimAvailableTasks } from './polling_lifecycle'; import { createInitialMiddleware } from './lib/middleware'; @@ -55,15 +55,64 @@ describe('TaskPollingLifecycle', () => { afterEach(() => clock.restore()); describe('start', () => { - test('begins polling once start is called', () => { - const taskManager = new TaskPollingLifecycle(taskManagerOpts); + test('begins polling once the ES and SavedObjects services are available', () => { + const elasticsearchAndSOAvailability$ = new Subject(); + new TaskPollingLifecycle({ + elasticsearchAndSOAvailability$, + ...taskManagerOpts, + }); + + clock.tick(150); + expect(mockTaskStore.claimAvailableTasks).not.toHaveBeenCalled(); + + elasticsearchAndSOAvailability$.next(true); + + clock.tick(150); + expect(mockTaskStore.claimAvailableTasks).toHaveBeenCalled(); + }); + }); + + describe('stop', () => { + test('stops polling once the ES and SavedObjects services become unavailable', () => { + const elasticsearchAndSOAvailability$ = new Subject(); + new TaskPollingLifecycle({ + elasticsearchAndSOAvailability$, + ...taskManagerOpts, + }); + + elasticsearchAndSOAvailability$.next(true); + + clock.tick(150); + expect(mockTaskStore.claimAvailableTasks).toHaveBeenCalled(); + elasticsearchAndSOAvailability$.next(false); + + mockTaskStore.claimAvailableTasks.mockClear(); clock.tick(150); expect(mockTaskStore.claimAvailableTasks).not.toHaveBeenCalled(); + }); + + test('restarts polling once the ES and SavedObjects services become available again', () => { + const elasticsearchAndSOAvailability$ = new Subject(); + new TaskPollingLifecycle({ + elasticsearchAndSOAvailability$, + ...taskManagerOpts, + }); + + elasticsearchAndSOAvailability$.next(true); - taskManager.start(); + clock.tick(150); + expect(mockTaskStore.claimAvailableTasks).toHaveBeenCalled(); + elasticsearchAndSOAvailability$.next(false); + mockTaskStore.claimAvailableTasks.mockClear(); clock.tick(150); + + expect(mockTaskStore.claimAvailableTasks).not.toHaveBeenCalled(); + + elasticsearchAndSOAvailability$.next(true); + clock.tick(150); + expect(mockTaskStore.claimAvailableTasks).toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/task_manager/server/polling_lifecycle.ts b/x-pack/plugins/task_manager/server/polling_lifecycle.ts index ba19cb63fffa2..ccba750401f28 100644 --- a/x-pack/plugins/task_manager/server/polling_lifecycle.ts +++ b/x-pack/plugins/task_manager/server/polling_lifecycle.ts @@ -48,6 +48,7 @@ export type TaskPollingLifecycleOpts = { taskStore: TaskStore; config: TaskManagerConfig; middleware: Middleware; + elasticsearchAndSOAvailability$: Observable; } & ManagedConfiguration; export type TaskLifecycleEvent = @@ -72,8 +73,6 @@ export class TaskPollingLifecycle { private events$ = new Subject(); // all on-demand requests we wish to pipe into the poller private claimRequests$ = new Subject>(); - // the task poller that polls for work on fixed intervals and on demand - private poller$: Observable>>; // our subscription to the poller private pollingSubscription: Subscription = Subscription.EMPTY; @@ -84,36 +83,50 @@ export class TaskPollingLifecycle { * enabling the task manipulation methods, and beginning the background polling * mechanism. */ - constructor(opts: TaskPollingLifecycleOpts) { - const { logger, middleware, maxWorkersConfiguration$, pollIntervalConfiguration$ } = opts; + constructor({ + logger, + middleware, + maxWorkersConfiguration$, + pollIntervalConfiguration$, + // Elasticsearch and SavedObjects availability status + elasticsearchAndSOAvailability$, + config, + taskStore, + definitions, + }: TaskPollingLifecycleOpts) { this.logger = logger; this.middleware = middleware; + this.definitions = definitions; + this.store = taskStore; - this.definitions = opts.definitions; - this.store = opts.taskStore; // pipe store events into the lifecycle event stream this.store.events.subscribe((event) => this.events$.next(event)); this.bufferedStore = new BufferedTaskStore(this.store, { - bufferMaxOperations: opts.config.max_workers, - logger: this.logger, + bufferMaxOperations: config.max_workers, + logger, }); this.pool = new TaskPool({ - logger: this.logger, + logger, maxWorkers$: maxWorkersConfiguration$, }); const { max_poll_inactivity_cycles: maxPollInactivityCycles, poll_interval: pollInterval, - } = opts.config; - this.poller$ = createObservableMonitor>, Error>( + } = config; + + // the task poller that polls for work on fixed intervals and on demand + const poller$: Observable + >> = createObservableMonitor>, Error>( () => createTaskPoller({ - logger: this.logger, + logger, pollInterval$: pollIntervalConfiguration$, - bufferCapacity: opts.config.request_capacity, + bufferCapacity: config.request_capacity, getCapacity: () => this.pool.availableWorkers, pollRequests$: this.claimRequests$, work: this.pollForWork, @@ -133,10 +146,20 @@ export class TaskPollingLifecycle { // operation than just timing out the `work` internally) inactivityTimeout: pollInterval * (maxPollInactivityCycles + 1), onError: (error) => { - this.logger.error(`[Task Poller Monitor]: ${error.message}`); + logger.error(`[Task Poller Monitor]: ${error.message}`); }, } ); + + elasticsearchAndSOAvailability$.subscribe((areESAndSOAvailable) => { + if (areESAndSOAvailable && !this.isStarted) { + // start polling for work + this.pollingSubscription = this.subscribeToPoller(poller$); + } else if (!areESAndSOAvailable && this.isStarted) { + this.pollingSubscription.unsubscribe(); + this.pool.cancelRunningTasks(); + } + }); } public get events(): Observable { @@ -184,39 +207,24 @@ export class TaskPollingLifecycle { ); }; - /** - * Starts up the task manager and starts picking up tasks. - */ - public start() { - if (!this.isStarted) { - this.pollingSubscription = this.poller$ - .pipe( - tap( - mapErr((error: PollingError) => { - if (error.type === PollingErrorType.RequestCapacityReached) { - pipe( - error.data, - mapOptional((id) => this.emitEvent(asTaskRunRequestEvent(id, asErr(error)))) - ); - } - this.logger.error(error.message); - }) - ) + private subscribeToPoller(poller$: Observable>>) { + return poller$ + .pipe( + tap( + mapErr((error: PollingError) => { + if (error.type === PollingErrorType.RequestCapacityReached) { + pipe( + error.data, + mapOptional((id) => this.emitEvent(asTaskRunRequestEvent(id, asErr(error)))) + ); + } + this.logger.error(error.message); + }) ) - .subscribe((event: Result>) => { - this.emitEvent(asTaskPollingCycleEvent(event)); - }); - } - } - - /** - * Stops the task manager and cancels running tasks. - */ - public stop() { - if (this.isStarted) { - this.pollingSubscription.unsubscribe(); - this.pool.cancelRunningTasks(); - } + ) + .subscribe((event: Result>) => { + this.emitEvent(asTaskPollingCycleEvent(event)); + }); } } From d6b006ff2f7383e31c2f0ace0e91ca2f4eea007f Mon Sep 17 00:00:00 2001 From: ymao1 Date: Thu, 29 Oct 2020 07:40:18 -0400 Subject: [PATCH 20/80] [Alerting UI] Removing beta labels (#81919) * Removing beta labels * i18n fix * Fixing test --- .../translations/translations/ja-JP.json | 9 ------ .../translations/translations/zh-CN.json | 9 ------ .../public/application/home.tsx | 17 ----------- .../connector_add_flyout.tsx | 30 ------------------- .../connector_add_modal.tsx | 17 +---------- .../connector_edit_flyout.tsx | 29 ------------------ .../components/alert_details.test.tsx | 26 +--------------- .../components/alert_details.tsx | 17 ----------- .../sections/alert_form/alert_add.tsx | 24 +-------------- .../sections/alert_form/alert_edit.tsx | 16 ---------- .../apps/triggers_actions_ui/home_page.ts | 2 +- 11 files changed, 4 insertions(+), 192 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 58ee36507cb73..1492c8a03906a 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -20199,7 +20199,6 @@ "xpack.triggersActionsUI.geoThreshold.whenEntityLabel": "エンティティ", "xpack.triggersActionsUI.home.alertsTabTitle": "アラート", "xpack.triggersActionsUI.home.appTitle": "アラートとアクション", - "xpack.triggersActionsUI.home.betaBadgeTooltipContent": "{pluginName} はベータ段階で、変更される可能性があります。デザインとコードはオフィシャル GA 機能よりも完成度が低く、現状のまま保証なしで提供されています。ベータ機能にはオフィシャル GA 機能の SLA が適用されません。", "xpack.triggersActionsUI.home.breadcrumbTitle": "アラートとアクション", "xpack.triggersActionsUI.home.connectorsTabTitle": "コネクター", "xpack.triggersActionsUI.home.sectionDescription": "アラートを使用して条件を検出し、コネクターを使用してアクションを実行します。", @@ -20250,18 +20249,14 @@ "xpack.triggersActionsUI.sections.addAlert.error.requiredTimeFieldText": "時間フィールドが必要です。", "xpack.triggersActionsUI.sections.addAlert.error.requiredTimeWindowSizeText": "時間ウィンドウサイズが必要です。", "xpack.triggersActionsUI.sections.addAlert.error.requiredtTermFieldText": "用語フィールドが必要です。", - "xpack.triggersActionsUI.sections.addConnectorForm.betaBadgeTooltipContent": "{pluginName} はベータ段階で、変更される可能性があります。デザインとコードはオフィシャル GA 機能よりも完成度が低く、現状のまま保証なしで提供されています。ベータ機能にはオフィシャル GA 機能の SLA が適用されません。", "xpack.triggersActionsUI.sections.addConnectorForm.flyoutTitle": "{actionTypeName} コネクタ", "xpack.triggersActionsUI.sections.addConnectorForm.selectConnectorFlyoutTitle": "コネクターを選択", "xpack.triggersActionsUI.sections.addConnectorForm.updateErrorNotificationText": "コネクターを作成できません。", "xpack.triggersActionsUI.sections.addConnectorForm.updateSuccessNotificationText": "「{connectorName}」を作成しました", - "xpack.triggersActionsUI.sections.addFlyout.betaBadgeTooltipContent": "{pluginName} はベータ段階で、変更される可能性があります。デザインとコードはオフィシャル GA 機能よりも完成度が低く、現状のまま保証なしで提供されています。ベータ機能にはオフィシャル GA 機能の SLA が適用されません。", - "xpack.triggersActionsUI.sections.addModalConnectorForm.betaBadgeTooltipContent": "{pluginName} はベータ段階で、変更される可能性があります。デザインとコードはオフィシャル GA 機能よりも完成度が低く、現状のまま保証なしで提供されています。ベータ機能にはオフィシャル GA 機能の SLA が適用されません。", "xpack.triggersActionsUI.sections.addModalConnectorForm.cancelButtonLabel": "キャンセル", "xpack.triggersActionsUI.sections.addModalConnectorForm.flyoutTitle": "{actionTypeName} コネクター", "xpack.triggersActionsUI.sections.addModalConnectorForm.saveButtonLabel": "保存", "xpack.triggersActionsUI.sections.addModalConnectorForm.updateSuccessNotificationText": "「{connectorName}」を作成しました", - "xpack.triggersActionsUI.sections.alertAdd.betaBadgeTooltipContent": "{pluginName} はベータ段階で、変更される可能性があります。デザインとコードはオフィシャル GA 機能よりも完成度が低く、現状のまま保証なしで提供されています。ベータ機能にはオフィシャル GA 機能の SLA が適用されません。", "xpack.triggersActionsUI.sections.alertAdd.conditionPrompt": "条件を定義してください", "xpack.triggersActionsUI.sections.alertAdd.errorLoadingAlertVisualizationTitle": "アラートビジュアライゼーションを読み込めません", "xpack.triggersActionsUI.sections.alertAdd.flyoutTitle": "アラートの作成", @@ -20291,7 +20286,6 @@ "xpack.triggersActionsUI.sections.alertDetails.alertInstancesList.columns.status": "ステータス", "xpack.triggersActionsUI.sections.alertDetails.alertInstancesList.status.active": "アクティブ", "xpack.triggersActionsUI.sections.alertDetails.alertInstancesList.status.inactive": "OK", - "xpack.triggersActionsUI.sections.alertDetails.betaBadgeTooltipContent": "{pluginName} はベータ段階で、変更される可能性があります。デザインとコードはオフィシャル GA 機能よりも完成度が低く、現状のまま保証なしで提供されています。ベータ機能にはオフィシャル GA 機能の SLA が適用されません。", "xpack.triggersActionsUI.sections.alertDetails.collapsedItemActons.disableTitle": "無効にする", "xpack.triggersActionsUI.sections.alertDetails.collapsedItemActons.muteTitle": "ミュート", "xpack.triggersActionsUI.sections.alertDetails.dismissButtonTitle": "閉じる", @@ -20299,7 +20293,6 @@ "xpack.triggersActionsUI.sections.alertDetails.unableToLoadAlertInstanceSummaryMessage": "アラートインスタンス概要を読み込めません:{message}", "xpack.triggersActionsUI.sections.alertDetails.unableToLoadAlertMessage": "アラートを読み込めません: {message}", "xpack.triggersActionsUI.sections.alertDetails.viewAlertInAppButtonLabel": "アプリで表示", - "xpack.triggersActionsUI.sections.alertEdit.betaBadgeTooltipContent": "{pluginName} はベータ段階で、変更される可能性があります。デザインとコードはオフィシャル GA 機能よりも完成度が低く、現状のまま保証なしで提供されています。ベータ機能にはオフィシャル GA 機能の SLA が適用されません。", "xpack.triggersActionsUI.sections.alertEdit.cancelButtonLabel": "キャンセル", "xpack.triggersActionsUI.sections.alertEdit.disabledActionsWarningTitle": "このアラートには無効なアクションがあります", "xpack.triggersActionsUI.sections.alertEdit.flyoutTitle": "アラートを編集", @@ -20412,7 +20405,6 @@ "xpack.triggersActionsUI.sections.builtinActionTypes.emailAction.subjectTextFieldLabel": "件名", "xpack.triggersActionsUI.sections.builtinActionTypes.emailAction.userTextFieldLabel": "ユーザー名", "xpack.triggersActionsUI.sections.editConnectorForm.actionTypeDescription": "{actionDescription}", - "xpack.triggersActionsUI.sections.editConnectorForm.betaBadgeTooltipContent": "{pluginName} はベータ段階で、変更される可能性があります。デザインとコードはオフィシャル GA 機能よりも完成度が低く、現状のまま保証なしで提供されています。ベータ機能にはオフィシャル GA 機能の SLA が適用されません。", "xpack.triggersActionsUI.sections.editConnectorForm.cancelButtonLabel": "キャンセル", "xpack.triggersActionsUI.sections.editConnectorForm.descriptionText": "このコネクターは読み取り専用です。", "xpack.triggersActionsUI.sections.editConnectorForm.flyoutPreconfiguredTitle": "コネクターを編集", @@ -20422,7 +20414,6 @@ "xpack.triggersActionsUI.sections.editConnectorForm.tabText": "構成", "xpack.triggersActionsUI.sections.editConnectorForm.updateErrorNotificationText": "コネクターを更新できません。", "xpack.triggersActionsUI.sections.editConnectorForm.updateSuccessNotificationText": "「{connectorName}」を更新しました", - "xpack.triggersActionsUI.sections.preconfiguredConnectorForm.betaBadgeTooltipContent": "{pluginName}はベータ段階で、変更される可能性があります。デザインとコードはオフィシャルGA機能よりも完成度が低く、現状のまま保証なしで提供されています。ベータ機能にはオフィシャルGA機能のSLAが適用されません。", "xpack.triggersActionsUI.sections.preconfiguredConnectorForm.flyoutTitle": "{connectorName}", "xpack.triggersActionsUI.sections.preconfiguredConnectorForm.tooltipContent": "このコネクターはあらかじめ構成されているため、編集できません。", "xpack.triggersActionsUI.sections.testConnectorForm.awaitingExecutionDescription": "アクションを実行すると、結果がここに表示されます。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 832b716934bca..be5bcd3cf0543 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -20218,7 +20218,6 @@ "xpack.triggersActionsUI.geoThreshold.whenEntityLabel": "当实体", "xpack.triggersActionsUI.home.alertsTabTitle": "告警", "xpack.triggersActionsUI.home.appTitle": "告警和操作", - "xpack.triggersActionsUI.home.betaBadgeTooltipContent": "{pluginName} 为公测版,可能会进行更改。设计和代码相对于正式发行版功能还不够成熟,将按原样提供,且不提供任何保证。公测版功能不受正式发行版功能支持 SLA 的约束。", "xpack.triggersActionsUI.home.breadcrumbTitle": "告警和操作", "xpack.triggersActionsUI.home.connectorsTabTitle": "连接器", "xpack.triggersActionsUI.home.sectionDescription": "使用告警检测条件,并使用连接器采取操作。", @@ -20270,18 +20269,14 @@ "xpack.triggersActionsUI.sections.addAlert.error.requiredTimeFieldText": "时间字段必填。", "xpack.triggersActionsUI.sections.addAlert.error.requiredTimeWindowSizeText": "“时间窗大小”必填。", "xpack.triggersActionsUI.sections.addAlert.error.requiredtTermFieldText": "词字段必填。", - "xpack.triggersActionsUI.sections.addConnectorForm.betaBadgeTooltipContent": "{pluginName} 为公测版,可能会进行更改。设计和代码相对于正式发行版功能还不够成熟,将按原样提供,且不提供任何保证。公测版功能不受正式发行版功能支持 SLA 的约束。", "xpack.triggersActionsUI.sections.addConnectorForm.flyoutTitle": "{actionTypeName} 连接器", "xpack.triggersActionsUI.sections.addConnectorForm.selectConnectorFlyoutTitle": "选择连接器", "xpack.triggersActionsUI.sections.addConnectorForm.updateErrorNotificationText": "无法创建连接器。", "xpack.triggersActionsUI.sections.addConnectorForm.updateSuccessNotificationText": "已创建“{connectorName}”", - "xpack.triggersActionsUI.sections.addFlyout.betaBadgeTooltipContent": "{pluginName} 为公测版,可能会进行更改。设计和代码相对于正式发行版功能还不够成熟,将按原样提供,且不提供任何保证。公测版功能不受正式发行版功能支持 SLA 的约束。", - "xpack.triggersActionsUI.sections.addModalConnectorForm.betaBadgeTooltipContent": "{pluginName} 为公测版,可能会进行更改。设计和代码相对于正式发行版功能还不够成熟,将按原样提供,且不提供任何保证。公测版功能不受正式发行版功能支持 SLA 的约束。", "xpack.triggersActionsUI.sections.addModalConnectorForm.cancelButtonLabel": "取消", "xpack.triggersActionsUI.sections.addModalConnectorForm.flyoutTitle": "{actionTypeName} 连接器", "xpack.triggersActionsUI.sections.addModalConnectorForm.saveButtonLabel": "保存", "xpack.triggersActionsUI.sections.addModalConnectorForm.updateSuccessNotificationText": "已创建“{connectorName}”", - "xpack.triggersActionsUI.sections.alertAdd.betaBadgeTooltipContent": "{pluginName} 为公测版,可能会进行更改。设计和代码相对于正式发行版功能还不够成熟,将按原样提供,且不提供任何保证。公测版功能不受正式发行版功能支持 SLA 的约束。", "xpack.triggersActionsUI.sections.alertAdd.conditionPrompt": "定义条件", "xpack.triggersActionsUI.sections.alertAdd.errorLoadingAlertVisualizationTitle": "无法加载告警可视化", "xpack.triggersActionsUI.sections.alertAdd.flyoutTitle": "创建告警", @@ -20311,7 +20306,6 @@ "xpack.triggersActionsUI.sections.alertDetails.alertInstancesList.columns.status": "状态", "xpack.triggersActionsUI.sections.alertDetails.alertInstancesList.status.active": "活动", "xpack.triggersActionsUI.sections.alertDetails.alertInstancesList.status.inactive": "确定", - "xpack.triggersActionsUI.sections.alertDetails.betaBadgeTooltipContent": "{pluginName} 为公测版,可能会进行更改。设计和代码相对于正式发行版功能还不够成熟,将按原样提供,且不提供任何保证。公测版功能不受正式发行版功能支持 SLA 的约束。", "xpack.triggersActionsUI.sections.alertDetails.collapsedItemActons.disableTitle": "禁用", "xpack.triggersActionsUI.sections.alertDetails.collapsedItemActons.muteTitle": "静音", "xpack.triggersActionsUI.sections.alertDetails.dismissButtonTitle": "关闭", @@ -20319,7 +20313,6 @@ "xpack.triggersActionsUI.sections.alertDetails.unableToLoadAlertInstanceSummaryMessage": "无法加载告警实例摘要:{message}", "xpack.triggersActionsUI.sections.alertDetails.unableToLoadAlertMessage": "无法加载告警:{message}", "xpack.triggersActionsUI.sections.alertDetails.viewAlertInAppButtonLabel": "在应用中查看", - "xpack.triggersActionsUI.sections.alertEdit.betaBadgeTooltipContent": "{pluginName} 为公测版,可能会进行更改。设计和代码相对于正式发行版功能还不够成熟,将按原样提供,且不提供任何保证。公测版功能不受正式发行版功能支持 SLA 的约束。", "xpack.triggersActionsUI.sections.alertEdit.cancelButtonLabel": "取消", "xpack.triggersActionsUI.sections.alertEdit.disabledActionsWarningTitle": "此告警具有已禁用的操作", "xpack.triggersActionsUI.sections.alertEdit.flyoutTitle": "编辑告警", @@ -20432,7 +20425,6 @@ "xpack.triggersActionsUI.sections.builtinActionTypes.emailAction.subjectTextFieldLabel": "主题", "xpack.triggersActionsUI.sections.builtinActionTypes.emailAction.userTextFieldLabel": "用户名", "xpack.triggersActionsUI.sections.editConnectorForm.actionTypeDescription": "{actionDescription}", - "xpack.triggersActionsUI.sections.editConnectorForm.betaBadgeTooltipContent": "{pluginName} 为公测版,可能会进行更改。设计和代码相对于正式发行版功能还不够成熟,将按原样提供,且不提供任何保证。公测版功能不受正式发行版功能支持 SLA 的约束。", "xpack.triggersActionsUI.sections.editConnectorForm.cancelButtonLabel": "取消", "xpack.triggersActionsUI.sections.editConnectorForm.descriptionText": "此连接器为只读。", "xpack.triggersActionsUI.sections.editConnectorForm.flyoutPreconfiguredTitle": "编辑连接器", @@ -20442,7 +20434,6 @@ "xpack.triggersActionsUI.sections.editConnectorForm.tabText": "配置", "xpack.triggersActionsUI.sections.editConnectorForm.updateErrorNotificationText": "无法更新连接器。", "xpack.triggersActionsUI.sections.editConnectorForm.updateSuccessNotificationText": "已更新“{connectorName}”", - "xpack.triggersActionsUI.sections.preconfiguredConnectorForm.betaBadgeTooltipContent": "{pluginName} 为公测版,可能会进行更改。设计和代码相对于正式发行版功能还不够成熟,将按原样提供,且不提供任何保证。公测版功能不受正式发行版功能支持 SLA 的约束。", "xpack.triggersActionsUI.sections.preconfiguredConnectorForm.flyoutTitle": "{connectorName}", "xpack.triggersActionsUI.sections.preconfiguredConnectorForm.tooltipContent": "这是预配置连接器,无法编辑", "xpack.triggersActionsUI.sections.testConnectorForm.awaitingExecutionDescription": "执行该操作时,结果将显示在此处。", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/home.tsx b/x-pack/plugins/triggers_actions_ui/public/application/home.tsx index f009a04d40978..482b38ffc0d68 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/home.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/home.tsx @@ -16,11 +16,9 @@ import { EuiTab, EuiTabs, EuiTitle, - EuiBetaBadge, EuiText, } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; import { Section, routeToConnectors, routeToAlerts } from './constants'; import { getAlertingSectionBreadcrumb } from './lib/breadcrumb'; import { getCurrentDocTitle } from './lib/doc_title'; @@ -29,7 +27,6 @@ import { hasShowActionsCapability } from './lib/capabilities'; import { ActionsConnectorsList } from './sections/actions_connectors_list/components/actions_connectors_list'; import { AlertsList } from './sections/alerts_list/components/alerts_list'; -import { PLUGIN } from './constants/plugin'; import { HealthCheck } from './components/health_check'; import { HealthContextProvider } from './context/health_context'; @@ -91,20 +88,6 @@ export const TriggersActionsUIHome: React.FunctionComponent -   - diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx index 060a751677de0..2e222884dab50 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx @@ -17,7 +17,6 @@ import { EuiButtonEmpty, EuiButton, EuiFlyoutBody, - EuiBetaBadge, EuiCallOut, EuiSpacer, } from '@elastic/eui'; @@ -31,7 +30,6 @@ import { hasSaveActionsCapability } from '../../lib/capabilities'; import { createActionConnector } from '../../lib/action_connector_api'; import { useActionsConnectorsContext } from '../../context/actions_connectors_context'; import { VIEW_LICENSE_OPTIONS_LINK } from '../../../common/constants'; -import { PLUGIN } from '../../constants/plugin'; export interface ConnectorAddFlyoutProps { addFlyoutVisible: boolean; @@ -189,20 +187,6 @@ export const ConnectorAddFlyout = ({ actionTypeName: actionType.name, }} /> -   - @@ -216,20 +200,6 @@ export const ConnectorAddFlyout = ({ defaultMessage="Select a connector" id="xpack.triggersActionsUI.sections.addConnectorForm.selectConnectorFlyoutTitle" /> -   - )} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx index 90abb986517d4..d7ca91218d4dd 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx @@ -5,7 +5,7 @@ */ import React, { useCallback, useReducer, useState } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiTitle, EuiFlexItem, EuiIcon, EuiFlexGroup, EuiBetaBadge } from '@elastic/eui'; +import { EuiTitle, EuiFlexItem, EuiIcon, EuiFlexGroup } from '@elastic/eui'; import { EuiModal, EuiButton, @@ -24,7 +24,6 @@ import { connectorReducer } from './connector_reducer'; import { createActionConnector } from '../../lib/action_connector_api'; import { TypeRegistry } from '../../type_registry'; import './connector_add_modal.scss'; -import { PLUGIN } from '../../constants/plugin'; import { hasSaveActionsCapability } from '../../lib/capabilities'; interface ConnectorAddModalProps { @@ -135,20 +134,6 @@ export const ConnectorAddModal = ({ actionTypeName: actionType.name, }} /> -   -
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx index 4d8981f25aedc..e89eb8c95fbab 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx @@ -31,7 +31,6 @@ import { connectorReducer } from './connector_reducer'; import { updateActionConnector, executeAction } from '../../lib/action_connector_api'; import { hasSaveActionsCapability } from '../../lib/capabilities'; import { useActionsConnectorsContext } from '../../context/actions_connectors_context'; -import { PLUGIN } from '../../constants/plugin'; import { ActionTypeExecutorResult, isActionTypeExecutorResult, @@ -156,20 +155,6 @@ export const ConnectorEditFlyout = ({ } )} /> -   - @@ -187,20 +172,6 @@ export const ConnectorEditFlyout = ({ defaultMessage="Edit connector" id="xpack.triggersActionsUI.sections.editConnectorForm.flyoutPreconfiguredTitle" /> -   - ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.test.tsx index 51c3e030f44eb..662db81101eee 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.test.tsx @@ -8,18 +8,8 @@ import uuid from 'uuid'; import { shallow } from 'enzyme'; import { AlertDetails } from './alert_details'; import { Alert, ActionType, ValidationResult } from '../../../../types'; -import { - EuiTitle, - EuiBadge, - EuiFlexItem, - EuiSwitch, - EuiBetaBadge, - EuiButtonEmpty, - EuiText, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; +import { EuiTitle, EuiBadge, EuiFlexItem, EuiSwitch, EuiButtonEmpty, EuiText } from '@elastic/eui'; import { ViewInApp } from './view_in_app'; -import { PLUGIN } from '../../../constants/plugin'; import { coreMock } from 'src/core/public/mocks'; import { ALERTS_FEATURE_ID } from '../../../../../../alerts/common'; @@ -104,20 +94,6 @@ describe('alert_details', () => {

{alert.name} -   -

) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx index 0af01114731a3..1272024557bb6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx @@ -22,12 +22,10 @@ import { EuiSwitch, EuiCallOut, EuiSpacer, - EuiBetaBadge, EuiButtonEmpty, EuiButton, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; import { useAppDependencies } from '../../../app_context'; import { hasAllPrivilege, hasExecuteActionsCapability } from '../../../lib/capabilities'; import { getAlertingSectionBreadcrumb, getAlertDetailsBreadcrumb } from '../../../lib/breadcrumb'; @@ -39,7 +37,6 @@ import { } from '../../common/components/with_bulk_alert_api_operations'; import { AlertInstancesRouteWithApi } from './alert_instances_route'; import { ViewInApp } from './view_in_app'; -import { PLUGIN } from '../../../constants/plugin'; import { AlertEdit } from '../../alert_form'; import { AlertsContextProvider } from '../../../context/alerts_context'; import { routeToAlertDetails } from '../../../constants'; @@ -130,20 +127,6 @@ export const AlertDetails: React.FunctionComponent = ({

{alert.name} -   -

diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx index 763462ba6ebf4..89deb4b26f012 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.tsx @@ -6,14 +6,7 @@ import React, { useCallback, useReducer, useState, useEffect } from 'react'; import { isObject } from 'lodash'; import { FormattedMessage } from '@kbn/i18n/react'; -import { - EuiTitle, - EuiFlyoutHeader, - EuiFlyout, - EuiFlyoutBody, - EuiPortal, - EuiBetaBadge, -} from '@elastic/eui'; +import { EuiTitle, EuiFlyoutHeader, EuiFlyout, EuiFlyoutBody, EuiPortal } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useAlertsContext } from '../../context/alerts_context'; import { Alert, AlertAction, IErrorObject } from '../../../types'; @@ -21,7 +14,6 @@ import { AlertForm, validateBaseProperties } from './alert_form'; import { alertReducer } from './alert_reducer'; import { createAlert } from '../../lib/alert_api'; import { HealthCheck } from '../../components/health_check'; -import { PLUGIN } from '../../constants/plugin'; import { ConfirmAlertSave } from './confirm_alert_save'; import { hasShowActionsCapability } from '../../lib/capabilities'; import AlertAddFooter from './alert_add_footer'; @@ -163,20 +155,6 @@ export const AlertAdd = ({ defaultMessage="Create alert" id="xpack.triggersActionsUI.sections.alertAdd.flyoutTitle" /> -   - diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx index 0435a4cc33cb8..5eadc742a9dc8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.tsx @@ -16,7 +16,6 @@ import { EuiButton, EuiFlyoutBody, EuiPortal, - EuiBetaBadge, EuiCallOut, EuiSpacer, } from '@elastic/eui'; @@ -27,7 +26,6 @@ import { AlertForm, validateBaseProperties } from './alert_form'; import { alertReducer } from './alert_reducer'; import { updateAlert } from '../../lib/alert_api'; import { HealthCheck } from '../../components/health_check'; -import { PLUGIN } from '../../constants/plugin'; import { HealthContextProvider } from '../../context/health_context'; interface AlertEditProps { @@ -119,20 +117,6 @@ export const AlertEdit = ({ initialAlert, onClose }: AlertEditProps) => { defaultMessage="Edit alert" id="xpack.triggersActionsUI.sections.alertEdit.flyoutTitle" /> -   - diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts index 3b93607832670..bd799947256d6 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts @@ -23,7 +23,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await log.debug('Checking for section heading to say Triggers and Actions.'); const headingText = await pageObjects.triggersActionsUI.getSectionHeadingText(); - expect(headingText).to.be('Alerts and Actions BETA'); + expect(headingText).to.be('Alerts and Actions'); }); describe('Connectors tab', () => { From db92edff1fad494819b542d911b7b7b53bd27f14 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 29 Oct 2020 12:46:01 +0100 Subject: [PATCH 21/80] [UX] Create apm static index pattern on ux page visit (#81842) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/apm/public/application/csmApp.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/x-pack/plugins/apm/public/application/csmApp.tsx b/x-pack/plugins/apm/public/application/csmApp.tsx index 2baddbe572a52..d8f54c7bfc94f 100644 --- a/x-pack/plugins/apm/public/application/csmApp.tsx +++ b/x-pack/plugins/apm/public/application/csmApp.tsx @@ -28,6 +28,7 @@ import { ConfigSchema } from '../index'; import { ApmPluginSetupDeps, ApmPluginStartDeps } from '../plugin'; import { createCallApmApi } from '../services/rest/createCallApmApi'; import { px, units } from '../style/variables'; +import { createStaticIndexPattern } from '../services/rest/index_pattern'; const CsmMainContainer = styled.div` padding: ${px(units.plus)}; @@ -114,6 +115,12 @@ export const renderApp = ( ) => { createCallApmApi(core.http); + // Automatically creates static index pattern and stores as saved object + createStaticIndexPattern().catch((e) => { + // eslint-disable-next-line no-console + console.log('Error creating static index pattern', e); + }); + ReactDOM.render( Date: Thu, 29 Oct 2020 14:51:09 +0300 Subject: [PATCH 22/80] Vega visualization renderer (#81606) * Create vega to_ast function * Create a custom vega renderer * Fix sass error Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../vega_editor.scss} | 0 .../vega_vis.scss} | 8 ++ .../public/components/vega_vis_component.tsx | 85 +++++++++++++++++++ .../public/components/vega_vis_editor.tsx | 6 +- .../components/vega_vis_editor_lazy.tsx | 29 +++++++ src/plugins/vis_type_vega/public/index.scss | 9 -- src/plugins/vis_type_vega/public/plugin.ts | 3 +- src/plugins/vis_type_vega/public/to_ast.ts | 32 +++++++ src/plugins/vis_type_vega/public/vega_fn.ts | 14 +-- .../vega_inspector/vega_data_inspector.tsx | 6 +- .../public/vega_inspector/vega_inspector.tsx | 13 ++- src/plugins/vis_type_vega/public/vega_type.ts | 15 ++-- .../public/vega_view/vega_base_view.d.ts | 40 +++++++++ .../public/vega_view/vega_base_view.js | 29 ++++--- .../public/vega_view/vega_map_view.d.ts | 22 +++++ .../index.ts => vega_view/vega_view.d.ts} | 4 +- .../public/vega_vis_renderer.tsx | 51 +++++++++++ .../public/vega_visualization.test.js | 22 +---- ...visualization.js => vega_visualization.ts} | 59 +++++++------ .../__snapshots__/build_pipeline.test.ts.snap | 2 - .../public/legacy/build_pipeline.test.ts | 8 -- .../public/legacy/build_pipeline.ts | 3 - 22 files changed, 354 insertions(+), 106 deletions(-) rename src/plugins/vis_type_vega/public/{_vega_editor.scss => components/vega_editor.scss} (100%) rename src/plugins/vis_type_vega/public/{_vega_vis.scss => components/vega_vis.scss} (96%) create mode 100644 src/plugins/vis_type_vega/public/components/vega_vis_component.tsx create mode 100644 src/plugins/vis_type_vega/public/components/vega_vis_editor_lazy.tsx delete mode 100644 src/plugins/vis_type_vega/public/index.scss create mode 100644 src/plugins/vis_type_vega/public/to_ast.ts create mode 100644 src/plugins/vis_type_vega/public/vega_view/vega_base_view.d.ts create mode 100644 src/plugins/vis_type_vega/public/vega_view/vega_map_view.d.ts rename src/plugins/vis_type_vega/public/{components/index.ts => vega_view/vega_view.d.ts} (89%) create mode 100644 src/plugins/vis_type_vega/public/vega_vis_renderer.tsx rename src/plugins/vis_type_vega/public/{vega_visualization.js => vega_visualization.ts} (70%) diff --git a/src/plugins/vis_type_vega/public/_vega_editor.scss b/src/plugins/vis_type_vega/public/components/vega_editor.scss similarity index 100% rename from src/plugins/vis_type_vega/public/_vega_editor.scss rename to src/plugins/vis_type_vega/public/components/vega_editor.scss diff --git a/src/plugins/vis_type_vega/public/_vega_vis.scss b/src/plugins/vis_type_vega/public/components/vega_vis.scss similarity index 96% rename from src/plugins/vis_type_vega/public/_vega_vis.scss rename to src/plugins/vis_type_vega/public/components/vega_vis.scss index 6a0d20246089e..004eed5a3972b 100644 --- a/src/plugins/vis_type_vega/public/_vega_vis.scss +++ b/src/plugins/vis_type_vega/public/components/vega_vis.scss @@ -1,3 +1,11 @@ +.vgaVis__wrapper { + @include euiScrollBar; + + display: flex; + flex: 1 1 0; + overflow: auto; +} + .vgaVis { display: flex; flex: 1 1 100%; diff --git a/src/plugins/vis_type_vega/public/components/vega_vis_component.tsx b/src/plugins/vis_type_vega/public/components/vega_vis_component.tsx new file mode 100644 index 0000000000000..f1a2f8cbfa8d4 --- /dev/null +++ b/src/plugins/vis_type_vega/public/components/vega_vis_component.tsx @@ -0,0 +1,85 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { useEffect, useMemo, useRef } from 'react'; +import { EuiResizeObserver } from '@elastic/eui'; +import { throttle } from 'lodash'; + +import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; +import { createVegaVisualization } from '../vega_visualization'; +import { VegaVisualizationDependencies } from '../plugin'; +import { VegaParser } from '../data_model/vega_parser'; + +import './vega_vis.scss'; + +interface VegaVisComponentProps { + deps: VegaVisualizationDependencies; + fireEvent: IInterpreterRenderHandlers['event']; + renderComplete: () => void; + visData: VegaParser; +} + +type VegaVisController = InstanceType>; + +const VegaVisComponent = ({ visData, fireEvent, renderComplete, deps }: VegaVisComponentProps) => { + const chartDiv = useRef(null); + const visController = useRef(null); + + useEffect(() => { + if (chartDiv.current) { + const VegaVis = createVegaVisualization(deps); + visController.current = new VegaVis(chartDiv.current, fireEvent); + } + + return () => { + visController.current?.destroy(); + visController.current = null; + }; + }, [deps, fireEvent]); + + useEffect(() => { + if (visController.current) { + visController.current.render(visData).then(renderComplete); + } + }, [visData, renderComplete]); + + const updateChartSize = useMemo( + () => + throttle(() => { + if (visController.current) { + visController.current.render(visData).then(renderComplete); + } + }, 300), + [renderComplete, visData] + ); + + return ( + + {(resizeRef) => ( +
+
+
+ )} + + ); +}; + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { VegaVisComponent as default }; diff --git a/src/plugins/vis_type_vega/public/components/vega_vis_editor.tsx b/src/plugins/vis_type_vega/public/components/vega_vis_editor.tsx index 5e770fcff556d..7d669235c36b8 100644 --- a/src/plugins/vis_type_vega/public/components/vega_vis_editor.tsx +++ b/src/plugins/vis_type_vega/public/components/vega_vis_editor.tsx @@ -30,6 +30,8 @@ import { VisParams } from '../vega_fn'; import { VegaHelpMenu } from './vega_help_menu'; import { VegaActionsMenu } from './vega_actions_menu'; +import './vega_editor.scss'; + const aceOptions = { maxLines: Infinity, highlightActiveLine: false, @@ -102,4 +104,6 @@ function VegaVisEditor({ stateParams, setValue }: VisOptionsProps) { ); } -export { VegaVisEditor }; +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { VegaVisEditor as default }; diff --git a/src/plugins/vis_type_vega/public/components/vega_vis_editor_lazy.tsx b/src/plugins/vis_type_vega/public/components/vega_vis_editor_lazy.tsx new file mode 100644 index 0000000000000..d6c78972410e0 --- /dev/null +++ b/src/plugins/vis_type_vega/public/components/vega_vis_editor_lazy.tsx @@ -0,0 +1,29 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { lazy } from 'react'; + +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; +import { VisParams } from '../vega_fn'; + +const VegaVisEditor = lazy(() => import('./vega_vis_editor')); + +export const VegaVisEditorComponent = (props: VisOptionsProps) => ( + +); diff --git a/src/plugins/vis_type_vega/public/index.scss b/src/plugins/vis_type_vega/public/index.scss deleted file mode 100644 index 78d9eb61999f7..0000000000000 --- a/src/plugins/vis_type_vega/public/index.scss +++ /dev/null @@ -1,9 +0,0 @@ -// Prefix all styles with "vga" to avoid conflicts. -// Examples -// vgaChart -// vgaChart__legend -// vgaChart__legend--small -// vgaChart__legend-isLoading - -@import './vega_vis'; -@import './vega_editor'; diff --git a/src/plugins/vis_type_vega/public/plugin.ts b/src/plugins/vis_type_vega/public/plugin.ts index ce5c5130961c6..04481685c841b 100644 --- a/src/plugins/vis_type_vega/public/plugin.ts +++ b/src/plugins/vis_type_vega/public/plugin.ts @@ -35,10 +35,10 @@ import { import { createVegaFn } from './vega_fn'; import { createVegaTypeDefinition } from './vega_type'; import { IServiceSettings } from '../../maps_legacy/public'; -import './index.scss'; import { ConfigSchema } from '../config'; import { getVegaInspectorView } from './vega_inspector'; +import { getVegaVisRenderer } from './vega_vis_renderer'; /** @internal */ export interface VegaVisualizationDependencies { @@ -93,6 +93,7 @@ export class VegaPlugin implements Plugin, void> { inspector.registerView(getVegaInspectorView({ uiSettings: core.uiSettings })); expressions.registerFunction(() => createVegaFn(visualizationDependencies)); + expressions.registerRenderer(getVegaVisRenderer(visualizationDependencies)); visualizations.createBaseVisualization(createVegaTypeDefinition(visualizationDependencies)); } diff --git a/src/plugins/vis_type_vega/public/to_ast.ts b/src/plugins/vis_type_vega/public/to_ast.ts new file mode 100644 index 0000000000000..a5fe8f13c3daf --- /dev/null +++ b/src/plugins/vis_type_vega/public/to_ast.ts @@ -0,0 +1,32 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { buildExpression, buildExpressionFunction } from '../../expressions/public'; +import { Vis } from '../../visualizations/public'; +import { VegaExpressionFunctionDefinition, VisParams } from './vega_fn'; + +export const toExpressionAst = (vis: Vis) => { + const vega = buildExpressionFunction('vega', { + spec: vis.params.spec, + }); + + const ast = buildExpression([vega]); + + return ast.toAst(); +}; diff --git a/src/plugins/vis_type_vega/public/vega_fn.ts b/src/plugins/vis_type_vega/public/vega_fn.ts index c88b78948133c..25d4e76c336b3 100644 --- a/src/plugins/vis_type_vega/public/vega_fn.ts +++ b/src/plugins/vis_type_vega/public/vega_fn.ts @@ -40,21 +40,23 @@ interface Arguments { export type VisParams = Required; -interface RenderValue { +export interface RenderValue { visData: VegaParser; visType: 'vega'; visConfig: VisParams; } -export const createVegaFn = ( - dependencies: VegaVisualizationDependencies -): ExpressionFunctionDefinition< +export type VegaExpressionFunctionDefinition = ExpressionFunctionDefinition< 'vega', Input, Arguments, Output, ExecutionContext -> => ({ +>; + +export const createVegaFn = ( + dependencies: VegaVisualizationDependencies +): VegaExpressionFunctionDefinition => ({ name: 'vega', type: 'render', inputTypes: ['kibana_context', 'null'], @@ -80,7 +82,7 @@ export const createVegaFn = ( return { type: 'render', - as: 'visualization', + as: 'vega_vis', value: { visData: response, visType: 'vega', diff --git a/src/plugins/vis_type_vega/public/vega_inspector/vega_data_inspector.tsx b/src/plugins/vis_type_vega/public/vega_inspector/vega_data_inspector.tsx index 6dfa7a23c4fe8..350e781dc7076 100644 --- a/src/plugins/vis_type_vega/public/vega_inspector/vega_data_inspector.tsx +++ b/src/plugins/vis_type_vega/public/vega_inspector/vega_data_inspector.tsx @@ -41,7 +41,7 @@ const specLabel = i18n.translate('visTypeVega.inspector.specLabel', { defaultMessage: 'Spec', }); -export const VegaDataInspector = ({ adapters }: VegaDataInspectorProps) => { +const VegaDataInspector = ({ adapters }: VegaDataInspectorProps) => { const tabs = [ { id: 'data-viewer--id', @@ -75,3 +75,7 @@ export const VegaDataInspector = ({ adapters }: VegaDataInspectorProps) => { /> ); }; + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { VegaDataInspector as default }; diff --git a/src/plugins/vis_type_vega/public/vega_inspector/vega_inspector.tsx b/src/plugins/vis_type_vega/public/vega_inspector/vega_inspector.tsx index 83d9e467646a6..4b3e48d6a37a0 100644 --- a/src/plugins/vis_type_vega/public/vega_inspector/vega_inspector.tsx +++ b/src/plugins/vis_type_vega/public/vega_inspector/vega_inspector.tsx @@ -16,14 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -import React from 'react'; +import React, { lazy, Suspense } from 'react'; +import { EuiLoadingSpinner } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { IUiSettingsClient } from 'kibana/public'; -import { VegaAdapter } from './vega_adapter'; -import { VegaDataInspector, VegaDataInspectorProps } from './vega_data_inspector'; import { KibanaContextProvider } from '../../../kibana_react/public'; import { Adapters, RequestAdapter, InspectorViewDescription } from '../../../inspector/public'; +import { VegaAdapter } from './vega_adapter'; +import type { VegaDataInspectorProps } from './vega_data_inspector'; + +const VegaDataInspector = lazy(() => import('./vega_data_inspector')); export interface VegaInspectorAdapters extends Adapters { requests: RequestAdapter; @@ -46,7 +49,9 @@ export const getVegaInspectorView = (dependencies: VegaInspectorViewDependencies }, component: (props) => ( - + }> + + ), } as InspectorViewDescription); diff --git a/src/plugins/vis_type_vega/public/vega_type.ts b/src/plugins/vis_type_vega/public/vega_type.ts index 0496f765e5e99..17f35b75f0016 100644 --- a/src/plugins/vis_type_vega/public/vega_type.ts +++ b/src/plugins/vis_type_vega/public/vega_type.ts @@ -21,22 +21,20 @@ import { i18n } from '@kbn/i18n'; import { BaseVisTypeOptions } from 'src/plugins/visualizations/public'; import { DefaultEditorSize } from '../../vis_default_editor/public'; import { VegaVisualizationDependencies } from './plugin'; -import { VegaVisEditor } from './components'; import { createVegaRequestHandler } from './vega_request_handler'; -// @ts-expect-error -import { createVegaVisualization } from './vega_visualization'; import { getDefaultSpec } from './default_spec'; import { createInspectorAdapters } from './vega_inspector'; import { VIS_EVENT_TO_TRIGGER } from '../../visualizations/public'; - +import { toExpressionAst } from './to_ast'; +import { VisParams } from './vega_fn'; import { getInfoMessage } from './components/experimental_map_vis_info'; +import { VegaVisEditorComponent } from './components/vega_vis_editor_lazy'; export const createVegaTypeDefinition = ( dependencies: VegaVisualizationDependencies -): BaseVisTypeOptions => { +): BaseVisTypeOptions => { const requestHandler = createVegaRequestHandler(dependencies); - const visualization = createVegaVisualization(dependencies); return { name: 'vega', @@ -49,13 +47,12 @@ export const createVegaTypeDefinition = ( icon: 'visVega', visConfig: { defaults: { spec: getDefaultSpec() } }, editorConfig: { - optionsTemplate: VegaVisEditor, + optionsTemplate: VegaVisEditorComponent, enableAutoApply: true, defaultSize: DefaultEditorSize.MEDIUM, }, - visualization, requestHandler, - responseHandler: 'none', + toExpressionAst, options: { showIndexSelection: false, showQueryBar: true, diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_base_view.d.ts b/src/plugins/vis_type_vega/public/vega_view/vega_base_view.d.ts new file mode 100644 index 0000000000000..54b96813769ba --- /dev/null +++ b/src/plugins/vis_type_vega/public/vega_view/vega_base_view.d.ts @@ -0,0 +1,40 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { DataPublicPluginStart } from 'src/plugins/data/public'; +import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; +import { IServiceSettings } from 'src/plugins/maps_legacy/public'; +import { VegaParser } from '../data_model/vega_parser'; + +interface VegaViewParams { + parentEl: HTMLDivElement; + fireEvent: IInterpreterRenderHandlers['event']; + vegaParser: VegaParser; + serviceSettings: IServiceSettings; + filterManager: DataPublicPluginStart['query']['filterManager']; + timefilter: DataPublicPluginStart['query']['timefilter']['timefilter']; + // findIndex: (index: string) => Promise<...>; +} + +export class VegaBaseView { + constructor(params: VegaViewParams); + init(): Promise; + onError(error: any): void; + destroy(): Promise; +} diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_base_view.js b/src/plugins/vis_type_vega/public/vega_view/vega_base_view.js index 979432b2aed2a..25ea77ddbccb4 100644 --- a/src/plugins/vis_type_vega/public/vega_view/vega_base_view.js +++ b/src/plugins/vis_type_vega/public/vega_view/vega_base_view.js @@ -63,7 +63,7 @@ export class VegaBaseView { this._parser = opts.vegaParser; this._serviceSettings = opts.serviceSettings; this._filterManager = opts.filterManager; - this._applyFilter = opts.applyFilter; + this._fireEvent = opts.fireEvent; this._timefilter = opts.timefilter; this._findIndex = opts.findIndex; this._view = null; @@ -264,7 +264,7 @@ export class VegaBaseView { const indexId = await this._findIndex(index); const filter = esFilters.buildQueryFilter(query, indexId); - this._applyFilter({ filters: [filter] }); + this._fireEvent({ name: 'applyFilter', data: { filters: [filter] } }); } /** @@ -301,19 +301,22 @@ export class VegaBaseView { setTimeFilterHandler(start, end) { const { from, to, mode } = VegaBaseView._parseTimeRange(start, end); - this._applyFilter({ - timeFieldName: '*', - filters: [ - { - range: { - '*': { - mode, - gte: from, - lte: to, + this._fireEvent({ + name: 'applyFilter', + data: { + timeFieldName: '*', + filters: [ + { + range: { + '*': { + mode, + gte: from, + lte: to, + }, }, }, - }, - ], + ], + }, }); } diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_map_view.d.ts b/src/plugins/vis_type_vega/public/vega_view/vega_map_view.d.ts new file mode 100644 index 0000000000000..a1210e05f4507 --- /dev/null +++ b/src/plugins/vis_type_vega/public/vega_view/vega_map_view.d.ts @@ -0,0 +1,22 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { VegaBaseView } from './vega_base_view'; + +export class VegaMapView extends VegaBaseView {} diff --git a/src/plugins/vis_type_vega/public/components/index.ts b/src/plugins/vis_type_vega/public/vega_view/vega_view.d.ts similarity index 89% rename from src/plugins/vis_type_vega/public/components/index.ts rename to src/plugins/vis_type_vega/public/vega_view/vega_view.d.ts index 90f067c778fd2..c137d8222750c 100644 --- a/src/plugins/vis_type_vega/public/components/index.ts +++ b/src/plugins/vis_type_vega/public/vega_view/vega_view.d.ts @@ -17,4 +17,6 @@ * under the License. */ -export { VegaVisEditor } from './vega_vis_editor'; +import { VegaBaseView } from './vega_base_view'; + +export class VegaView extends VegaBaseView {} diff --git a/src/plugins/vis_type_vega/public/vega_vis_renderer.tsx b/src/plugins/vis_type_vega/public/vega_vis_renderer.tsx new file mode 100644 index 0000000000000..542f59b3dfff9 --- /dev/null +++ b/src/plugins/vis_type_vega/public/vega_vis_renderer.tsx @@ -0,0 +1,51 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { lazy } from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; + +import { ExpressionRenderDefinition } from 'src/plugins/expressions'; +import { VisualizationContainer } from '../../visualizations/public'; +import { VegaVisualizationDependencies } from './plugin'; +import { RenderValue } from './vega_fn'; +const VegaVisComponent = lazy(() => import('./components/vega_vis_component')); + +export const getVegaVisRenderer: ( + deps: VegaVisualizationDependencies +) => ExpressionRenderDefinition = (deps) => ({ + name: 'vega_vis', + reuseDomNode: true, + render: (domNode, { visData }, handlers) => { + handlers.onDestroy(() => { + unmountComponentAtNode(domNode); + }); + + render( + + + , + domNode + ); + }, +}); diff --git a/src/plugins/vis_type_vega/public/vega_visualization.test.js b/src/plugins/vis_type_vega/public/vega_visualization.test.js index dcf1722768075..837fdf2a9aea3 100644 --- a/src/plugins/vis_type_vega/public/vega_visualization.test.js +++ b/src/plugins/vis_type_vega/public/vega_visualization.test.js @@ -30,8 +30,6 @@ import vegaMapGraph from './test_utils/vega_map_test.json'; import { VegaParser } from './data_model/vega_parser'; import { SearchAPI } from './data_model/search_api'; -import { createVegaTypeDefinition } from './vega_type'; - import { setInjectedVars, setData, setSavedObjects, setNotifications } from './services'; import { coreMock } from '../../../core/public/mocks'; import { dataPluginMock } from '../../data/public/mocks'; @@ -49,9 +47,7 @@ jest.mock('./lib/vega', () => ({ describe('VegaVisualizations', () => { let domNode; let VegaVisualization; - let vis; let vegaVisualizationDependencies; - let vegaVisType; let mockWidth; let mockedWidthValue; @@ -91,22 +87,12 @@ describe('VegaVisualizations', () => { getServiceSettings: mockGetServiceSettings, }; - vegaVisType = createVegaTypeDefinition(vegaVisualizationDependencies); VegaVisualization = createVegaVisualization(vegaVisualizationDependencies); }); describe('VegaVisualization - basics', () => { beforeEach(async () => { setupDOM(); - - vis = { - type: vegaVisType, - API: { - events: { - applyFilter: jest.fn(), - }, - }, - }; }); afterEach(() => { @@ -117,7 +103,7 @@ describe('VegaVisualizations', () => { test('should show vegalite graph and update on resize (may fail in dev env)', async () => { let vegaVis; try { - vegaVis = new VegaVisualization(domNode, vis); + vegaVis = new VegaVisualization(domNode, jest.fn()); const vegaParser = new VegaParser( JSON.stringify(vegaliteGraph), @@ -137,7 +123,7 @@ describe('VegaVisualizations', () => { mockedWidthValue = 256; mockedHeightValue = 256; - await vegaVis._vegaView.resize(); + await vegaVis.vegaView.resize(); expect(domNode.innerHTML).toMatchSnapshot(); } finally { @@ -148,7 +134,7 @@ describe('VegaVisualizations', () => { test('should show vega graph (may fail in dev env)', async () => { let vegaVis; try { - vegaVis = new VegaVisualization(domNode, vis); + vegaVis = new VegaVisualization(domNode, jest.fn()); const vegaParser = new VegaParser( JSON.stringify(vegaGraph), new SearchAPI({ @@ -172,7 +158,7 @@ describe('VegaVisualizations', () => { test('should show vega blank rectangle on top of a map (vegamap)', async () => { let vegaVis; try { - vegaVis = new VegaVisualization(domNode, vis); + vegaVis = new VegaVisualization(domNode, jest.fn()); const vegaParser = new VegaParser( JSON.stringify(vegaMapGraph), new SearchAPI({ diff --git a/src/plugins/vis_type_vega/public/vega_visualization.js b/src/plugins/vis_type_vega/public/vega_visualization.ts similarity index 70% rename from src/plugins/vis_type_vega/public/vega_visualization.js rename to src/plugins/vis_type_vega/public/vega_visualization.ts index 2d58e9cda60cd..58c436bcd4be4 100644 --- a/src/plugins/vis_type_vega/public/vega_visualization.js +++ b/src/plugins/vis_type_vega/public/vega_visualization.ts @@ -17,28 +17,34 @@ * under the License. */ import { i18n } from '@kbn/i18n'; +import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; +import { VegaParser } from './data_model/vega_parser'; +import { VegaVisualizationDependencies } from './plugin'; import { getNotifications, getData, getSavedObjects } from './services'; +import type { VegaView } from './vega_view/vega_view'; -export const createVegaVisualization = ({ getServiceSettings }) => +export const createVegaVisualization = ({ getServiceSettings }: VegaVisualizationDependencies) => class VegaVisualization { - constructor(el, vis) { - this._el = el; - this._vis = vis; + private readonly dataPlugin = getData(); + private readonly savedObjectsClient = getSavedObjects(); + private vegaView: InstanceType | null = null; - this.savedObjectsClient = getSavedObjects(); - this.dataPlugin = getData(); - } + constructor( + private el: HTMLDivElement, + private fireEvent: IInterpreterRenderHandlers['event'] + ) {} /** * Find index pattern by its title, of if not given, gets default * @param {string} [index] * @returns {Promise} index id */ - async findIndex(index) { + async findIndex(index: string) { const { indexPatterns } = this.dataPlugin; let idxObj; if (index) { + // @ts-expect-error idxObj = indexPatterns.findByTitle(this.savedObjectsClient, index); if (!idxObj) { throw new Error( @@ -61,16 +67,10 @@ export const createVegaVisualization = ({ getServiceSettings }) => return idxObj.id; } - /** - * - * @param {VegaParser} visData - * @param {*} status - * @returns {Promise} - */ - async render(visData) { + async render(visData: VegaParser) { const { toasts } = getNotifications(); - if (!visData && !this._vegaView) { + if (!visData && !this.vegaView) { toasts.addWarning( i18n.translate('visTypeVega.visualization.unableToRenderWithoutDataWarningMessage', { defaultMessage: 'Unable to render without data', @@ -82,8 +82,8 @@ export const createVegaVisualization = ({ getServiceSettings }) => try { await this._render(visData); } catch (error) { - if (this._vegaView) { - this._vegaView.onError(error); + if (this.vegaView) { + this.vegaView.onError(error); } else { toasts.addError(error, { title: i18n.translate('visTypeVega.visualization.renderErrorTitle', { @@ -94,20 +94,20 @@ export const createVegaVisualization = ({ getServiceSettings }) => } } - async _render(vegaParser) { + async _render(vegaParser: VegaParser) { if (vegaParser) { // New data received, rebuild the graph - if (this._vegaView) { - await this._vegaView.destroy(); - this._vegaView = null; + if (this.vegaView) { + await this.vegaView.destroy(); + this.vegaView = null; } const serviceSettings = await getServiceSettings(); const { filterManager } = this.dataPlugin.query; const { timefilter } = this.dataPlugin.query.timefilter; const vegaViewParams = { - parentEl: this._el, - applyFilter: this._vis.API.events.applyFilter, + parentEl: this.el, + fireEvent: this.fireEvent, vegaParser, serviceSettings, filterManager, @@ -116,18 +116,17 @@ export const createVegaVisualization = ({ getServiceSettings }) => }; if (vegaParser.useMap) { - const services = { toastService: getNotifications().toasts }; const { VegaMapView } = await import('./vega_view/vega_map_view'); - this._vegaView = new VegaMapView(vegaViewParams, services); + this.vegaView = new VegaMapView(vegaViewParams); } else { - const { VegaView } = await import('./vega_view/vega_view'); - this._vegaView = new VegaView(vegaViewParams); + const { VegaView: VegaViewClass } = await import('./vega_view/vega_view'); + this.vegaView = new VegaViewClass(vegaViewParams); } - await this._vegaView.init(); + await this.vegaView?.init(); } } destroy() { - return this._vegaView && this._vegaView.destroy(); + this.vegaView?.destroy(); } }; diff --git a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap index cbdecd4aac747..959d9031853af 100644 --- a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap +++ b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap @@ -13,5 +13,3 @@ exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunct exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles region_map function without buckets 1`] = `"regionmap visConfig='{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"}}' "`; exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles tile_map function 1`] = `"tilemap visConfig='{\\"metric\\":{},\\"dimensions\\":{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},\\"geohash\\":1,\\"geocentroid\\":3}}' "`; - -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles vega function 1`] = `"vega spec='this is a test' "`; diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts index c744043ed155b..501a69080d93f 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts @@ -94,14 +94,6 @@ describe('visualize loader pipeline helpers: build pipeline', () => { uiState = {}; }); - it('handles vega function', () => { - const vis = { - params: { spec: 'this is a test' }, - }; - const actual = buildPipelineVisFunction.vega(vis.params, schemasDef, uiState); - expect(actual).toMatchSnapshot(); - }); - it('handles input_control_vis function', () => { const params = { some: 'nested', diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.ts b/src/plugins/visualizations/public/legacy/build_pipeline.ts index eb431212166a3..b08583c376b36 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.ts @@ -254,9 +254,6 @@ const adjustVislibDimensionFormmaters = (vis: Vis, dimensions: { y: any[] }): vo }; export const buildPipelineVisFunction: BuildPipelineVisFunction = { - vega: (params) => { - return `vega ${prepareString('spec', params.spec)}`; - }, input_control_vis: (params) => { return `input_control_vis ${prepareJson('visConfig', params)}`; }, From 13fe95b400ea6bd933921d24a6b24313e11be193 Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Thu, 29 Oct 2020 12:32:36 +0000 Subject: [PATCH 23/80] Enables the EventLog Client to query across ILM versions of the `.event-log` index (#81920) Fixes a bug in the EventLog client which caused it to query for events created in the current version instead of querying across versions. --- .../event_log/server/event_log_client.test.ts | 4 +- .../event_log/server/event_log_client.ts | 2 +- .../event_log_multiple_indicies/data.json | 274 +++++++++ .../event_log_multiple_indicies/mappings.json | 576 ++++++++++++++++++ .../event_log/public_api_integration.ts | 26 + 5 files changed, 879 insertions(+), 3 deletions(-) create mode 100644 x-pack/test/functional/es_archives/event_log_multiple_indicies/data.json create mode 100644 x-pack/test/functional/es_archives/event_log_multiple_indicies/mappings.json diff --git a/x-pack/plugins/event_log/server/event_log_client.test.ts b/x-pack/plugins/event_log/server/event_log_client.test.ts index 3273fe847080f..d6793be425585 100644 --- a/x-pack/plugins/event_log/server/event_log_client.test.ts +++ b/x-pack/plugins/event_log/server/event_log_client.test.ts @@ -114,7 +114,7 @@ describe('EventLogStart', () => { ).toEqual(result); expect(esContext.esAdapter.queryEventsBySavedObject).toHaveBeenCalledWith( - esContext.esNames.alias, + esContext.esNames.indexPattern, undefined, 'saved-object-type', 'saved-object-id', @@ -195,7 +195,7 @@ describe('EventLogStart', () => { ).toEqual(result); expect(esContext.esAdapter.queryEventsBySavedObject).toHaveBeenCalledWith( - esContext.esNames.alias, + esContext.esNames.indexPattern, undefined, 'saved-object-type', 'saved-object-id', diff --git a/x-pack/plugins/event_log/server/event_log_client.ts b/x-pack/plugins/event_log/server/event_log_client.ts index 32fd99d170026..b7de4acb9428c 100644 --- a/x-pack/plugins/event_log/server/event_log_client.ts +++ b/x-pack/plugins/event_log/server/event_log_client.ts @@ -92,7 +92,7 @@ export class EventLogClient implements IEventLogClient { await this.savedObjectGetter(type, id); return await this.esContext.esAdapter.queryEventsBySavedObject( - this.esContext.esNames.alias, + this.esContext.esNames.indexPattern, namespace, type, id, diff --git a/x-pack/test/functional/es_archives/event_log_multiple_indicies/data.json b/x-pack/test/functional/es_archives/event_log_multiple_indicies/data.json new file mode 100644 index 0000000000000..4e871f6308b77 --- /dev/null +++ b/x-pack/test/functional/es_archives/event_log_multiple_indicies/data.json @@ -0,0 +1,274 @@ +{ + "type": "doc", + "value": { + "id": "config:8.0.0", + "index": ".kibana_1", + "source": { + "config": { + "buildNum": 9007199254740991 + }, + "migrationVersion": { + "config": "7.9.0" + }, + "references": [ + ], + "type": "config", + "updated_at": "2020-10-28T15:19:15.795Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "space:default", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "space": "6.6.0" + }, + "references": [ + ], + "space": { + "_reserved": true, + "color": "#00bfb3", + "description": "This is your default space!", + "disabledFeatures": [ + ], + "name": "Default" + }, + "type": "space", + "updated_at": "2020-10-28T15:19:15.857Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "space:namespace-a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "space": "6.6.0" + }, + "references": [ + ], + "space": { + "disabledFeatures": [ + ], + "name": "Space A" + }, + "type": "space", + "updated_at": "2020-10-28T15:19:52.887Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "event_log_test:421f2511-5cd1-44fd-95df-e0df83e354d5", + "index": ".kibana_1", + "source": { + "event_log_test": { + }, + "references": [ + ], + "type": "event_log_test", + "updated_at": "2020-10-28T15:19:53.861Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "XKbLb3UBt6Z_MVvSSPbe", + "index": ".kibana-event-log-7.9.0-000001", + "source": { + "@timestamp": "2020-10-28T15:19:54.841Z", + "ecs": { + "version": "1.5.0" + }, + "event": { + "action": "test", + "duration": 0, + "end": "2020-10-28T15:19:54.841Z", + "provider": "event_log_fixture", + "start": "2020-10-28T15:19:54.841Z" + }, + "kibana": { + "saved_objects": [ + { + "id": "421f2511-5cd1-44fd-95df-e0df83e354d5", + "rel": "primary", + "type": "event_log_test" + } + ], + "server_uuid": "5b2de169-2785-441b-ae8c-186a1936b17d" + }, + "message": "test 2020-10-28T15:19:53.825Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "XabLb3UBt6Z_MVvSSfYD", + "index": ".kibana-event-log-7.9.0-000001", + "source": { + "@timestamp": "2020-10-28T15:19:54.879Z", + "ecs": { + "version": "1.5.0" + }, + "event": { + "action": "test", + "duration": 0, + "end": "2020-10-28T15:19:54.879Z", + "provider": "event_log_fixture", + "start": "2020-10-28T15:19:54.879Z" + }, + "kibana": { + "saved_objects": [ + { + "id": "421f2511-5cd1-44fd-95df-e0df83e354d5", + "rel": "primary", + "type": "event_log_test" + } + ], + "server_uuid": "5b2de169-2785-441b-ae8c-186a1936b17d" + }, + "message": "test 2020-10-28T15:19:54.849Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "XqbLb3UBt6Z_MVvSSfYe", + "index": ".kibana-event-log-7.9.0-000001", + "source": { + "@timestamp": "2020-10-28T15:19:54.905Z", + "ecs": { + "version": "1.5.0" + }, + "event": { + "action": "test", + "duration": 0, + "end": "2020-10-28T15:19:54.905Z", + "provider": "event_log_fixture", + "start": "2020-10-28T15:19:54.905Z" + }, + "kibana": { + "saved_objects": [ + { + "id": "421f2511-5cd1-44fd-95df-e0df83e354d5", + "rel": "primary", + "type": "event_log_test" + } + ], + "server_uuid": "5b2de169-2785-441b-ae8c-186a1936b17d" + }, + "message": "test 2020-10-28T15:19:54.881Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "X6bLb3UBt6Z_MVvSTfYk", + "index": ".kibana-event-log-8.0.0-000001", + "source": { + "@timestamp": "2020-10-28T15:19:55.933Z", + "ecs": { + "version": "1.5.0" + }, + "event": { + "action": "test", + "duration": 0, + "end": "2020-10-28T15:19:55.933Z", + "provider": "event_log_fixture", + "start": "2020-10-28T15:19:55.933Z" + }, + "kibana": { + "saved_objects": [ + { + "id": "421f2511-5cd1-44fd-95df-e0df83e354d5", + "rel": "primary", + "type": "event_log_test" + } + ], + "server_uuid": "5b2de169-2785-441b-ae8c-186a1936b17d" + }, + "message": "test 2020-10-28T15:19:55.913Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "YKbLb3UBt6Z_MVvSTfY8", + "index": ".kibana-event-log-8.0.0-000001", + "source": { + "@timestamp": "2020-10-28T15:19:55.957Z", + "ecs": { + "version": "1.5.0" + }, + "event": { + "action": "test", + "duration": 0, + "end": "2020-10-28T15:19:55.957Z", + "provider": "event_log_fixture", + "start": "2020-10-28T15:19:55.957Z" + }, + "kibana": { + "saved_objects": [ + { + "id": "421f2511-5cd1-44fd-95df-e0df83e354d5", + "rel": "primary", + "type": "event_log_test" + } + ], + "server_uuid": "5b2de169-2785-441b-ae8c-186a1936b17d" + }, + "message": "test 2020-10-28T15:19:55.938Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "YabLb3UBt6Z_MVvSTfZc", + "index": ".kibana-event-log-8.0.0-000001", + "source": { + "@timestamp": "2020-10-28T15:19:55.991Z", + "ecs": { + "version": "1.5.0" + }, + "event": { + "action": "test", + "duration": 0, + "end": "2020-10-28T15:19:55.991Z", + "provider": "event_log_fixture", + "start": "2020-10-28T15:19:55.991Z" + }, + "kibana": { + "saved_objects": [ + { + "id": "421f2511-5cd1-44fd-95df-e0df83e354d5", + "rel": "primary", + "type": "event_log_test" + } + ], + "server_uuid": "5b2de169-2785-441b-ae8c-186a1936b17d" + }, + "message": "test 2020-10-28T15:19:55.962Z" + } + } +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/event_log_multiple_indicies/mappings.json b/x-pack/test/functional/es_archives/event_log_multiple_indicies/mappings.json new file mode 100644 index 0000000000000..b418ccc1343a2 --- /dev/null +++ b/x-pack/test/functional/es_archives/event_log_multiple_indicies/mappings.json @@ -0,0 +1,576 @@ +{ + "type": "index", + "value": { + "aliases": { + ".kibana": { + } + }, + "index": ".kibana_1", + "mappings": { + "_meta": { + "migrationMappingPropertyHashes": { + "action": "6e96ac5e648f57523879661ea72525b7", + "action_task_params": "a9d49f184ee89641044be0ca2950fa3a", + "alert": "eaf6f5841dbf4cb5e3045860f75f53ca", + "apm-indices": "9bb9b2bf1fa636ed8619cbab5ce6a1dd", + "apm-telemetry": "3d1b76c39bfb2cc8296b024d73854724", + "app_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724", + "application_usage_daily": "43b8830d5d0df85a6823d290885fc9fd", + "application_usage_totals": "3d1b76c39bfb2cc8296b024d73854724", + "application_usage_transactional": "3d1b76c39bfb2cc8296b024d73854724", + "canvas-element": "7390014e1091044523666d97247392fc", + "canvas-workpad": "b0a1706d356228dbdcb4a17e6b9eb231", + "canvas-workpad-template": "ae2673f678281e2c055d764b153e9715", + "cases": "477f214ff61acc3af26a7b7818e380c1", + "cases-comments": "c2061fb929f585df57425102fa928b4b", + "cases-configure": "387c5f3a3bda7e0ae0dd4e106f914a69", + "cases-user-actions": "32277330ec6b721abe3b846cfd939a71", + "config": "c63748b75f39d0c54de12d12c1ccbc20", + "dashboard": "40554caf09725935e2c02e02563a2d07", + "endpoint:user-artifact": "4a11183eee21e6fbad864f7a30b39ad0", + "endpoint:user-artifact-manifest": "4b9c0e7cfaf86d82a7ee9ed68065e50d", + "enterprise_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724", + "epm-packages": "2b83397e3eaaaa8ef15e38813f3721c3", + "event_log_test": "bef808d4a9c27f204ffbda3359233931", + "exception-list": "67f055ab8c10abd7b2ebfd969b836788", + "exception-list-agnostic": "67f055ab8c10abd7b2ebfd969b836788", + "file-upload-telemetry": "0ed4d3e1983d1217a30982630897092e", + "fleet-agent-actions": "9511b565b1cc6441a42033db3d5de8e9", + "fleet-agent-events": "e20a508b6e805189356be381dbfac8db", + "fleet-agents": "cb661e8ede2b640c42c8e5ef99db0683", + "fleet-enrollment-api-keys": "a69ef7ae661dab31561d6c6f052ef2a7", + "graph-workspace": "cd7ba1330e6682e9cc00b78850874be1", + "index-pattern": "45915a1ad866812242df474eb0479052", + "infrastructure-ui-source": "3d1b76c39bfb2cc8296b024d73854724", + "ingest-agent-policies": "8b0733cce189659593659dad8db426f0", + "ingest-outputs": "8854f34453a47e26f86a29f8f3b80b4e", + "ingest-package-policies": "f74dfe498e1849267cda41580b2be110", + "ingest_manager_settings": "02a03095f0e05b7a538fa801b88a217f", + "inventory-view": "3d1b76c39bfb2cc8296b024d73854724", + "kql-telemetry": "d12a98a6f19a2d273696597547e064ee", + "lens": "52346cfec69ff7b47d5f0c12361a2797", + "lens-ui-telemetry": "509bfa5978586998e05f9e303c07a327", + "map": "4a05b35c3a3a58fbc72dd0202dc3487f", + "maps-telemetry": "5ef305b18111b77789afefbd36b66171", + "metrics-explorer-view": "3d1b76c39bfb2cc8296b024d73854724", + "migrationVersion": "4a1746014a75ade3a714e1db5763276f", + "ml-telemetry": "257fd1d4b4fdbb9cb4b8a3b27da201e9", + "monitoring-telemetry": "2669d5ec15e82391cf58df4294ee9c68", + "namespace": "2f4316de49999235636386fe51dc06c1", + "namespaces": "2f4316de49999235636386fe51dc06c1", + "originId": "2f4316de49999235636386fe51dc06c1", + "query": "11aaeb7f5f7fa5bb43f25e18ce26e7d9", + "references": "7997cf5a56cc02bdc9c93361bde732b0", + "sample-data-telemetry": "7d3cfeb915303c9641c59681967ffeb4", + "search": "43012c7ebc4cb57054e0a490e4b43023", + "search-telemetry": "3d1b76c39bfb2cc8296b024d73854724", + "siem-detection-engine-rule-actions": "6569b288c169539db10cb262bf79de18", + "siem-detection-engine-rule-status": "ae783f41c6937db6b7a2ef5c93a9e9b0", + "siem-ui-timeline": "d12c5474364d737d17252acf1dc4585c", + "siem-ui-timeline-note": "8874706eedc49059d4cf0f5094559084", + "siem-ui-timeline-pinned-event": "20638091112f0e14f0e443d512301c29", + "space": "c5ca8acafa0beaa4d08d014a97b6bc6b", + "telemetry": "36a616f7026dfa617d6655df850fe16d", + "timelion-sheet": "9a2a2748877c7a7b582fef201ab1d4cf", + "tsvb-validation-telemetry": "3a37ef6c8700ae6fc97d5c7da00e9215", + "type": "2f4316de49999235636386fe51dc06c1", + "ui-metric": "0d409297dc5ebe1e3a1da691c6ee32e3", + "updated_at": "00da57df13e94e9d98437d13ace4bfe0", + "upgrade-assistant-reindex-operation": "215107c281839ea9b3ad5f6419819763", + "upgrade-assistant-telemetry": "56702cec857e0a9dacfb696655b4ff7b", + "uptime-dynamic-settings": "3d1b76c39bfb2cc8296b024d73854724", + "url": "c7f66a0df8b1b52f17c28c4adb111105", + "visualization": "f819cf6636b75c9e76ba733a0c6ef355", + "workplace_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724" + } + }, + "dynamic": "strict", + "properties": { + "config": { + "dynamic": "false", + "properties": { + "buildNum": { + "type": "keyword" + } + } + }, + "event_log_test": { + "type": "object" + }, + "migrationVersion": { + "dynamic": "true", + "properties": { + "config": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "space": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "ml-telemetry": { + "properties": { + "file_data_visualizer": { + "properties": { + "index_creation_count": { + "type": "long" + } + } + } + } + }, + "monitoring-telemetry": { + "properties": { + "reportedClusterUuids": { + "type": "keyword" + } + } + }, + "namespace": { + "type": "keyword" + }, + "namespaces": { + "type": "keyword" + }, + "originId": { + "type": "keyword" + }, + "query": { + "properties": { + "description": { + "type": "text" + }, + "filters": { + "enabled": false, + "type": "object" + }, + "query": { + "properties": { + "language": { + "type": "keyword" + }, + "query": { + "index": false, + "type": "keyword" + } + } + }, + "timefilter": { + "enabled": false, + "type": "object" + }, + "title": { + "type": "text" + } + } + }, + "references": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + } + }, + "type": "nested" + }, + "type": { + "type": "keyword" + }, + "space": { + "properties": { + "_reserved": { + "type": "boolean" + }, + "color": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "disabledFeatures": { + "type": "keyword" + }, + "imageUrl": { + "index": false, + "type": "text" + }, + "initials": { + "type": "keyword" + }, + "name": { + "fields": { + "keyword": { + "ignore_above": 2048, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "ui-metric": { + "properties": { + "count": { + "type": "integer" + } + } + }, + "updated_at": { + "type": "date" + }, + "url": { + "properties": { + "accessCount": { + "type": "long" + }, + "accessDate": { + "type": "date" + }, + "createDate": { + "type": "date" + }, + "url": { + "fields": { + "keyword": { + "ignore_above": 2048, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "visualization": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "index": false, + "type": "text" + } + } + }, + "savedSearchRefName": { + "doc_values": false, + "index": false, + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "index": false, + "type": "text" + }, + "version": { + "type": "integer" + }, + "visState": { + "index": false, + "type": "text" + } + } + }, + "workplace_search_telemetry": { + "dynamic": "false", + "type": "object" + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "0-1", + "number_of_replicas": "0", + "number_of_shards": "1" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + ".kibana-event-log-7.9.0": { + "is_write_index": true + } + }, + "index": ".kibana-event-log-7.9.0-000001", + "mappings": { + "dynamic": "false", + "properties": { + "@timestamp": { + "type": "date" + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "properties": { + "message": { + "norms": false, + "type": "text" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "start": { + "type": "date" + } + } + }, + "kibana": { + "properties": { + "alerting": { + "properties": { + "instance_id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "saved_objects": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "rel": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "server_uuid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "tags": { + "ignore_above": 1024, + "meta": { + "isArray": "true" + }, + "type": "keyword" + }, + "user": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "0-1", + "lifecycle": { + "name": "kibana-event-log-policy", + "rollover_alias": ".kibana-event-log-7.9.0" + }, + "number_of_replicas": "0", + "number_of_shards": "1" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + ".kibana-event-log-8.0.0": { + "is_write_index": true + } + }, + "index": ".kibana-event-log-8.0.0-000001", + "mappings": { + "dynamic": "false", + "properties": { + "@timestamp": { + "type": "date" + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "properties": { + "message": { + "norms": false, + "type": "text" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "start": { + "type": "date" + } + } + }, + "kibana": { + "properties": { + "alerting": { + "properties": { + "instance_id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "saved_objects": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "rel": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "server_uuid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "tags": { + "ignore_above": 1024, + "meta": { + "isArray": "true" + }, + "type": "keyword" + }, + "user": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "0-1", + "lifecycle": { + "name": "kibana-event-log-policy", + "rollover_alias": ".kibana-event-log-8.0.0" + }, + "number_of_replicas": "0", + "number_of_shards": "1" + } + } + } +} \ No newline at end of file diff --git a/x-pack/test/plugin_api_integration/test_suites/event_log/public_api_integration.ts b/x-pack/test/plugin_api_integration/test_suites/event_log/public_api_integration.ts index eea18863e3be8..dff10daafbdb8 100644 --- a/x-pack/test/plugin_api_integration/test_suites/event_log/public_api_integration.ts +++ b/x-pack/test/plugin_api_integration/test_suites/event_log/public_api_integration.ts @@ -157,6 +157,32 @@ export default function ({ getService }: FtrProviderContext) { }); }); } + + describe(`Index Lifecycle`, () => { + it('should query across indicies matching the Event Log index pattern', async () => { + await esArchiver.load('event_log_multiple_indicies'); + + const id = `421f2511-5cd1-44fd-95df-e0df83e354d5`; + + const { + body: { data, total }, + } = await findEvents(undefined, id, {}); + + expect(data.length).to.be(6); + expect(total).to.be(6); + + expect(data.map((foundEvent: IEvent) => foundEvent?.message)).to.eql([ + 'test 2020-10-28T15:19:53.825Z', + 'test 2020-10-28T15:19:54.849Z', + 'test 2020-10-28T15:19:54.881Z', + 'test 2020-10-28T15:19:55.913Z', + 'test 2020-10-28T15:19:55.938Z', + 'test 2020-10-28T15:19:55.962Z', + ]); + + await esArchiver.unload('event_log_multiple_indicies'); + }); + }); }); async function findEvents( From d1344b6ecd294641f5f0f10ca826f3fa0618ae8c Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Thu, 29 Oct 2020 12:33:22 +0000 Subject: [PATCH 24/80] added alerting to app directory (#81902) Adds a link to the Alerts & Actions from the app directory --- .../plugins/triggers_actions_ui/kibana.json | 4 +-- .../triggers_actions_ui/public/plugin.ts | 31 +++++++++++++++++-- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/kibana.json b/x-pack/plugins/triggers_actions_ui/kibana.json index c9187096821d8..a4446e0a75120 100644 --- a/x-pack/plugins/triggers_actions_ui/kibana.json +++ b/x-pack/plugins/triggers_actions_ui/kibana.json @@ -3,9 +3,9 @@ "version": "kibana", "server": true, "ui": true, - "optionalPlugins": ["alerts", "stackAlerts"], + "optionalPlugins": ["home", "alerts", "stackAlerts"], "requiredPlugins": ["management", "charts", "data", "kibanaReact"], "configPath": ["xpack", "trigger_actions_ui"], "extraPublicDirs": ["public/common", "public/common/constants"], - "requiredBundles": ["alerts", "esUiShared"] + "requiredBundles": ["home", "alerts", "esUiShared"] } diff --git a/x-pack/plugins/triggers_actions_ui/public/plugin.ts b/x-pack/plugins/triggers_actions_ui/public/plugin.ts index 874a380f56b5f..393ac5bc1b74d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/plugin.ts +++ b/x-pack/plugins/triggers_actions_ui/public/plugin.ts @@ -20,6 +20,10 @@ import { ManagementAppMountParams, ManagementSetup, } from '../../../../src/plugins/management/public'; +import { + FeatureCatalogueCategory, + HomePublicPluginSetup, +} from '../../../../src/plugins/home/public'; import { ChartsPluginStart } from '../../../../src/plugins/charts/public'; import { PluginStartContract as AlertingStart } from '../../alerts/public'; import { DataPublicPluginStart } from '../../../../src/plugins/data/public'; @@ -40,6 +44,7 @@ export interface TriggersAndActionsUIPublicPluginStart { interface PluginsSetup { management: ManagementSetup; + home?: HomePublicPluginSetup; } interface PluginsStart { @@ -73,11 +78,31 @@ export class Plugin const actionTypeRegistry = this.actionTypeRegistry; const alertTypeRegistry = this.alertTypeRegistry; + const featureTitle = i18n.translate('xpack.triggersActionsUI.managementSection.displayName', { + defaultMessage: 'Alerts and Actions', + }); + const featureDescription = i18n.translate( + 'xpack.triggersActionsUI.managementSection.displayDescription', + { + defaultMessage: 'Detect conditions using alerts, and take actions using connectors.', + } + ); + + if (plugins.home) { + plugins.home.featureCatalogue.register({ + id: 'triggersActions', + title: featureTitle, + description: featureDescription, + icon: 'watchesApp', + path: '/app/management/insightsAndAlerting/triggersActions', + showOnHomePage: false, + category: FeatureCatalogueCategory.ADMIN, + }); + } + plugins.management.sections.section.insightsAndAlerting.registerApp({ id: 'triggersActions', - title: i18n.translate('xpack.triggersActionsUI.managementSection.displayName', { - defaultMessage: 'Alerts and Actions', - }), + title: featureTitle, order: 0, async mount(params: ManagementAppMountParams) { const [coreStart, pluginsStart] = (await core.getStartServices()) as [ From 275c30a926a3bde5836180b726389d73de39addf Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 29 Oct 2020 12:44:51 +0000 Subject: [PATCH 25/80] skip flaky suite (#81632) --- test/functional/apps/discover/_doc_table.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/discover/_doc_table.ts b/test/functional/apps/discover/_doc_table.ts index 7fc120f9ea474..d3c0fe834958d 100644 --- a/test/functional/apps/discover/_doc_table.ts +++ b/test/functional/apps/discover/_doc_table.ts @@ -88,7 +88,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await footer.getVisibleText()).to.have.string(rowsHardLimit); }); - describe('expand a document row', function () { + // FLAKY: https://github.com/elastic/kibana/issues/81632 + describe.skip('expand a document row', function () { const rowToInspect = 1; beforeEach(async function () { // close the toggle if open From 1407f713e517b51cefcbf2f0a890a56bd9b7c21d Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 29 Oct 2020 14:35:48 +0100 Subject: [PATCH 26/80] Update KibanaRequest to use the new WHATWG URL API (#80713) --- ...kibana-plugin-core-server.kibanarequest.md | 4 +-- ...-core-server.kibanarequest.rewrittenurl.md | 2 +- ...na-plugin-core-server.kibanarequest.url.md | 2 +- src/core/server/http/http_server.mocks.ts | 28 +++++++++++-------- src/core/server/http/http_server.ts | 2 +- .../http/integration_tests/lifecycle.test.ts | 24 ++++++++++++++-- .../server/http/lifecycle/on_pre_routing.ts | 25 +++++++++++++++-- src/core/server/http/router/request.ts | 15 +++++----- src/core/server/server.api.md | 6 ++-- .../server/lib/task_runner_factory.test.ts | 18 ++++++++++++ .../actions/server/lib/task_runner_factory.ts | 6 ++++ .../server/alerts_client_factory.test.ts | 6 ++++ x-pack/plugins/alerts/server/plugin.test.ts | 6 ++++ .../server/task_runner/task_runner.test.ts | 18 ++++++++++++ .../alerts/server/task_runner/task_runner.ts | 6 ++++ ...dashboard_mode_request_interceptor.test.ts | 10 +++---- .../dashboard_mode_request_interceptor.ts | 2 +- .../lib/enterprise_search_config_api.test.ts | 1 - .../event_log/server/event_log_client.test.ts | 6 ++++ .../server/event_log_start_service.test.ts | 6 ++++ .../saved_object_provider_registry.test.ts | 6 ++++ .../server/services/agent_policy_update.ts | 6 ++++ .../agents/checkin/state_connected_agents.ts | 6 ++++ .../agents/checkin/state_new_actions.ts | 6 ++++ .../ml/server/routes/data_frame_analytics.ts | 12 ++------ x-pack/plugins/reporting/server/core.ts | 7 +++++ .../lib/authorized_user_pre_routing.test.ts | 2 +- .../server/audit/audit_events.test.ts | 16 ++++------- .../security/server/audit/audit_events.ts | 14 +++++----- .../server/authentication/authenticator.ts | 4 +-- .../authentication/providers/basic.test.ts | 4 +-- .../server/authentication/providers/basic.ts | 10 +++++-- .../server/authentication/providers/http.ts | 8 ++++-- .../authentication/providers/kerberos.ts | 6 ++-- .../server/authentication/providers/oidc.ts | 8 ++++-- .../server/authentication/providers/pki.ts | 6 ++-- .../server/authentication/providers/saml.ts | 8 ++++-- .../authentication/providers/token.test.ts | 4 +-- .../server/authentication/providers/token.ts | 10 +++++-- .../server/authorization/api_authorization.ts | 6 ++-- .../authorization/authorization_service.tsx | 2 +- .../server/routes/authentication/oidc.ts | 2 +- .../server/routes/views/login.test.ts | 4 +-- .../on_post_auth_interceptor.ts | 2 +- .../on_request_interceptor.ts | 13 ++------- .../spaces_service/spaces_service.test.ts | 10 +++---- 46 files changed, 262 insertions(+), 113 deletions(-) diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanarequest.md b/docs/development/core/server/kibana-plugin-core-server.kibanarequest.md index 1134994faa9bd..4129662acb2b1 100644 --- a/docs/development/core/server/kibana-plugin-core-server.kibanarequest.md +++ b/docs/development/core/server/kibana-plugin-core-server.kibanarequest.md @@ -30,9 +30,9 @@ export declare class KibanaRequestboolean | Whether or not the request is a "system request" rather than an application-level request. Can be set on the client using the HttpFetchOptions#asSystemRequest option. | | [params](./kibana-plugin-core-server.kibanarequest.params.md) | | Params | | | [query](./kibana-plugin-core-server.kibanarequest.query.md) | | Query | | -| [rewrittenUrl](./kibana-plugin-core-server.kibanarequest.rewrittenurl.md) | | Url | URL rewritten in onPreRouting request interceptor. | +| [rewrittenUrl](./kibana-plugin-core-server.kibanarequest.rewrittenurl.md) | | URL | URL rewritten in onPreRouting request interceptor. | | [route](./kibana-plugin-core-server.kibanarequest.route.md) | | RecursiveReadonly<KibanaRequestRoute<Method>> | matched route details | | [socket](./kibana-plugin-core-server.kibanarequest.socket.md) | | IKibanaSocket | [IKibanaSocket](./kibana-plugin-core-server.ikibanasocket.md) | -| [url](./kibana-plugin-core-server.kibanarequest.url.md) | | Url | a WHATWG URL standard object. | +| [url](./kibana-plugin-core-server.kibanarequest.url.md) | | URL | a WHATWG URL standard object. | | [uuid](./kibana-plugin-core-server.kibanarequest.uuid.md) | | string | A UUID to identify this request. | diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanarequest.rewrittenurl.md b/docs/development/core/server/kibana-plugin-core-server.kibanarequest.rewrittenurl.md index 10628bafaf1d4..fb547330ee6ea 100644 --- a/docs/development/core/server/kibana-plugin-core-server.kibanarequest.rewrittenurl.md +++ b/docs/development/core/server/kibana-plugin-core-server.kibanarequest.rewrittenurl.md @@ -9,5 +9,5 @@ URL rewritten in onPreRouting request interceptor. Signature: ```typescript -readonly rewrittenUrl?: Url; +readonly rewrittenUrl?: URL; ``` diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanarequest.url.md b/docs/development/core/server/kibana-plugin-core-server.kibanarequest.url.md index 31d1348197201..b72760e272bb2 100644 --- a/docs/development/core/server/kibana-plugin-core-server.kibanarequest.url.md +++ b/docs/development/core/server/kibana-plugin-core-server.kibanarequest.url.md @@ -9,5 +9,5 @@ a WHATWG URL standard object. Signature: ```typescript -readonly url: Url; +readonly url: URL; ``` diff --git a/src/core/server/http/http_server.mocks.ts b/src/core/server/http/http_server.mocks.ts index 6aad232cf42b6..d615e799f383f 100644 --- a/src/core/server/http/http_server.mocks.ts +++ b/src/core/server/http/http_server.mocks.ts @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ +import { parse as parseUrl } from 'url'; import { Request } from 'hapi'; import { merge } from 'lodash'; import { Socket } from 'net'; @@ -72,6 +73,7 @@ function createKibanaRequestMock

({ auth = { isAuthenticated: true }, }: RequestFixtureOptions = {}) { const queryString = stringify(query, { sort: false }); + const url = parseUrl(`${path}${queryString ? `?${queryString}` : ''}`); return KibanaRequest.from( createRawRequestMock({ @@ -83,12 +85,7 @@ function createKibanaRequestMock

({ payload: body, path, method, - url: { - path, - pathname: path, - query: queryString, - search: queryString ? `?${queryString}` : queryString, - }, + url, route: { settings: { tags: routeTags, auth: routeAuthRequired, app: kibanaRouteOptions }, }, @@ -121,6 +118,11 @@ interface DeepPartialArray extends Array> {} type DeepPartialObject = { [P in keyof T]+?: DeepPartial }; function createRawRequestMock(customization: DeepPartial = {}) { + const pathname = customization.url?.pathname || '/'; + const path = `${pathname}${customization.url?.search || ''}`; + const url = Object.assign({ pathname, path, href: path }, customization.url); + + // @ts-expect-error _core isn't supposed to be accessed - remove once we upgrade to hapi v18 return merge( {}, { @@ -129,17 +131,21 @@ function createRawRequestMock(customization: DeepPartial = {}) { isAuthenticated: true, }, headers: {}, - path: '/', + path, route: { settings: {} }, - url: { - href: '/', - }, + url, raw: { req: { - url: '/', + url: path, socket: {}, }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, }, customization ) as Request; diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index 2440f2b1da0bd..d94bce12fb439 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -271,7 +271,7 @@ export class HttpServer { } this.registerOnPreRouting((request, response, toolkit) => { - const oldUrl = request.url.href!; + const oldUrl = request.url.pathname + request.url.search; const newURL = basePathService.remove(oldUrl); const shouldRedirect = newURL !== oldUrl; if (shouldRedirect) { diff --git a/src/core/server/http/integration_tests/lifecycle.test.ts b/src/core/server/http/integration_tests/lifecycle.test.ts index 01817b29de8ac..37401a2c24ccd 100644 --- a/src/core/server/http/integration_tests/lifecycle.test.ts +++ b/src/core/server/http/integration_tests/lifecycle.test.ts @@ -124,7 +124,13 @@ describe('OnPreRouting', () => { const router = createRouter('/'); router.get({ path: '/login', validate: false }, (context, req, res) => { - return res.ok({ body: { rewrittenUrl: req.rewrittenUrl?.path } }); + return res.ok({ + body: { + rewrittenUrl: req.rewrittenUrl + ? `${req.rewrittenUrl.pathname}${req.rewrittenUrl.search}` + : undefined, + }, + }); }); registerOnPreRouting((req, res, t) => t.rewriteUrl('/login')); @@ -143,7 +149,13 @@ describe('OnPreRouting', () => { const router = createRouter('/'); router.get({ path: '/reroute-2', validate: false }, (context, req, res) => { - return res.ok({ body: { rewrittenUrl: req.rewrittenUrl?.path } }); + return res.ok({ + body: { + rewrittenUrl: req.rewrittenUrl + ? `${req.rewrittenUrl.pathname}${req.rewrittenUrl.search}` + : undefined, + }, + }); }); registerOnPreRouting((req, res, t) => t.rewriteUrl('/reroute-1')); @@ -163,7 +175,13 @@ describe('OnPreRouting', () => { const router = createRouter('/'); router.get({ path: '/login', validate: false }, (context, req, res) => { - return res.ok({ body: { rewrittenUrl: req.rewrittenUrl?.path } }); + return res.ok({ + body: { + rewrittenUrl: req.rewrittenUrl + ? `${req.rewrittenUrl.pathname}${req.rewrittenUrl.search}` + : undefined, + }, + }); }); registerOnPreRouting((req, res, t) => t.next()); diff --git a/src/core/server/http/lifecycle/on_pre_routing.ts b/src/core/server/http/lifecycle/on_pre_routing.ts index 92ae1f0b7bbdf..e553f113a7cf8 100644 --- a/src/core/server/http/lifecycle/on_pre_routing.ts +++ b/src/core/server/http/lifecycle/on_pre_routing.ts @@ -17,6 +17,7 @@ * under the License. */ +import { URL } from 'url'; import { Lifecycle, Request, ResponseToolkit as HapiResponseToolkit } from 'hapi'; import { Logger } from '../../logging'; import { @@ -110,10 +111,30 @@ export function adoptToHapiOnRequest(fn: OnPreRoutingHandler, log: Logger) { if (preRoutingResult.isRewriteUrl(result)) { const appState = request.app as KibanaRequestState; - appState.rewrittenUrl = appState.rewrittenUrl ?? request.url; + appState.rewrittenUrl = + // @ts-expect-error request._core isn't supposed to be accessed - remove once we upgrade to hapi v18 + appState.rewrittenUrl ?? new URL(request.url.href!, request._core.info.uri); const { url } = result; - request.setUrl(url); + + // TODO: Remove once we upgrade to Node.js 12! + // + // Warning: The following for-loop took 10 days to write, and is a hack + // to force V8 to make a copy of the string in memory. + // + // The reason why we need this is because of what appears to be a bug + // in V8 that caused some URL paths to not be routed correctly once + // `request.setUrl` was called with the path. + // + // The details can be seen in this discussion on Twitter: + // https://twitter.com/wa7son/status/1319992632366518277 + let urlCopy = ''; + for (let i = 0; i < url.length; i++) { + urlCopy += url[i]; + } + + request.setUrl(urlCopy); + // We should update raw request as well since it can be proxied to the old platform request.raw.req.url = url; return responseToolkit.continue; diff --git a/src/core/server/http/router/request.ts b/src/core/server/http/router/request.ts index 2d0e8d6c1a6ad..561bf742050c3 100644 --- a/src/core/server/http/router/request.ts +++ b/src/core/server/http/router/request.ts @@ -17,7 +17,7 @@ * under the License. */ -import { Url } from 'url'; +import { URL } from 'url'; import uuid from 'uuid'; import { Request, RouteOptionsApp, ApplicationState } from 'hapi'; import { Observable, fromEvent, merge } from 'rxjs'; @@ -45,7 +45,7 @@ export interface KibanaRouteOptions extends RouteOptionsApp { export interface KibanaRequestState extends ApplicationState { requestId: string; requestUuid: string; - rewrittenUrl?: Url; + rewrittenUrl?: URL; } /** @@ -163,7 +163,7 @@ export class KibanaRequest< */ public readonly uuid: string; /** a WHATWG URL standard object. */ - public readonly url: Url; + public readonly url: URL; /** matched route details */ public readonly route: RecursiveReadonly>; /** @@ -190,7 +190,7 @@ export class KibanaRequest< /** * URL rewritten in onPreRouting request interceptor. */ - public readonly rewrittenUrl?: Url; + public readonly rewrittenUrl?: URL; /** @internal */ protected readonly [requestSymbol]: Request; @@ -212,7 +212,8 @@ export class KibanaRequest< this.uuid = appState?.requestUuid ?? uuid.v4(); this.rewrittenUrl = appState?.rewrittenUrl; - this.url = request.url; + // @ts-expect-error request._core isn't supposed to be accessed - remove once we upgrade to hapi v18 + this.url = new URL(request.url.href!, request._core.info.uri); this.headers = deepFreeze({ ...request.headers }); this.isSystemRequest = request.headers['kbn-system-request'] === 'true' || @@ -304,8 +305,8 @@ export class KibanaRequest< if (authOptions === false) return false; throw new Error( `unexpected authentication options: ${JSON.stringify(authOptions)} for route: ${ - this.url.href - }` + this.url.pathname + }${this.url.search}` ); } } diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index d9dc46d2cad99..914b5fbdb5196 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -162,7 +162,7 @@ import { Type } from '@kbn/config-schema'; import { TypeOf } from '@kbn/config-schema'; import { UpdateDocumentByQueryParams } from 'elasticsearch'; import { UpdateDocumentParams } from 'elasticsearch'; -import { Url } from 'url'; +import { URL } from 'url'; // @public export interface AppCategory { @@ -1007,11 +1007,11 @@ export class KibanaRequest>; // (undocumented) readonly socket: IKibanaSocket; - readonly url: Url; + readonly url: URL; readonly uuid: string; } diff --git a/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts b/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts index 18cbd9f9c5fad..c8e2684651598 100644 --- a/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts +++ b/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts @@ -145,6 +145,12 @@ test('executes the task by calling the executor with proper parameters', async ( url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, }, }); }); @@ -271,6 +277,12 @@ test('uses API key when provided', async () => { url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, }, }); }); @@ -310,6 +322,12 @@ test(`doesn't use API key when not provided`, async () => { url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, }, }); }); diff --git a/x-pack/plugins/actions/server/lib/task_runner_factory.ts b/x-pack/plugins/actions/server/lib/task_runner_factory.ts index aeeeb4ed7d520..93ae5a2c807f9 100644 --- a/x-pack/plugins/actions/server/lib/task_runner_factory.ts +++ b/x-pack/plugins/actions/server/lib/task_runner_factory.ts @@ -102,6 +102,12 @@ export class TaskRunnerFactory { url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, } as unknown) as KibanaRequest; let executorResult: ActionTypeExecutorResult; diff --git a/x-pack/plugins/alerts/server/alerts_client_factory.test.ts b/x-pack/plugins/alerts/server/alerts_client_factory.test.ts index 55c2f3ddd18a4..4e457cdb12bd3 100644 --- a/x-pack/plugins/alerts/server/alerts_client_factory.test.ts +++ b/x-pack/plugins/alerts/server/alerts_client_factory.test.ts @@ -60,6 +60,12 @@ const fakeRequest = ({ url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, getSavedObjectsClient: () => savedObjectsClient, } as unknown) as Request; diff --git a/x-pack/plugins/alerts/server/plugin.test.ts b/x-pack/plugins/alerts/server/plugin.test.ts index b13a1c62f6602..ece7d31d2f7fd 100644 --- a/x-pack/plugins/alerts/server/plugin.test.ts +++ b/x-pack/plugins/alerts/server/plugin.test.ts @@ -149,6 +149,12 @@ describe('Alerting Plugin', () => { url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, getSavedObjectsClient: jest.fn(), } as unknown) as KibanaRequest; await startContract.getAlertsClientWithRequest(fakeRequest); diff --git a/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts b/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts index 8e345d6ff66a8..17d5fcd31b745 100644 --- a/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts +++ b/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts @@ -364,6 +364,12 @@ describe('Task Runner', () => { url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, }); expect(actionsClient.enqueueExecution).toHaveBeenCalledTimes(1); expect(actionsClient.enqueueExecution.mock.calls[0]).toMatchInlineSnapshot(` @@ -662,6 +668,12 @@ describe('Task Runner', () => { url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, }); }); @@ -694,6 +706,12 @@ describe('Task Runner', () => { url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, }); }); diff --git a/x-pack/plugins/alerts/server/task_runner/task_runner.ts b/x-pack/plugins/alerts/server/task_runner/task_runner.ts index 954c5675df89c..76125da20d552 100644 --- a/x-pack/plugins/alerts/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerts/server/task_runner/task_runner.ts @@ -101,6 +101,12 @@ export class TaskRunner { url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, } as unknown) as KibanaRequest; } diff --git a/x-pack/plugins/dashboard_mode/server/interceptors/dashboard_mode_request_interceptor.test.ts b/x-pack/plugins/dashboard_mode/server/interceptors/dashboard_mode_request_interceptor.test.ts index 67fc1a98ad4d1..4b1e4b34da86a 100644 --- a/x-pack/plugins/dashboard_mode/server/interceptors/dashboard_mode_request_interceptor.test.ts +++ b/x-pack/plugins/dashboard_mode/server/interceptors/dashboard_mode_request_interceptor.test.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { parse as parseUrl } from 'url'; import { OnPostAuthHandler, OnPostAuthToolkit, @@ -45,7 +46,7 @@ describe('DashboardOnlyModeRequestInterceptor', () => { test('should not redirects for not app/* requests', async () => { const request = ({ url: { - path: 'api/test', + pathname: 'api/test', }, } as unknown) as KibanaRequest; @@ -57,7 +58,7 @@ describe('DashboardOnlyModeRequestInterceptor', () => { test('should not redirects not authenticated users', async () => { const request = ({ url: { - path: '/app/home', + pathname: '/app/home', }, } as unknown) as KibanaRequest; @@ -70,10 +71,9 @@ describe('DashboardOnlyModeRequestInterceptor', () => { function testRedirectToDashboardModeApp(url: string) { describe(`requests to url:"${url}"`, () => { test('redirects to the dashboard_mode app instead', async () => { + const { pathname, search, hash } = parseUrl(url); const request = ({ - url: { - path: url, - }, + url: { pathname, search, hash }, credentials: { roles: [DASHBOARD_ONLY_MODE_ROLE], }, diff --git a/x-pack/plugins/dashboard_mode/server/interceptors/dashboard_mode_request_interceptor.ts b/x-pack/plugins/dashboard_mode/server/interceptors/dashboard_mode_request_interceptor.ts index 4378c818f087c..9978d18142ff5 100644 --- a/x-pack/plugins/dashboard_mode/server/interceptors/dashboard_mode_request_interceptor.ts +++ b/x-pack/plugins/dashboard_mode/server/interceptors/dashboard_mode_request_interceptor.ts @@ -22,7 +22,7 @@ export const setupDashboardModeRequestInterceptor = ({ getUiSettingsClient, }: DashboardModeRequestInterceptorDependencies) => (async (request, response, toolkit) => { - const path = request.url.path || ''; + const path = request.url.pathname; const isAppRequest = path.startsWith('/app/'); if (!isAppRequest) { diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts index 2bddc9f1c80bd..5bd15ce411002 100644 --- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts @@ -21,7 +21,6 @@ describe('callEnterpriseSearchConfigAPI', () => { accessCheckTimeoutWarning: 100, }; const mockRequest = { - url: { path: '/app/kibana' }, headers: { authorization: '==someAuth' }, }; const mockDependencies = { diff --git a/x-pack/plugins/event_log/server/event_log_client.test.ts b/x-pack/plugins/event_log/server/event_log_client.test.ts index d6793be425585..d9846428b9488 100644 --- a/x-pack/plugins/event_log/server/event_log_client.test.ts +++ b/x-pack/plugins/event_log/server/event_log_client.test.ts @@ -322,6 +322,12 @@ function FakeRequest(): KibanaRequest { url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, getSavedObjectsClient: () => savedObjectGetter, } as unknown) as KibanaRequest; } diff --git a/x-pack/plugins/event_log/server/event_log_start_service.test.ts b/x-pack/plugins/event_log/server/event_log_start_service.test.ts index 0a5b169e87d4d..db6f4a1ad0f27 100644 --- a/x-pack/plugins/event_log/server/event_log_start_service.test.ts +++ b/x-pack/plugins/event_log/server/event_log_start_service.test.ts @@ -56,6 +56,12 @@ function fakeRequest(): KibanaRequest { url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, getSavedObjectsClient: () => savedObjectsClient, } as unknown) as KibanaRequest; } diff --git a/x-pack/plugins/event_log/server/saved_object_provider_registry.test.ts b/x-pack/plugins/event_log/server/saved_object_provider_registry.test.ts index 6a02d54c87514..076260ab2fe53 100644 --- a/x-pack/plugins/event_log/server/saved_object_provider_registry.test.ts +++ b/x-pack/plugins/event_log/server/saved_object_provider_registry.test.ts @@ -93,6 +93,12 @@ function fakeRequest(): KibanaRequest { url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, getSavedObjectsClient: () => savedObjectsClient, } as unknown) as KibanaRequest; } diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy_update.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy_update.ts index fe06de765bbff..1ad710ba70e29 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy_update.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy_update.ts @@ -23,6 +23,12 @@ const fakeRequest = ({ url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, } as unknown) as KibanaRequest; export async function agentPolicyUpdateEventHandler( diff --git a/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_connected_agents.ts b/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_connected_agents.ts index 994ecc64c82a7..b9ef36ecaae54 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_connected_agents.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_connected_agents.ts @@ -23,6 +23,12 @@ function getInternalUserSOClient() { url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, } as unknown) as KibanaRequest; return appContextService.getInternalUserSOClient(fakeRequest); diff --git a/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.ts b/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.ts index aa48d8fe18e9f..c0e8540004930 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.ts @@ -58,6 +58,12 @@ function getInternalUserSOClient() { url: '/', }, }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, } as unknown) as KibanaRequest; return appContextService.getInternalUserSOClient(fakeRequest); diff --git a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts index e0f1b01dafa13..48aed19ea9050 100644 --- a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts +++ b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts @@ -456,16 +456,10 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat }, mlLicense.fullLicenseAPIGuard(async ({ client, request, response }) => { try { - const options: { id: string; force?: boolean | undefined } = { + const { body } = await client.asInternalUser.ml.stopDataFrameAnalytics({ id: request.params.analyticsId, - }; - // @ts-expect-error TODO: update types - if (request.url?.query?.force !== undefined) { - // @ts-expect-error TODO: update types - options.force = request.url.query.force; - } - - const { body } = await client.asInternalUser.ml.stopDataFrameAnalytics(options); + force: request.query.force, + }); return response.ok({ body, }); diff --git a/x-pack/plugins/reporting/server/core.ts b/x-pack/plugins/reporting/server/core.ts index abd86d51fb6b6..d62adc62bc9aa 100644 --- a/x-pack/plugins/reporting/server/core.ts +++ b/x-pack/plugins/reporting/server/core.ts @@ -210,11 +210,18 @@ export class ReportingCore { } public getFakeRequest(baseRequest: object, spaceId: string | undefined, logger = this.logger) { + // @ts-expect-error _core isn't supposed to be accessed - remove once we upgrade to hapi v18 const fakeRequest = KibanaRequest.from({ path: '/', route: { settings: {} }, url: { href: '/' }, raw: { req: { url: '/' } }, + // TODO: Remove once we upgrade to hapi v18 + _core: { + info: { + uri: 'http://localhost', + }, + }, ...baseRequest, } as Hapi.Request); diff --git a/x-pack/plugins/reporting/server/routes/lib/authorized_user_pre_routing.test.ts b/x-pack/plugins/reporting/server/routes/lib/authorized_user_pre_routing.test.ts index cee8a88000e29..cce002a0e6935 100644 --- a/x-pack/plugins/reporting/server/routes/lib/authorized_user_pre_routing.test.ts +++ b/x-pack/plugins/reporting/server/routes/lib/authorized_user_pre_routing.test.ts @@ -27,7 +27,7 @@ const getMockContext = () => const getMockRequest = () => ({ - url: { port: '5601', query: '', path: '/foo' }, + url: { port: '5601', search: '', pathname: '/foo' }, route: { path: '/foo', options: {} }, } as KibanaRequest); diff --git a/x-pack/plugins/security/server/audit/audit_events.test.ts b/x-pack/plugins/security/server/audit/audit_events.test.ts index 1978795f82a24..f153b9efb9d43 100644 --- a/x-pack/plugins/security/server/audit/audit_events.test.ts +++ b/x-pack/plugins/security/server/audit/audit_events.test.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { URL } from 'url'; import { EventOutcome, SavedObjectAction, @@ -192,11 +193,11 @@ describe('#httpRequestEvent', () => { }, "message": "User is requesting [/path] endpoint", "url": Object { - "domain": undefined, + "domain": "localhost", "path": "/path", "port": undefined, "query": undefined, - "scheme": undefined, + "scheme": "http:", }, } `); @@ -211,12 +212,7 @@ describe('#httpRequestEvent', () => { kibanaRequestState: { requestId: '123', requestUuid: '123e4567-e89b-12d3-a456-426614174000', - rewrittenUrl: { - path: '/original/path', - pathname: '/original/path', - query: 'query=param', - search: '?query=param', - }, + rewrittenUrl: new URL('http://localhost/original/path?query=param'), }, }), }) @@ -234,11 +230,11 @@ describe('#httpRequestEvent', () => { }, "message": "User is requesting [/original/path] endpoint", "url": Object { - "domain": undefined, + "domain": "localhost", "path": "/original/path", "port": undefined, "query": "query=param", - "scheme": undefined, + "scheme": "http:", }, } `); diff --git a/x-pack/plugins/security/server/audit/audit_events.ts b/x-pack/plugins/security/server/audit/audit_events.ts index 1ff9da3a95ff4..d91c18bf82e02 100644 --- a/x-pack/plugins/security/server/audit/audit_events.ts +++ b/x-pack/plugins/security/server/audit/audit_events.ts @@ -105,10 +105,10 @@ export interface HttpRequestParams { } export function httpRequestEvent({ request }: HttpRequestParams): AuditEvent { - const { pathname, search } = request.rewrittenUrl ?? request.url; + const url = request.rewrittenUrl ?? request.url; return { - message: `User is requesting [${pathname}] endpoint`, + message: `User is requesting [${url.pathname}] endpoint`, event: { action: 'http_request', category: EventCategory.WEB, @@ -120,11 +120,11 @@ export function httpRequestEvent({ request }: HttpRequestParams): AuditEvent { }, }, url: { - domain: request.url.hostname, - path: pathname, - port: request.url.port ? parseInt(request.url.port, 10) : undefined, - query: search?.slice(1) || undefined, - scheme: request.url.protocol, + domain: url.hostname, + path: url.pathname, + port: url.port ? parseInt(url.port, 10) : undefined, + query: url.search ? url.search.slice(1) : undefined, + scheme: url.protocol, }, }; } diff --git a/x-pack/plugins/security/server/authentication/authenticator.ts b/x-pack/plugins/security/server/authentication/authenticator.ts index 3b587182c491c..80aeb4f8b2959 100644 --- a/x-pack/plugins/security/server/authentication/authenticator.ts +++ b/x-pack/plugins/security/server/authentication/authenticator.ts @@ -333,7 +333,7 @@ export class Authenticator { this.logger.debug('Redirecting request to Login Selector.'); return AuthenticationResult.redirectTo( `${this.options.basePath.serverBasePath}/login?next=${encodeURIComponent( - `${this.options.basePath.get(request)}${request.url.path}` + `${this.options.basePath.get(request)}${request.url.pathname}${request.url.search}` )}` ); } @@ -728,7 +728,7 @@ export class Authenticator { preAccessRedirectURL = `${preAccessRedirectURL}?next=${encodeURIComponent( authenticationResult.redirectURL || redirectURL || - `${this.options.basePath.get(request)}${request.url.path}` + `${this.options.basePath.get(request)}${request.url.pathname}${request.url.search}` )}`; } else if (redirectURL && !authenticationResult.redirectURL) { preAccessRedirectURL = redirectURL; diff --git a/x-pack/plugins/security/server/authentication/providers/basic.test.ts b/x-pack/plugins/security/server/authentication/providers/basic.test.ts index 2481844abb389..87002ebed5672 100644 --- a/x-pack/plugins/security/server/authentication/providers/basic.test.ts +++ b/x-pack/plugins/security/server/authentication/providers/basic.test.ts @@ -101,13 +101,13 @@ describe('BasicAuthenticationProvider', () => { await expect( provider.authenticate( httpServerMock.createKibanaRequest({ - path: '/s/foo/some-path # that needs to be encoded', + path: '/s/foo/some path that needs to be encoded', }), null ) ).resolves.toEqual( AuthenticationResult.redirectTo( - '/mock-server-basepath/login?next=%2Fmock-server-basepath%2Fs%2Ffoo%2Fsome-path%20%23%20that%20needs%20to%20be%20encoded' + '/mock-server-basepath/login?next=%2Fmock-server-basepath%2Fs%2Ffoo%2Fsome%2520path%2520that%2520needs%2520to%2520be%2520encoded' ) ); }); diff --git a/x-pack/plugins/security/server/authentication/providers/basic.ts b/x-pack/plugins/security/server/authentication/providers/basic.ts index 35ab2d242659a..28b671346ee7f 100644 --- a/x-pack/plugins/security/server/authentication/providers/basic.ts +++ b/x-pack/plugins/security/server/authentication/providers/basic.ts @@ -90,7 +90,9 @@ export class BasicAuthenticationProvider extends BaseAuthenticationProvider { * @param [state] Optional state object associated with the provider. */ public async authenticate(request: KibanaRequest, state?: ProviderState | null) { - this.logger.debug(`Trying to authenticate user request to ${request.url.path}.`); + this.logger.debug( + `Trying to authenticate user request to ${request.url.pathname}${request.url.search}.` + ); if (HTTPAuthorizationHeader.parseFromRequest(request) != null) { this.logger.debug('Cannot authenticate requests with `Authorization` header.'); @@ -106,7 +108,9 @@ export class BasicAuthenticationProvider extends BaseAuthenticationProvider { this.logger.debug('Redirecting request to Login page.'); const basePath = this.options.basePath.get(request); return AuthenticationResult.redirectTo( - `${basePath}/login?next=${encodeURIComponent(`${basePath}${request.url.path}`)}` + `${basePath}/login?next=${encodeURIComponent( + `${basePath}${request.url.pathname}${request.url.search}` + )}` ); } @@ -119,7 +123,7 @@ export class BasicAuthenticationProvider extends BaseAuthenticationProvider { * @param [state] Optional state object associated with the provider. */ public async logout(request: KibanaRequest, state?: ProviderState | null) { - this.logger.debug(`Trying to log user out via ${request.url.path}.`); + this.logger.debug(`Trying to log user out via ${request.url.pathname}${request.url.search}.`); // Having a `null` state means that provider was specifically called to do a logout, but when // session isn't defined then provider is just being probed whether or not it can perform logout. diff --git a/x-pack/plugins/security/server/authentication/providers/http.ts b/x-pack/plugins/security/server/authentication/providers/http.ts index 3e33a52cbbc6b..933685d68978f 100644 --- a/x-pack/plugins/security/server/authentication/providers/http.ts +++ b/x-pack/plugins/security/server/authentication/providers/http.ts @@ -56,7 +56,9 @@ export class HTTPAuthenticationProvider extends BaseAuthenticationProvider { * @param request Request instance. */ public async authenticate(request: KibanaRequest) { - this.logger.debug(`Trying to authenticate user request to ${request.url.path}.`); + this.logger.debug( + `Trying to authenticate user request to ${request.url.pathname}${request.url.search}.` + ); const authorizationHeader = HTTPAuthorizationHeader.parseFromRequest(request); if (authorizationHeader == null) { @@ -72,12 +74,12 @@ export class HTTPAuthenticationProvider extends BaseAuthenticationProvider { try { const user = await this.getUser(request); this.logger.debug( - `Request to ${request.url.path} has been authenticated via authorization header with "${authorizationHeader.scheme}" scheme.` + `Request to ${request.url.pathname}${request.url.search} has been authenticated via authorization header with "${authorizationHeader.scheme}" scheme.` ); return AuthenticationResult.succeeded(user); } catch (err) { this.logger.debug( - `Failed to authenticate request to ${request.url.path} via authorization header with "${authorizationHeader.scheme}" scheme: ${err.message}` + `Failed to authenticate request to ${request.url.pathname}${request.url.search} via authorization header with "${authorizationHeader.scheme}" scheme: ${err.message}` ); return AuthenticationResult.failed(err); } diff --git a/x-pack/plugins/security/server/authentication/providers/kerberos.ts b/x-pack/plugins/security/server/authentication/providers/kerberos.ts index 5b593851cc2f2..d7de71f4da9ed 100644 --- a/x-pack/plugins/security/server/authentication/providers/kerberos.ts +++ b/x-pack/plugins/security/server/authentication/providers/kerberos.ts @@ -65,7 +65,9 @@ export class KerberosAuthenticationProvider extends BaseAuthenticationProvider { * @param [state] Optional state object associated with the provider. */ public async authenticate(request: KibanaRequest, state?: ProviderState | null) { - this.logger.debug(`Trying to authenticate user request to ${request.url.path}.`); + this.logger.debug( + `Trying to authenticate user request to ${request.url.pathname}${request.url.search}.` + ); const authorizationHeader = HTTPAuthorizationHeader.parseFromRequest(request); if (authorizationHeader && authorizationHeader.scheme.toLowerCase() !== 'negotiate') { @@ -100,7 +102,7 @@ export class KerberosAuthenticationProvider extends BaseAuthenticationProvider { * @param state State value previously stored by the provider. */ public async logout(request: KibanaRequest, state?: ProviderState | null) { - this.logger.debug(`Trying to log user out via ${request.url.path}.`); + this.logger.debug(`Trying to log user out via ${request.url.pathname}${request.url.search}.`); // Having a `null` state means that provider was specifically called to do a logout, but when // session isn't defined then provider is just being probed whether or not it can perform logout. diff --git a/x-pack/plugins/security/server/authentication/providers/oidc.ts b/x-pack/plugins/security/server/authentication/providers/oidc.ts index 75c909cdcd94b..9570c59f8ea1d 100644 --- a/x-pack/plugins/security/server/authentication/providers/oidc.ts +++ b/x-pack/plugins/security/server/authentication/providers/oidc.ts @@ -166,7 +166,9 @@ export class OIDCAuthenticationProvider extends BaseAuthenticationProvider { * @param [state] Optional state object associated with the provider. */ public async authenticate(request: KibanaRequest, state?: ProviderState | null) { - this.logger.debug(`Trying to authenticate user request to ${request.url.path}.`); + this.logger.debug( + `Trying to authenticate user request to ${request.url.pathname}${request.url.search}.` + ); if (HTTPAuthorizationHeader.parseFromRequest(request) != null) { this.logger.debug('Cannot authenticate requests with `Authorization` header.'); @@ -418,7 +420,7 @@ export class OIDCAuthenticationProvider extends BaseAuthenticationProvider { * @param state State value previously stored by the provider. */ public async logout(request: KibanaRequest, state?: ProviderState | null) { - this.logger.debug(`Trying to log user out via ${request.url.path}.`); + this.logger.debug(`Trying to log user out via ${request.url.pathname}${request.url.search}.`); // Having a `null` state means that provider was specifically called to do a logout, but when // session isn't defined then provider is just being probed whether or not it can perform logout. @@ -477,7 +479,7 @@ export class OIDCAuthenticationProvider extends BaseAuthenticationProvider { `${ this.options.basePath.serverBasePath }/internal/security/capture-url?next=${encodeURIComponent( - `${this.options.basePath.get(request)}${request.url.path}` + `${this.options.basePath.get(request)}${request.url.pathname}${request.url.search}` )}&providerType=${encodeURIComponent(this.type)}&providerName=${encodeURIComponent( this.options.name )}`, diff --git a/x-pack/plugins/security/server/authentication/providers/pki.ts b/x-pack/plugins/security/server/authentication/providers/pki.ts index f3cc21500df26..6dcb448e08150 100644 --- a/x-pack/plugins/security/server/authentication/providers/pki.ts +++ b/x-pack/plugins/security/server/authentication/providers/pki.ts @@ -61,7 +61,9 @@ export class PKIAuthenticationProvider extends BaseAuthenticationProvider { * @param [state] Optional state object associated with the provider. */ public async authenticate(request: KibanaRequest, state?: ProviderState | null) { - this.logger.debug(`Trying to authenticate user request to ${request.url.path}.`); + this.logger.debug( + `Trying to authenticate user request to ${request.url.pathname}${request.url.search}.` + ); if (HTTPAuthorizationHeader.parseFromRequest(request) != null) { this.logger.debug('Cannot authenticate requests with `Authorization` header.'); @@ -105,7 +107,7 @@ export class PKIAuthenticationProvider extends BaseAuthenticationProvider { * @param state State value previously stored by the provider. */ public async logout(request: KibanaRequest, state?: ProviderState | null) { - this.logger.debug(`Trying to log user out via ${request.url.path}.`); + this.logger.debug(`Trying to log user out via ${request.url.pathname}${request.url.search}.`); // Having a `null` state means that provider was specifically called to do a logout, but when // session isn't defined then provider is just being probed whether or not it can perform logout. diff --git a/x-pack/plugins/security/server/authentication/providers/saml.ts b/x-pack/plugins/security/server/authentication/providers/saml.ts index cf6772332b8b6..59a1782c1f1fd 100644 --- a/x-pack/plugins/security/server/authentication/providers/saml.ts +++ b/x-pack/plugins/security/server/authentication/providers/saml.ts @@ -193,7 +193,9 @@ export class SAMLAuthenticationProvider extends BaseAuthenticationProvider { * @param [state] Optional state object associated with the provider. */ public async authenticate(request: KibanaRequest, state?: ProviderState | null) { - this.logger.debug(`Trying to authenticate user request to ${request.url.path}.`); + this.logger.debug( + `Trying to authenticate user request to ${request.url.pathname}${request.url.search}` + ); if (HTTPAuthorizationHeader.parseFromRequest(request) != null) { this.logger.debug('Cannot authenticate requests with `Authorization` header.'); @@ -232,7 +234,7 @@ export class SAMLAuthenticationProvider extends BaseAuthenticationProvider { * @param state State value previously stored by the provider. */ public async logout(request: KibanaRequest, state?: ProviderState | null) { - this.logger.debug(`Trying to log user out via ${request.url.path}.`); + this.logger.debug(`Trying to log user out via ${request.url.pathname}${request.url.search}.`); // Normally when there is no active session in Kibana, `logout` method shouldn't do anything // and user will eventually be redirected to the home page to log in. But when SAML SLO is @@ -631,7 +633,7 @@ export class SAMLAuthenticationProvider extends BaseAuthenticationProvider { `${ this.options.basePath.serverBasePath }/internal/security/capture-url?next=${encodeURIComponent( - `${this.options.basePath.get(request)}${request.url.path}` + `${this.options.basePath.get(request)}${request.url.pathname}${request.url.search}` )}&providerType=${encodeURIComponent(this.type)}&providerName=${encodeURIComponent( this.options.name )}`, diff --git a/x-pack/plugins/security/server/authentication/providers/token.test.ts b/x-pack/plugins/security/server/authentication/providers/token.test.ts index 0264edf4fc082..ffb1c89b24e47 100644 --- a/x-pack/plugins/security/server/authentication/providers/token.test.ts +++ b/x-pack/plugins/security/server/authentication/providers/token.test.ts @@ -173,13 +173,13 @@ describe('TokenAuthenticationProvider', () => { await expect( provider.authenticate( httpServerMock.createKibanaRequest({ - path: '/s/foo/some-path # that needs to be encoded', + path: '/s/foo/some path that needs to be encoded', }), null ) ).resolves.toEqual( AuthenticationResult.redirectTo( - '/mock-server-basepath/login?next=%2Fmock-server-basepath%2Fs%2Ffoo%2Fsome-path%20%23%20that%20needs%20to%20be%20encoded' + '/mock-server-basepath/login?next=%2Fmock-server-basepath%2Fs%2Ffoo%2Fsome%2520path%2520that%2520needs%2520to%2520be%2520encoded' ) ); }); diff --git a/x-pack/plugins/security/server/authentication/providers/token.ts b/x-pack/plugins/security/server/authentication/providers/token.ts index 869fd69173e2e..7dace488bc95a 100644 --- a/x-pack/plugins/security/server/authentication/providers/token.ts +++ b/x-pack/plugins/security/server/authentication/providers/token.ts @@ -92,7 +92,9 @@ export class TokenAuthenticationProvider extends BaseAuthenticationProvider { * @param [state] Optional state object associated with the provider. */ public async authenticate(request: KibanaRequest, state?: ProviderState | null) { - this.logger.debug(`Trying to authenticate user request to ${request.url.path}.`); + this.logger.debug( + `Trying to authenticate user request to ${request.url.pathname}${request.url.search}.` + ); if (HTTPAuthorizationHeader.parseFromRequest(request) != null) { this.logger.debug('Cannot authenticate requests with `Authorization` header.'); @@ -126,7 +128,7 @@ export class TokenAuthenticationProvider extends BaseAuthenticationProvider { * @param state State value previously stored by the provider. */ public async logout(request: KibanaRequest, state?: ProviderState | null) { - this.logger.debug(`Trying to log user out via ${request.url.path}.`); + this.logger.debug(`Trying to log user out via ${request.url.pathname}${request.url.search}.`); // Having a `null` state means that provider was specifically called to do a logout, but when // session isn't defined then provider is just being probed whether or not it can perform logout. @@ -241,7 +243,9 @@ export class TokenAuthenticationProvider extends BaseAuthenticationProvider { * @param request Request instance. */ private getLoginPageURL(request: KibanaRequest) { - const nextURL = encodeURIComponent(`${this.options.basePath.get(request)}${request.url.path}`); + const nextURL = encodeURIComponent( + `${this.options.basePath.get(request)}${request.url.pathname}${request.url.search}` + ); return `${this.options.basePath.get(request)}/login?next=${nextURL}`; } } diff --git a/x-pack/plugins/security/server/authorization/api_authorization.ts b/x-pack/plugins/security/server/authorization/api_authorization.ts index 813ed8d064d94..9cf090ab271ae 100644 --- a/x-pack/plugins/security/server/authorization/api_authorization.ts +++ b/x-pack/plugins/security/server/authorization/api_authorization.ts @@ -33,11 +33,13 @@ export function initAPIAuthorization( // we've actually authorized the request if (checkPrivilegesResponse.hasAllRequested) { - logger.debug(`User authorized for "${request.url.path}"`); + logger.debug(`User authorized for "${request.url.pathname}${request.url.search}"`); return toolkit.next(); } - logger.warn(`User not authorized for "${request.url.path}": responding with 403`); + logger.warn( + `User not authorized for "${request.url.pathname}${request.url.search}": responding with 403` + ); return response.forbidden(); }); } diff --git a/x-pack/plugins/security/server/authorization/authorization_service.tsx b/x-pack/plugins/security/server/authorization/authorization_service.tsx index 9547295af4dfb..a45bca90d8b56 100644 --- a/x-pack/plugins/security/server/authorization/authorization_service.tsx +++ b/x-pack/plugins/security/server/authorization/authorization_service.tsx @@ -168,7 +168,7 @@ export class AuthorizationService { http.registerOnPreResponse((request, preResponse, toolkit) => { if (preResponse.statusCode === 403 && canRedirectRequest(request)) { const basePath = http.basePath.get(request); - const next = `${basePath}${request.url.path}`; + const next = `${basePath}${request.url.pathname}${request.url.search}`; const regularBundlePath = `${basePath}/${buildNumber}/bundles`; const logoutUrl = http.basePath.prepend( diff --git a/x-pack/plugins/security/server/routes/authentication/oidc.ts b/x-pack/plugins/security/server/routes/authentication/oidc.ts index 5d8a7ae7bdfea..7eaa619b330e0 100644 --- a/x-pack/plugins/security/server/routes/authentication/oidc.ts +++ b/x-pack/plugins/security/server/routes/authentication/oidc.ts @@ -135,7 +135,7 @@ export function defineOIDCRoutes({ loginAttempt = { type: OIDCLogin.LoginWithAuthorizationCodeFlow, // We pass the path only as we can't be sure of the full URL and Elasticsearch doesn't need it anyway. - authenticationResponseURI: request.url.path!, + authenticationResponseURI: request.url.pathname + request.url.search, }; } else if (request.query.iss) { logger.warn( diff --git a/x-pack/plugins/security/server/routes/views/login.test.ts b/x-pack/plugins/security/server/routes/views/login.test.ts index fee3adbb19f97..b90a44be7aade 100644 --- a/x-pack/plugins/security/server/routes/views/login.test.ts +++ b/x-pack/plugins/security/server/routes/views/login.test.ts @@ -100,7 +100,7 @@ describe('Login view routes', () => { auth: { isAuthenticated: true }, }); (request as any).url = new URL( - `${request.url.path}${request.url.search}`, + `${request.url.pathname}${request.url.search}`, 'https://kibana.co' ); license.getFeatures.mockReturnValue({ showLogin: true } as any); @@ -114,7 +114,7 @@ describe('Login view routes', () => { // Redirect if `showLogin` is `false` even if user is not authenticated. request = httpServerMock.createKibanaRequest({ query, auth: { isAuthenticated: false } }); (request as any).url = new URL( - `${request.url.path}${request.url.search}`, + `${request.url.pathname}${request.url.search}`, 'https://kibana.co' ); license.getFeatures.mockReturnValue({ showLogin: false } as any); diff --git a/x-pack/plugins/spaces/server/lib/request_interceptors/on_post_auth_interceptor.ts b/x-pack/plugins/spaces/server/lib/request_interceptors/on_post_auth_interceptor.ts index e3a724e153688..1aa2011a15b35 100644 --- a/x-pack/plugins/spaces/server/lib/request_interceptors/on_post_auth_interceptor.ts +++ b/x-pack/plugins/spaces/server/lib/request_interceptors/on_post_auth_interceptor.ts @@ -28,7 +28,7 @@ export function initSpacesOnPostAuthRequestInterceptor({ http.registerOnPostAuth(async (request, response, toolkit) => { const serverBasePath = http.basePath.serverBasePath; - const path = request.url.pathname!; + const path = request.url.pathname; const spaceId = spacesService.getSpaceId(request); diff --git a/x-pack/plugins/spaces/server/lib/request_interceptors/on_request_interceptor.ts b/x-pack/plugins/spaces/server/lib/request_interceptors/on_request_interceptor.ts index 6408803c2114b..a3335b1e075f2 100644 --- a/x-pack/plugins/spaces/server/lib/request_interceptors/on_request_interceptor.ts +++ b/x-pack/plugins/spaces/server/lib/request_interceptors/on_request_interceptor.ts @@ -9,8 +9,6 @@ import { LifecycleResponseFactory, CoreSetup, } from 'src/core/server'; -import { format } from 'url'; -import { modifyUrl } from '../utils/url'; import { getSpaceIdFromPath } from '../../../common'; export interface OnRequestInterceptorDeps { @@ -34,16 +32,9 @@ export function initSpacesOnRequestInterceptor({ http }: OnRequestInterceptorDep http.basePath.set(request, reqBasePath); - const newLocation = (path && path.substr(reqBasePath.length)) || '/'; + const newPathname = path.substr(reqBasePath.length) || '/'; - const newUrl = modifyUrl(format(request.url), (parts) => { - return { - ...parts, - pathname: newLocation, - }; - }); - - return toolkit.rewriteUrl(newUrl); + return toolkit.rewriteUrl(`${newPathname}${request.url.search}`); } return toolkit.next(); diff --git a/x-pack/plugins/spaces/server/spaces_service/spaces_service.test.ts b/x-pack/plugins/spaces/server/spaces_service/spaces_service.test.ts index b48bf971d0c1b..d1e1d81134940 100644 --- a/x-pack/plugins/spaces/server/spaces_service/spaces_service.test.ts +++ b/x-pack/plugins/spaces/server/spaces_service/spaces_service.test.ts @@ -58,7 +58,7 @@ const createService = async (serverBasePath: string = '') => { serverBasePath, } as HttpServiceSetup['basePath']; httpSetup.basePath.get = jest.fn().mockImplementation((request: KibanaRequest) => { - const { spaceId } = getSpaceIdFromPath(request.url.path); + const { spaceId } = getSpaceIdFromPath(request.url.pathname); if (spaceId !== DEFAULT_SPACE_ID) { return `/s/${spaceId}`; @@ -83,7 +83,7 @@ describe('SpacesService', () => { const spacesServiceSetup = await createService(); const request: KibanaRequest = { - url: { path: '/app/kibana' }, + url: { pathname: '/app/kibana' }, } as KibanaRequest; expect(spacesServiceSetup.getSpaceId(request)).toEqual(DEFAULT_SPACE_ID); @@ -93,7 +93,7 @@ describe('SpacesService', () => { const spacesServiceSetup = await createService(); const request: KibanaRequest = { - url: { path: '/s/foo/app/kibana' }, + url: { pathname: '/s/foo/app/kibana' }, } as KibanaRequest; expect(spacesServiceSetup.getSpaceId(request)).toEqual('foo'); @@ -140,7 +140,7 @@ describe('SpacesService', () => { const spacesServiceSetup = await createService(); const request: KibanaRequest = { - url: { path: '/app/kibana' }, + url: { pathname: '/app/kibana' }, } as KibanaRequest; expect(spacesServiceSetup.isInDefaultSpace(request)).toEqual(true); @@ -150,7 +150,7 @@ describe('SpacesService', () => { const spacesServiceSetup = await createService(); const request: KibanaRequest = { - url: { path: '/s/foo/app/kibana' }, + url: { pathname: '/s/foo/app/kibana' }, } as KibanaRequest; expect(spacesServiceSetup.isInDefaultSpace(request)).toEqual(false); From 2d49dea005847cac6855deb7c41ab18241af02e6 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Thu, 29 Oct 2020 08:53:12 -0500 Subject: [PATCH 27/80] [deb/rpm] set logging.dest (#74896) Co-authored-by: Elastic Machine --- .../tasks/os_packages/package_scripts/post_install.sh | 9 ++++++--- src/dev/build/tasks/os_packages/run_fpm.ts | 2 ++ .../systemd/etc/systemd/system/kibana.service | 2 +- .../os_packages/service_templates/sysv/etc/init.d/kibana | 9 +++------ 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/dev/build/tasks/os_packages/package_scripts/post_install.sh b/src/dev/build/tasks/os_packages/package_scripts/post_install.sh index 1c679bdb40b59..939226b565f79 100644 --- a/src/dev/build/tasks/os_packages/package_scripts/post_install.sh +++ b/src/dev/build/tasks/os_packages/package_scripts/post_install.sh @@ -7,14 +7,17 @@ set_chmod() { chmod -f 660 ${KBN_PATH_CONF}/kibana.yml || true chmod -f 2750 <%= dataDir %> || true chmod -f 2750 ${KBN_PATH_CONF} || true + chmod -f 2750 <%= logDir %> || true } set_chown() { + chown <%= user %>:<%= group %> <%= logDir %> chown -R <%= user %>:<%= group %> <%= dataDir %> chown -R root:<%= group %> ${KBN_PATH_CONF} } -set_access() { +setup() { + [ ! -d "<%= logDir %>" ] && mkdir "<%= logDir %>" set_chmod set_chown } @@ -35,7 +38,7 @@ case $1 in IS_UPGRADE=true fi - set_access + setup ;; abort-deconfigure|abort-upgrade|abort-remove) ;; @@ -55,7 +58,7 @@ case $1 in IS_UPGRADE=true fi - set_access + setup ;; *) diff --git a/src/dev/build/tasks/os_packages/run_fpm.ts b/src/dev/build/tasks/os_packages/run_fpm.ts index b5169ec3d43b6..b8289f1da194f 100644 --- a/src/dev/build/tasks/os_packages/run_fpm.ts +++ b/src/dev/build/tasks/os_packages/run_fpm.ts @@ -109,6 +109,8 @@ export async function runFpm( `pluginsDir=/usr/share/kibana/plugins`, '--template-value', `dataDir=/var/lib/kibana`, + '--template-value', + `logDir=/var/log/kibana`, // config and data directories are copied to /usr/share and /var/lib // below, so exclude them from the main package source located in diff --git a/src/dev/build/tasks/os_packages/service_templates/systemd/etc/systemd/system/kibana.service b/src/dev/build/tasks/os_packages/service_templates/systemd/etc/systemd/system/kibana.service index df33b82f1f967..05724db8799f3 100644 --- a/src/dev/build/tasks/os_packages/service_templates/systemd/etc/systemd/system/kibana.service +++ b/src/dev/build/tasks/os_packages/service_templates/systemd/etc/systemd/system/kibana.service @@ -15,7 +15,7 @@ Environment=KBN_PATH_CONF=/etc/kibana EnvironmentFile=-/etc/default/kibana EnvironmentFile=-/etc/sysconfig/kibana -ExecStart=/usr/share/kibana/bin/kibana +ExecStart=/usr/share/kibana/bin/kibana --logging.dest="/var/log/kibana/kibana.log" Restart=on-failure RestartSec=3 diff --git a/src/dev/build/tasks/os_packages/service_templates/sysv/etc/init.d/kibana b/src/dev/build/tasks/os_packages/service_templates/sysv/etc/init.d/kibana index c13676ef031b0..eedd4898ce6c3 100755 --- a/src/dev/build/tasks/os_packages/service_templates/sysv/etc/init.d/kibana +++ b/src/dev/build/tasks/os_packages/service_templates/sysv/etc/init.d/kibana @@ -35,6 +35,7 @@ fi name=kibana program=/usr/share/kibana/bin/kibana +args="--logging.dest=/var/log/kibana/kibana.log" pidfile="/var/run/kibana/$name.pid" [ -r /etc/default/$name ] && . /etc/default/$name @@ -55,10 +56,6 @@ emit() { } start() { - [ ! -d "/var/log/kibana/" ] && mkdir "/var/log/kibana/" - chown "$user":"$group" "/var/log/kibana/" - chmod 2750 "/var/log/kibana/" - [ ! -d "/var/run/kibana/" ] && mkdir "/var/run/kibana/" chown "$user":"$group" "/var/run/kibana/" chmod 755 "/var/run/kibana/" @@ -66,8 +63,8 @@ start() { chroot --userspec "$user":"$group" "$chroot" sh -c " cd \"$chdir\" - exec \"$program\" - " >> /var/log/kibana/kibana.stdout 2>> /var/log/kibana/kibana.stderr & + exec \"$program $args\" + " >> /var/log/kibana/kibana.log 2>&1 & # Generate the pidfile from here. If we instead made the forked process # generate it there will be a race condition between the pidfile writing From 40fc944f30b121a6986df50dd30ef77ad90aad41 Mon Sep 17 00:00:00 2001 From: Sandra Gonzales Date: Thu, 29 Oct 2020 10:32:13 -0400 Subject: [PATCH 28/80] add experimental when getting packages, add integration tests for side effects like recreation of index patterns (#81940) --- .../server/services/epm/packages/get.ts | 2 +- .../apis/epm/install_remove_multiple.ts | 106 ++++++++++++++++++ .../data_stream/test_logs/fields/ecs.yml | 3 + .../data_stream/test_logs/fields/fields.yml | 16 +++ .../0.1.0/data_stream/test_logs/manifest.yml | 9 ++ .../data_stream/test_metrics/fields/ecs.yml | 3 + .../test_metrics/fields/fields.yml | 16 +++ .../data_stream/test_metrics/manifest.yml | 3 + .../experimental/0.1.0/docs/README.md | 3 + .../0.1.0/img/logo_overrides_64_color.svg | 7 ++ .../experimental/0.1.0/manifest.yml | 20 ++++ .../data_stream/test_logs/fields/ecs.yml | 3 + .../data_stream/test_logs/fields/fields.yml | 16 +++ .../0.1.0/data_stream/test_logs/manifest.yml | 9 ++ .../data_stream/test_metrics/fields/ecs.yml | 3 + .../test_metrics/fields/fields.yml | 16 +++ .../data_stream/test_metrics/manifest.yml | 3 + .../experimental2/0.1.0/docs/README.md | 3 + .../0.1.0/img/logo_overrides_64_color.svg | 7 ++ .../experimental2/0.1.0/manifest.yml | 20 ++++ 20 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_multiple.ts create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_logs/fields/ecs.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_logs/fields/fields.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_logs/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_metrics/fields/ecs.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_metrics/fields/fields.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_metrics/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/docs/README.md create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/img/logo_overrides_64_color.svg create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_logs/fields/ecs.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_logs/fields/fields.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_logs/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_metrics/fields/ecs.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_metrics/fields/fields.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_metrics/manifest.yml create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/docs/README.md create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/img/logo_overrides_64_color.svg create mode 100644 x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/manifest.yml diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts index 2cf94e9c16079..cd0dcba7b97b2 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts @@ -86,7 +86,7 @@ export async function getPackageKeysByStatus( savedObjectsClient: SavedObjectsClientContract, status: InstallationStatus ) { - const allPackages = await getPackages({ savedObjectsClient }); + const allPackages = await getPackages({ savedObjectsClient, experimental: true }); return allPackages.reduce>((acc, pkg) => { if (pkg.status === status) { if (pkg.status === InstallationStatus.installed) { diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_multiple.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_multiple.ts new file mode 100644 index 0000000000000..82072f59a482b --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_multiple.ts @@ -0,0 +1,106 @@ +/* + * 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 expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; +import { skipIfNoDockerRegistry } from '../../helpers'; + +export default function (providerContext: FtrProviderContext) { + const { getService } = providerContext; + const kibanaServer = getService('kibanaServer'); + const supertest = getService('supertest'); + const dockerServers = getService('dockerServers'); + const server = dockerServers.get('registry'); + const pkgName = 'all_assets'; + const pkgVersion = '0.1.0'; + const pkgKey = `${pkgName}-${pkgVersion}`; + const experimentalPkgName = 'experimental'; + const experimentalPkgKey = `${experimentalPkgName}-${pkgVersion}`; + const experimental2PkgName = 'experimental2'; + const experimental2PkgKey = `${experimental2PkgName}-${pkgVersion}`; + + const uninstallPackage = async (pkg: string) => { + await supertest.delete(`/api/fleet/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx'); + }; + const installPackage = async (pkg: string) => { + await supertest + .post(`/api/fleet/epm/packages/${pkg}`) + .set('kbn-xsrf', 'xxxx') + .send({ force: true }); + }; + + const installPackages = async (pkgs: string[]) => { + const installingPackagesPromise = pkgs.map((pkg) => installPackage(pkg)); + return Promise.all(installingPackagesPromise); + }; + const uninstallPackages = async (pkgs: string[]) => { + const uninstallingPackagesPromise = pkgs.map((pkg) => uninstallPackage(pkg)); + return Promise.all(uninstallingPackagesPromise); + }; + const expectPkgFieldToExist = async ( + fields: any[], + fieldName: string, + exists: boolean = true + ) => { + const fieldExists = fields.find((field: { name: string }) => field.name === fieldName); + if (exists) { + expect(fieldExists).not.to.be(undefined); + } else { + expect(fieldExists).to.be(undefined); + } + }; + describe('installs and uninstalls multiple packages side effects', async () => { + skipIfNoDockerRegistry(providerContext); + before(async () => { + if (!server.enabled) return; + await installPackages([pkgKey, experimentalPkgKey, experimental2PkgKey]); + }); + after(async () => { + if (!server.enabled) return; + await uninstallPackages([pkgKey, experimentalPkgKey, experimental2PkgKey]); + }); + it('should create index patterns from all installed packages, experimental or beta', async () => { + const resIndexPatternLogs = await kibanaServer.savedObjects.get({ + type: 'index-pattern', + id: 'logs-*', + }); + + const fieldsLogs = JSON.parse(resIndexPatternLogs.attributes.fields); + + expectPkgFieldToExist(fieldsLogs, 'logs_test_name'); + expectPkgFieldToExist(fieldsLogs, 'logs_experimental_name'); + expectPkgFieldToExist(fieldsLogs, 'logs_experimental2_name'); + const resIndexPatternMetrics = await kibanaServer.savedObjects.get({ + type: 'index-pattern', + id: 'metrics-*', + }); + const fieldsMetrics = JSON.parse(resIndexPatternMetrics.attributes.fields); + expectPkgFieldToExist(fieldsMetrics, 'metrics_test_name'); + expectPkgFieldToExist(fieldsMetrics, 'metrics_experimental_name'); + expectPkgFieldToExist(fieldsMetrics, 'metrics_experimental2_name'); + }); + it('should correctly recreate index patterns when a package is uninstalled', async () => { + await uninstallPackage(experimental2PkgKey); + const resIndexPatternLogs = await kibanaServer.savedObjects.get({ + type: 'index-pattern', + id: 'logs-*', + }); + const fields = JSON.parse(resIndexPatternLogs.attributes.fields); + expectPkgFieldToExist(fields, 'logs_test_name'); + expectPkgFieldToExist(fields, 'logs_experimental_name'); + expectPkgFieldToExist(fields, 'logs_experimental2_name', false); + const resIndexPatternMetrics = await kibanaServer.savedObjects.get({ + type: 'index-pattern', + id: 'metrics-*', + }); + const fieldsMetrics = JSON.parse(resIndexPatternMetrics.attributes.fields); + + expectPkgFieldToExist(fieldsMetrics, 'metrics_test_name'); + expectPkgFieldToExist(fieldsMetrics, 'metrics_experimental_name'); + expectPkgFieldToExist(fieldsMetrics, 'metrics_experimental2_name', false); + }); + }); +} diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_logs/fields/ecs.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_logs/fields/ecs.yml new file mode 100644 index 0000000000000..4c18291b7c5ad --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_logs/fields/ecs.yml @@ -0,0 +1,3 @@ +- name: logs_experimental_name + title: logs_experimental_title + type: keyword \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_logs/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_logs/fields/fields.yml new file mode 100644 index 0000000000000..6e003ed0ad147 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_logs/fields/fields.yml @@ -0,0 +1,16 @@ +- name: data_stream.type + type: constant_keyword + description: > + Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: > + Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: > + Data stream namespace. +- name: '@timestamp' + type: date + description: > + Event timestamp. diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_logs/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_logs/manifest.yml new file mode 100644 index 0000000000000..9ac3c68a0be9e --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_logs/manifest.yml @@ -0,0 +1,9 @@ +title: Test Dataset + +type: logs + +elasticsearch: + index_template.mappings: + dynamic: false + index_template.settings: + index.lifecycle.name: reference diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_metrics/fields/ecs.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_metrics/fields/ecs.yml new file mode 100644 index 0000000000000..3cd2db230f437 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_metrics/fields/ecs.yml @@ -0,0 +1,3 @@ +- name: metrics_experimental_name + title: metrics_experimental_title + type: keyword \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_metrics/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_metrics/fields/fields.yml new file mode 100644 index 0000000000000..6e003ed0ad147 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_metrics/fields/fields.yml @@ -0,0 +1,16 @@ +- name: data_stream.type + type: constant_keyword + description: > + Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: > + Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: > + Data stream namespace. +- name: '@timestamp' + type: date + description: > + Event timestamp. diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_metrics/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_metrics/manifest.yml new file mode 100644 index 0000000000000..6bc20442bd432 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/data_stream/test_metrics/manifest.yml @@ -0,0 +1,3 @@ +title: Test Dataset + +type: metrics \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/docs/README.md b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/docs/README.md new file mode 100644 index 0000000000000..8e524c4c71b5f --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/docs/README.md @@ -0,0 +1,3 @@ +# Test package + +For testing side effects when installing and removing multiple packages diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/img/logo_overrides_64_color.svg b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/img/logo_overrides_64_color.svg new file mode 100644 index 0000000000000..b03007a76ffcc --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/img/logo_overrides_64_color.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/manifest.yml new file mode 100644 index 0000000000000..9c83569a69cbe --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental/0.1.0/manifest.yml @@ -0,0 +1,20 @@ +format_version: 1.0.0 +name: experimental +title: experimental integration +description: This is a test package for testing experimental packages +version: 0.1.0 +categories: [] +release: experimental +type: integration +license: basic + +requirement: + elasticsearch: + versions: '>7.7.0' + kibana: + versions: '>7.7.0' + +icons: + - src: '/img/logo_overrides_64_color.svg' + size: '16x16' + type: 'image/svg+xml' diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_logs/fields/ecs.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_logs/fields/ecs.yml new file mode 100644 index 0000000000000..dad07fa9637af --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_logs/fields/ecs.yml @@ -0,0 +1,3 @@ +- name: logs_experimental2_name + title: logs_experimental2_title + type: keyword \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_logs/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_logs/fields/fields.yml new file mode 100644 index 0000000000000..6e003ed0ad147 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_logs/fields/fields.yml @@ -0,0 +1,16 @@ +- name: data_stream.type + type: constant_keyword + description: > + Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: > + Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: > + Data stream namespace. +- name: '@timestamp' + type: date + description: > + Event timestamp. diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_logs/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_logs/manifest.yml new file mode 100644 index 0000000000000..9ac3c68a0be9e --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_logs/manifest.yml @@ -0,0 +1,9 @@ +title: Test Dataset + +type: logs + +elasticsearch: + index_template.mappings: + dynamic: false + index_template.settings: + index.lifecycle.name: reference diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_metrics/fields/ecs.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_metrics/fields/ecs.yml new file mode 100644 index 0000000000000..0b6a2efaacd33 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_metrics/fields/ecs.yml @@ -0,0 +1,3 @@ +- name: metrics_experimental2_name + title: metrics_experimental2_title + type: keyword \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_metrics/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_metrics/fields/fields.yml new file mode 100644 index 0000000000000..6e003ed0ad147 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_metrics/fields/fields.yml @@ -0,0 +1,16 @@ +- name: data_stream.type + type: constant_keyword + description: > + Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: > + Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: > + Data stream namespace. +- name: '@timestamp' + type: date + description: > + Event timestamp. diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_metrics/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_metrics/manifest.yml new file mode 100644 index 0000000000000..6bc20442bd432 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/data_stream/test_metrics/manifest.yml @@ -0,0 +1,3 @@ +title: Test Dataset + +type: metrics \ No newline at end of file diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/docs/README.md b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/docs/README.md new file mode 100644 index 0000000000000..8e524c4c71b5f --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/docs/README.md @@ -0,0 +1,3 @@ +# Test package + +For testing side effects when installing and removing multiple packages diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/img/logo_overrides_64_color.svg b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/img/logo_overrides_64_color.svg new file mode 100644 index 0000000000000..b03007a76ffcc --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/img/logo_overrides_64_color.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/manifest.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/manifest.yml new file mode 100644 index 0000000000000..766835dbde037 --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/experimental2/0.1.0/manifest.yml @@ -0,0 +1,20 @@ +format_version: 1.0.0 +name: experimental2 +title: experimental integration +description: This is a test package for testing experimental packages +version: 0.1.0 +categories: [] +release: experimental +type: integration +license: basic + +requirement: + elasticsearch: + versions: '>7.7.0' + kibana: + versions: '>7.7.0' + +icons: + - src: '/img/logo_overrides_64_color.svg' + size: '16x16' + type: 'image/svg+xml' From 6bff52c66e4e9482b712abacb55a40eb722cc075 Mon Sep 17 00:00:00 2001 From: Andrew Cholakian Date: Thu, 29 Oct 2020 09:46:23 -0500 Subject: [PATCH 29/80] [Uptime] Fix broken overview page when no summary data present (#81952) Fixes https://github.com/elastic/kibana/issues/81950 by not assuming the summary is present in a bucket with partial check info --- .../search/refine_potential_matches.ts | 6 +++++ .../uptime/rest/monitor_states_generated.ts | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts b/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts index 98db43c5b2623..a864bfa591424 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts @@ -38,6 +38,12 @@ export const fullyMatchingIds = (queryResult: any, statusFilter?: string): Monit for (const locBucket of monBucket.location.buckets) { const latest = locBucket.summaries.latest.hits.hits[0]; + // It is possible for no latest summary to exist in this bucket if only partial + // non-summary docs exist + if (!latest) { + continue; + } + const latestStillMatching = locBucket.latest_matching.top.hits.hits[0]; // If the most recent document still matches the most recent document matching the current filters // we can include this in the result diff --git a/x-pack/test/api_integration/apis/uptime/rest/monitor_states_generated.ts b/x-pack/test/api_integration/apis/uptime/rest/monitor_states_generated.ts index 3e06373042d59..69571099a2642 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/monitor_states_generated.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/monitor_states_generated.ts @@ -24,6 +24,30 @@ export default function ({ getService }: FtrProviderContext) { before('load heartbeat data', () => getService('esArchiver').load('uptime/blank')); after('unload heartbeat index', () => getService('esArchiver').unload('uptime/blank')); + // In this case we don't actually have any monitors to display + // but the query should still return successfully. This has + // caused bugs in the past because a bucket of monitor data + // was available and the query code assumed at least one + // event would be a summary for each monitor. + // See https://github.com/elastic/kibana/issues/81950 + describe('checks with no summaries', async () => { + const testMonitorId = 'scope-test-id'; + before(async () => { + const es = getService('legacyEs'); + dateRangeStart = new Date().toISOString(); + await makeChecksWithStatus(es, testMonitorId, 1, numIps, 1, {}, 'up', (d) => { + delete d.summary; + return d; + }); + }); + + it('should return no monitors and have no errors', async () => { + const url = getBaseUrl(dateRangeStart, new Date().toISOString()); + const apiResponse = await supertest.get(url); + expect(apiResponse.status).to.equal(200); + }); + }); + describe('query document scoping with mismatched check statuses', async () => { let checks: any[] = []; let nonSummaryIp: string | null = null; From b5e3e18ea4b478f5a7dfb4b3a8bfa66ebed07fad Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Thu, 29 Oct 2020 10:48:49 -0400 Subject: [PATCH 30/80] [Lens] Stop using multi-level metrics in Lens pie charts (#81523) * [Lens] Stop using multi-level metrics in Lens * Fix linting * Simplify even more --- .../indexpattern.test.ts | 58 ++++++++++- .../indexpattern_datasource/to_expression.ts | 24 +---- .../pie_visualization/render_function.tsx | 41 +++----- .../pie_visualization/render_helpers.test.ts | 95 ++++++------------- .../pie_visualization/render_helpers.ts | 13 +-- .../lens/public/pie_visualization/types.ts | 6 -- 6 files changed, 99 insertions(+), 138 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts index 900cd02622aaf..77dc6f97fb236 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts @@ -319,10 +319,10 @@ describe('IndexPattern Data Source', () => { "1", ], "metricsAtAllLevels": Array [ - true, + false, ], "partialRows": Array [ - true, + false, ], "timeFields": Array [ "timestamp", @@ -334,7 +334,7 @@ describe('IndexPattern Data Source', () => { Object { "arguments": Object { "idMap": Array [ - "{\\"col--1-col1\\":{\\"label\\":\\"Count of records\\",\\"dataType\\":\\"number\\",\\"isBucketed\\":false,\\"sourceField\\":\\"Records\\",\\"operationType\\":\\"count\\",\\"id\\":\\"col1\\"},\\"col-2-col2\\":{\\"label\\":\\"Date\\",\\"dataType\\":\\"date\\",\\"isBucketed\\":true,\\"operationType\\":\\"date_histogram\\",\\"sourceField\\":\\"timestamp\\",\\"params\\":{\\"interval\\":\\"1d\\"},\\"id\\":\\"col2\\"}}", + "{\\"col-0-col1\\":{\\"label\\":\\"Count of records\\",\\"dataType\\":\\"number\\",\\"isBucketed\\":false,\\"sourceField\\":\\"Records\\",\\"operationType\\":\\"count\\",\\"id\\":\\"col1\\"},\\"col-1-col2\\":{\\"label\\":\\"Date\\",\\"dataType\\":\\"date\\",\\"isBucketed\\":true,\\"operationType\\":\\"date_histogram\\",\\"sourceField\\":\\"timestamp\\",\\"params\\":{\\"interval\\":\\"1d\\"},\\"id\\":\\"col2\\"}}", ], }, "function": "lens_rename_columns", @@ -392,6 +392,58 @@ describe('IndexPattern Data Source', () => { expect(ast.chain[0].arguments.timeFields).toEqual(['timestamp', 'another_datefield']); }); + it('should rename the output from esaggs when using flat query', () => { + const queryBaseState: IndexPatternBaseState = { + currentIndexPatternId: '1', + layers: { + first: { + indexPatternId: '1', + columnOrder: ['bucket1', 'bucket2', 'metric'], + columns: { + metric: { + label: 'Count of records', + dataType: 'number', + isBucketed: false, + sourceField: 'Records', + operationType: 'count', + }, + bucket1: { + label: 'Date', + dataType: 'date', + isBucketed: true, + operationType: 'date_histogram', + sourceField: 'timestamp', + params: { + interval: '1d', + }, + }, + bucket2: { + label: 'Terms', + dataType: 'string', + isBucketed: true, + operationType: 'terms', + sourceField: 'geo.src', + params: { + orderBy: { type: 'alphabetical' }, + orderDirection: 'asc', + size: 10, + }, + }, + }, + }, + }, + }; + + const state = enrichBaseState(queryBaseState); + const ast = indexPatternDatasource.toExpression(state, 'first') as Ast; + expect(ast.chain[0].arguments.metricsAtAllLevels).toEqual([false]); + expect(JSON.parse(ast.chain[1].arguments.idMap[0] as string)).toEqual({ + 'col-0-bucket1': expect.any(Object), + 'col-1-bucket2': expect.any(Object), + 'col-2-metric': expect.any(Object), + }); + }); + it('should not put date fields used outside date_histograms to the esaggs timeFields parameter', async () => { const queryBaseState: IndexPatternBaseState = { currentIndexPatternId: '1', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts b/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts index e2c4323b56c2a..ea7aa62054e5c 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts @@ -29,34 +29,16 @@ function getExpressionForLayer( } const columnEntries = columnOrder.map((colId) => [colId, columns[colId]] as const); - const bucketsCount = columnEntries.filter(([, entry]) => entry.isBucketed).length; - const metricsCount = columnEntries.length - bucketsCount; if (columnEntries.length) { const aggs = columnEntries.map(([colId, col]) => { return getEsAggsConfig(col, colId); }); - /** - * Because we are turning on metrics at all levels, the sequence generation - * logic here is more complicated. Examples follow: - * - * Example 1: [Count] - * Output: [`col-0-count`] - * - * Example 2: [Terms, Terms, Count] - * Output: [`col-0-terms0`, `col-2-terms1`, `col-3-count`] - * - * Example 3: [Terms, Terms, Count, Max] - * Output: [`col-0-terms0`, `col-3-terms1`, `col-4-count`, `col-5-max`] - */ const idMap = columnEntries.reduce((currentIdMap, [colId, column], index) => { - const newIndex = column.isBucketed - ? index * (metricsCount + 1) // Buckets are spaced apart by N + 1 - : (index ? index + 1 : 0) - bucketsCount + (bucketsCount - 1) * (metricsCount + 1); return { ...currentIdMap, - [`col-${columnEntries.length === 1 ? 0 : newIndex}-${colId}`]: { + [`col-${columnEntries.length === 1 ? 0 : index}-${colId}`]: { ...column, id: colId, }, @@ -122,8 +104,8 @@ function getExpressionForLayer( function: 'esaggs', arguments: { index: [indexPattern.id], - metricsAtAllLevels: [true], - partialRows: [true], + metricsAtAllLevels: [false], + partialRows: [false], includeFormatHints: [true], timeFields: allDateHistogramFields, aggConfigs: [JSON.stringify(aggs)], diff --git a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx index cb2458a76967c..d4c85ce9b8843 100644 --- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx @@ -27,8 +27,8 @@ import { import { FormatFactory, LensFilterEvent } from '../types'; import { VisualizationContainer } from '../visualization_container'; import { CHART_NAMES, DEFAULT_PERCENT_DECIMALS } from './constants'; -import { ColumnGroups, PieExpressionProps } from './types'; -import { getSliceValueWithFallback, getFilterContext } from './render_helpers'; +import { PieExpressionProps } from './types'; +import { getSliceValue, getFilterContext } from './render_helpers'; import { EmptyPlaceholder } from '../shared_components'; import './visualization.scss'; import { desanitizeFilterContext } from '../utils'; @@ -72,21 +72,6 @@ export function PieComponent( }); } - // The datatable for pie charts should include subtotals, like this: - // [bucket, subtotal, bucket, count] - // But the user only configured [bucket, bucket, count] - const columnGroups: ColumnGroups = []; - firstTable.columns.forEach((col) => { - if (groups.includes(col.id)) { - columnGroups.push({ - col, - metrics: [], - }); - } else if (columnGroups.length > 0) { - columnGroups[columnGroups.length - 1].metrics.push(col); - } - }); - const fillLabel: Partial = { textInvertible: false, valueFont: { @@ -100,7 +85,9 @@ export function PieComponent( fillLabel.valueFormatter = () => ''; } - const layers: PartitionLayer[] = columnGroups.map(({ col }, layerIndex) => { + const bucketColumns = firstTable.columns.filter((col) => groups.includes(col.id)); + + const layers: PartitionLayer[] = bucketColumns.map((col, layerIndex) => { return { groupByRollup: (d: Datum) => d[col.id] ?? EMPTY_SLICE, showAccessor: (d: Datum) => d !== EMPTY_SLICE, @@ -116,7 +103,7 @@ export function PieComponent( fillLabel: isDarkMode && shape === 'treemap' && - layerIndex < columnGroups.length - 1 && + layerIndex < bucketColumns.length - 1 && categoryDisplay !== 'hide' ? { ...fillLabel, textColor: euiDarkVars.euiTextColor } : fillLabel, @@ -136,10 +123,10 @@ export function PieComponent( if (shape === 'treemap') { // Only highlight the innermost color of the treemap, as it accurately represents area - return layerIndex < columnGroups.length - 1 ? 'rgba(0,0,0,0)' : outputColor; + return layerIndex < bucketColumns.length - 1 ? 'rgba(0,0,0,0)' : outputColor; } - const lighten = (d.depth - 1) / (columnGroups.length * 2); + const lighten = (d.depth - 1) / (bucketColumns.length * 2); return color(outputColor, 'hsl').lighten(lighten).hex(); }, }, @@ -198,8 +185,6 @@ export function PieComponent( setState({ isReady: true }); }, []); - const reverseGroups = [...columnGroups].reverse(); - const hasNegative = firstTable.rows.some((row) => { const value = row[metricColumn.id]; return typeof value === 'number' && value < 0; @@ -243,16 +228,12 @@ export function PieComponent( showLegend={ !hideLabels && (legendDisplay === 'show' || - (legendDisplay === 'default' && columnGroups.length > 1 && shape !== 'treemap')) + (legendDisplay === 'default' && bucketColumns.length > 1 && shape !== 'treemap')) } legendPosition={legendPosition || Position.Right} legendMaxDepth={nestedLegend ? undefined : 1 /* Color is based only on first layer */} onElementClick={(args) => { - const context = getFilterContext( - args[0][0] as LayerValue[], - columnGroups.map(({ col }) => col.id), - firstTable - ); + const context = getFilterContext(args[0][0] as LayerValue[], groups, firstTable); onClickValue(desanitizeFilterContext(context)); }} @@ -262,7 +243,7 @@ export function PieComponent( getSliceValueWithFallback(d, reverseGroups, metricColumn)} + valueAccessor={(d: Datum) => getSliceValue(d, metricColumn)} percentFormatter={(d: number) => percentFormatter.convert(d / 100)} valueGetter={hideLabels || numberDisplay === 'value' ? undefined : 'percent'} valueFormatter={(d: number) => (hideLabels ? '' : formatters[metricColumn.id].convert(d))} diff --git a/x-pack/plugins/lens/public/pie_visualization/render_helpers.test.ts b/x-pack/plugins/lens/public/pie_visualization/render_helpers.test.ts index d9ccda2a99ab2..22c63cd67281b 100644 --- a/x-pack/plugins/lens/public/pie_visualization/render_helpers.test.ts +++ b/x-pack/plugins/lens/public/pie_visualization/render_helpers.test.ts @@ -5,86 +5,47 @@ */ import { Datatable } from 'src/plugins/expressions/public'; -import { getSliceValueWithFallback, getFilterContext } from './render_helpers'; -import { ColumnGroups } from './types'; +import { getSliceValue, getFilterContext } from './render_helpers'; describe('render helpers', () => { - describe('#getSliceValueWithFallback', () => { - describe('without fallback', () => { - const columnGroups: ColumnGroups = [ - { col: { id: 'a', name: 'A', meta: { type: 'string' } }, metrics: [] }, - { col: { id: 'b', name: 'C', meta: { type: 'string' } }, metrics: [] }, - ]; - - it('returns the metric when positive number', () => { - expect( - getSliceValueWithFallback({ a: 'Cat', b: 'Home', c: 5 }, columnGroups, { + describe('#getSliceValue', () => { + it('returns the metric when positive number', () => { + expect( + getSliceValue( + { a: 'Cat', b: 'Home', c: 5 }, + { id: 'c', name: 'C', meta: { type: 'number' }, - }) - ).toEqual(5); - }); + } + ) + ).toEqual(5); + }); - it('returns the metric when negative number', () => { - expect( - getSliceValueWithFallback({ a: 'Cat', b: 'Home', c: -100 }, columnGroups, { + it('returns the metric when negative number', () => { + expect( + getSliceValue( + { a: 'Cat', b: 'Home', c: -100 }, + { id: 'c', name: 'C', meta: { type: 'number' }, - }) - ).toEqual(-100); - }); + } + ) + ).toEqual(-100); + }); - it('returns epsilon when metric is 0 without fallback', () => { - expect( - getSliceValueWithFallback({ a: 'Cat', b: 'Home', c: 0 }, columnGroups, { + it('returns epsilon when metric is 0 without fallback', () => { + expect( + getSliceValue( + { a: 'Cat', b: 'Home', c: 0 }, + { id: 'c', name: 'C', meta: { type: 'number' }, - }) - ).toEqual(Number.EPSILON); - }); - }); - - describe('fallback behavior', () => { - const columnGroups: ColumnGroups = [ - { - col: { id: 'a', name: 'A', meta: { type: 'string' } }, - metrics: [{ id: 'a_subtotal', name: '', meta: { type: 'number' } }], - }, - { col: { id: 'b', name: 'C', meta: { type: 'string' } }, metrics: [] }, - ]; - - it('falls back to metric from previous column if available', () => { - expect( - getSliceValueWithFallback( - { a: 'Cat', a_subtotal: 5, b: 'Home', c: undefined }, - columnGroups, - { id: 'c', name: 'C', meta: { type: 'number' } } - ) - ).toEqual(5); - }); - - it('uses epsilon if fallback is 0', () => { - expect( - getSliceValueWithFallback( - { a: 'Cat', a_subtotal: 0, b: 'Home', c: undefined }, - columnGroups, - { id: 'c', name: 'C', meta: { type: 'number' } } - ) - ).toEqual(Number.EPSILON); - }); - - it('uses epsilon if fallback is missing', () => { - expect( - getSliceValueWithFallback( - { a: 'Cat', a_subtotal: undefined, b: 'Home', c: undefined }, - columnGroups, - { id: 'c', name: 'C', meta: { type: 'number' } } - ) - ).toEqual(Number.EPSILON); - }); + } + ) + ).toEqual(Number.EPSILON); }); }); diff --git a/x-pack/plugins/lens/public/pie_visualization/render_helpers.ts b/x-pack/plugins/lens/public/pie_visualization/render_helpers.ts index 26b4f9ccda853..978afcca6a550 100644 --- a/x-pack/plugins/lens/public/pie_visualization/render_helpers.ts +++ b/x-pack/plugins/lens/public/pie_visualization/render_helpers.ts @@ -6,22 +6,13 @@ import { Datum, LayerValue } from '@elastic/charts'; import { Datatable, DatatableColumn } from 'src/plugins/expressions/public'; -import { ColumnGroups } from './types'; import { LensFilterEvent } from '../types'; -export function getSliceValueWithFallback( - d: Datum, - reverseGroups: ColumnGroups, - metricColumn: DatatableColumn -) { +export function getSliceValue(d: Datum, metricColumn: DatatableColumn) { if (typeof d[metricColumn.id] === 'number' && d[metricColumn.id] !== 0) { return d[metricColumn.id]; } - // Sometimes there is missing data for outer groups - // When there is missing data, we fall back to the next groups - // This creates a sunburst effect - const hasMetric = reverseGroups.find((group) => group.metrics.length && d[group.metrics[0].id]); - return hasMetric ? d[hasMetric.metrics[0].id] || Number.EPSILON : Number.EPSILON; + return Number.EPSILON; } export function getFilterContext( diff --git a/x-pack/plugins/lens/public/pie_visualization/types.ts b/x-pack/plugins/lens/public/pie_visualization/types.ts index 0596e54870a94..54bececa13c2a 100644 --- a/x-pack/plugins/lens/public/pie_visualization/types.ts +++ b/x-pack/plugins/lens/public/pie_visualization/types.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { DatatableColumn } from 'src/plugins/expressions/public'; import { LensMultiTable } from '../types'; export interface SharedLayerState { @@ -38,8 +37,3 @@ export interface PieExpressionProps { data: LensMultiTable; args: PieExpressionArgs; } - -export type ColumnGroups = Array<{ - col: DatatableColumn; - metrics: DatatableColumn[]; -}>; From 667ff6cd2cf54ace0b67490b2ea6174df3c737e2 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Thu, 29 Oct 2020 15:03:18 +0000 Subject: [PATCH 31/80] [User experience] Enhance page load duration metrics (#81915) * Enhance page load duration metrics and helper tooltips --- .../step_definitions/csm/csm_dashboard.ts | 2 +- .../step_definitions/csm/csm_filters.ts | 4 +- .../step_definitions/csm/percentile_select.ts | 2 +- .../csm/service_name_filter.ts | 2 +- .../app/RumDashboard/ClientMetrics/index.tsx | 44 ++++++++++++++-- .../app/RumDashboard/RumDashboard.tsx | 3 +- .../RumDashboard/UXMetrics/KeyUXMetrics.tsx | 51 ++++++++++++++++--- .../UXMetrics/__tests__/KeyUXMetrics.test.tsx | 28 +++++++--- .../RumDashboard/UXMetrics/translations.ts | 40 +++++++++++++++ .../app/RumDashboard/translations.ts | 21 ++++++++ .../__snapshots__/queries.test.ts.snap | 4 +- .../lib/rum_client/get_client_metrics.ts | 24 +++++---- 12 files changed, 191 insertions(+), 34 deletions(-) diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts index a8edf862ab256..d8540c3f3efd7 100644 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts +++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts @@ -26,7 +26,7 @@ Given(`a user browses the APM UI application for RUM Data`, () => { }); Then(`should have correct client metrics`, () => { - const metrics = ['4 ms', '58 ms', '55']; + const metrics = ['80 ms', '4 ms', '76 ms', '55']; verifyClientMetrics(metrics, true); }); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_filters.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_filters.ts index 5c2109bb518c2..88287286c66c5 100644 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_filters.ts +++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_filters.ts @@ -56,7 +56,9 @@ Then(/^it filters the client metrics "([^"]*)"$/, (filterName) => { cy.get('.euiStat__title-isLoading').should('not.be.visible'); const data = - filterName === 'os' ? ['5 ms', '64 ms', '8'] : ['4 ms', '55 ms', '28']; + filterName === 'os' + ? ['82 ms', '5 ms', '77 ms', '8'] + : ['75 ms', '4 ms', '71 ms', '28']; verifyClientMetrics(data, true); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/percentile_select.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/percentile_select.ts index 314254883b2fd..44802bbce6208 100644 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/percentile_select.ts +++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/percentile_select.ts @@ -16,7 +16,7 @@ When('the user changes the selected percentile', () => { }); Then(`it displays client metric related to that percentile`, () => { - const metrics = ['14 ms', '131 ms', '55']; + const metrics = ['165 ms', '14 ms', '151 ms', '55']; verifyClientMetrics(metrics, false); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/service_name_filter.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/service_name_filter.ts index 20c6a3fb72aa9..609d0d18f5bc8 100644 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/service_name_filter.ts +++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/service_name_filter.ts @@ -15,7 +15,7 @@ When('the user changes the selected service name', () => { }); Then(`it displays relevant client metrics`, () => { - const metrics = ['4 ms', '58 ms', '55']; + const metrics = ['80 ms', '4 ms', '76 ms', '55']; verifyClientMetrics(metrics, false); }); 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 index 0b4dcea5d12e0..b6924b9552699 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx @@ -7,7 +7,13 @@ import * as React from 'react'; import numeral from '@elastic/numeral'; import styled from 'styled-components'; import { useContext, useEffect } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiStat, EuiToolTip } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiStat, + EuiToolTip, + EuiIconTip, +} from '@elastic/eui'; import { useFetcher } from '../../../../hooks/useFetcher'; import { I18LABELS } from '../translations'; import { useUxQuery } from '../hooks/useUxQuery'; @@ -70,11 +76,35 @@ export function ClientMetrics() { return ( + + + {I18LABELS.totalPageLoad} + + + } + isLoading={status !== 'success'} + /> + + {I18LABELS.backEnd} + + + } isLoading={status !== 'success'} /> @@ -82,7 +112,15 @@ export function ClientMetrics() { + {I18LABELS.frontEnd} + + + } isLoading={status !== 'success'} /> diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx index b19adb12d02d4..e4e9109f007e7 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx @@ -36,8 +36,7 @@ export function RumDashboard() {

- {I18LABELS.pageLoadDuration} ( - {getPercentileLabel(percentile!)}) + {I18LABELS.pageLoad} ({getPercentileLabel(percentile!)})

diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx index e91f129195366..c7fe8e885020a 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx @@ -5,15 +5,20 @@ */ import React from 'react'; -import { EuiFlexItem, EuiStat, EuiFlexGroup } from '@elastic/eui'; +import { EuiFlexItem, EuiStat, EuiFlexGroup, EuiIconTip } from '@elastic/eui'; import numeral from '@elastic/numeral'; import { DATA_UNDEFINED_LABEL, FCP_LABEL, + FCP_TOOLTIP, LONGEST_LONG_TASK, + LONGEST_LONG_TASK_TOOLTIP, NO_OF_LONG_TASK, + NO_OF_LONG_TASK_TOOLTIP, SUM_LONG_TASKS, + SUM_LONG_TASKS_TOOLTIP, TBT_LABEL, + TBT_TOOLTIP, } from './translations'; import { useFetcher } from '../../../../hooks/useFetcher'; import { useUxQuery } from '../hooks/useUxQuery'; @@ -70,7 +75,12 @@ export function KeyUXMetrics({ data, loading }: Props) { + {FCP_LABEL} + + + } isLoading={loading} /> @@ -78,7 +88,12 @@ export function KeyUXMetrics({ data, loading }: Props) { + {TBT_LABEL} + + + } isLoading={loading} /> @@ -90,7 +105,15 @@ export function KeyUXMetrics({ data, loading }: Props) { ? numeral(longTaskData?.noOfLongTasks).format('0,0') : DATA_UNDEFINED_LABEL } - description={NO_OF_LONG_TASK} + description={ + <> + {NO_OF_LONG_TASK} + + + } isLoading={status !== 'success'} /> @@ -98,7 +121,15 @@ export function KeyUXMetrics({ data, loading }: Props) { + {LONGEST_LONG_TASK} + + + } isLoading={status !== 'success'} /> @@ -106,7 +137,15 @@ export function KeyUXMetrics({ data, loading }: Props) { + {SUM_LONG_TASKS} + + + } isLoading={status !== 'success'} /> diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/__tests__/KeyUXMetrics.test.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/__tests__/KeyUXMetrics.test.tsx index 329339deb2f89..3a6323a747a70 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/__tests__/KeyUXMetrics.test.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/__tests__/KeyUXMetrics.test.tsx @@ -19,7 +19,7 @@ describe('KeyUXMetrics', () => { status: fetcherHook.FETCH_STATUS.SUCCESS, refetch: jest.fn(), }); - const { getByText } = render( + const { getAllByText } = render( { /> ); - expect(getByText('Longest long task duration 271 ms')).toBeInTheDocument(); - expect(getByText('Total long tasks duration 520 ms')).toBeInTheDocument(); - expect(getByText('No. of long tasks 3')).toBeInTheDocument(); - expect(getByText('Total blocking time 271 ms')).toBeInTheDocument(); - expect(getByText('First contentful paint 1.27 s')).toBeInTheDocument(); + const checkText = (text: string) => { + return (content: any, node: any) => { + return node?.textContent?.includes(text); + }; + }; + + expect( + getAllByText(checkText('Longest long task duration271 ms'))[0] + ).toBeInTheDocument(); + expect( + getAllByText(checkText('Total long tasks duration520 ms'))[0] + ).toBeInTheDocument(); + expect( + getAllByText(checkText('No. of long tasks3'))[0] + ).toBeInTheDocument(); + expect( + getAllByText(checkText('Total blocking time271 ms'))[0] + ).toBeInTheDocument(); + expect( + getAllByText(checkText('First contentful paint1.27 s'))[0] + ).toBeInTheDocument(); }); }); diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/translations.ts b/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/translations.ts index 5920dc92f558d..3795f2f102237 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/translations.ts +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/translations.ts @@ -18,10 +18,26 @@ export const FCP_LABEL = i18n.translate('xpack.apm.rum.coreVitals.fcp', { defaultMessage: 'First contentful paint', }); +export const FCP_TOOLTIP = i18n.translate( + 'xpack.apm.rum.coreVitals.fcpTooltip', + { + defaultMessage: + 'First contentful paint (FCP) focusses on the initial rendering and measures the time from when the page starts loading to when any part of the page’s content is displayed on the screen.', + } +); + export const TBT_LABEL = i18n.translate('xpack.apm.rum.coreVitals.tbt', { defaultMessage: 'Total blocking time', }); +export const TBT_TOOLTIP = i18n.translate( + 'xpack.apm.rum.coreVitals.tbtTooltip', + { + defaultMessage: + 'Total blocking time (TBT) is the sum of the blocking time (duration above 50 ms) for each long task that occurs between the First contentful paint and the time when the transaction is completed.', + } +); + export const NO_OF_LONG_TASK = i18n.translate( 'xpack.apm.rum.uxMetrics.noOfLongTasks', { @@ -29,6 +45,14 @@ export const NO_OF_LONG_TASK = i18n.translate( } ); +export const NO_OF_LONG_TASK_TOOLTIP = i18n.translate( + 'xpack.apm.rum.uxMetrics.noOfLongTasksTooltip', + { + defaultMessage: + 'The number of long tasks, a long task is defined as any user activity or browser task that monopolizes the UI thread for extended periods (greater than 50 milliseconds) and blocks other critical tasks (frame rate or input latency) from being executed.', + } +); + export const LONGEST_LONG_TASK = i18n.translate( 'xpack.apm.rum.uxMetrics.longestLongTasks', { @@ -36,6 +60,14 @@ export const LONGEST_LONG_TASK = i18n.translate( } ); +export const LONGEST_LONG_TASK_TOOLTIP = i18n.translate( + 'xpack.apm.rum.uxMetrics.longestLongTasksTooltip', + { + defaultMessage: + 'The duration of the longest long task, a long task is defined as any user activity or browser task that monopolizes the UI thread for extended periods (greater than 50 milliseconds) and blocks other critical tasks (frame rate or input latency) from being executed.', + } +); + export const SUM_LONG_TASKS = i18n.translate( 'xpack.apm.rum.uxMetrics.sumLongTasks', { @@ -43,6 +75,14 @@ export const SUM_LONG_TASKS = i18n.translate( } ); +export const SUM_LONG_TASKS_TOOLTIP = i18n.translate( + 'xpack.apm.rum.uxMetrics.sumLongTasksTooltip', + { + defaultMessage: + 'The total duration of long tasks, a long task is defined as any user activity or browser task that monopolizes the UI thread for extended periods (greater than 50 milliseconds) and blocks other critical tasks (frame rate or input latency) from being executed.', + } +); + export const getPercentileLabel = (value: number) => { if (value === 50) return I18LABELS.median; diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts b/x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts index b7ecfc08db13b..75df1381d8a1d 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts @@ -10,6 +10,9 @@ export const I18LABELS = { dataMissing: i18n.translate('xpack.apm.rum.dashboard.dataMissing', { defaultMessage: 'N/A', }), + totalPageLoad: i18n.translate('xpack.apm.rum.dashboard.totalPageLoad', { + defaultMessage: 'Total', + }), backEnd: i18n.translate('xpack.apm.rum.dashboard.backend', { defaultMessage: 'Backend', }), @@ -34,6 +37,9 @@ export const I18LABELS = { defaultMessage: 'Page load duration', } ), + pageLoad: i18n.translate('xpack.apm.rum.dashboard.pageLoad.label', { + defaultMessage: 'Page load', + }), pageLoadDistribution: i18n.translate( 'xpack.apm.rum.dashboard.pageLoadDistribution.label', { @@ -156,6 +162,21 @@ export const I18LABELS = { noData: i18n.translate('xpack.apm.ux.visitorBreakdown.noData', { defaultMessage: 'No data.', }), + // Helper tooltips + totalPageLoadTooltip: i18n.translate( + 'xpack.apm.rum.dashboard.tooltips.totalPageLoad', + { + defaultMessage: 'Total represents the full page load duration', + } + ), + frontEndTooltip: i18n.translate('xpack.apm.rum.dashboard.tooltips.frontEnd', { + defaultMessage: + 'Frontend time represents the total page load duration minus the backend time', + }), + backEndTooltip: i18n.translate('xpack.apm.rum.dashboard.tooltips.backEnd', { + defaultMessage: + 'Backend time represents time to first byte (TTFB), which is when the first response packet is received after the request has been made', + }), }; export const VisitorBreakdownLabel = i18n.translate( 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 index 53dcd2f469148..b89c46f6e3fc5 100644 --- 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 @@ -22,9 +22,9 @@ Object { ], }, }, - "domInteractive": Object { + "totalPageLoadDuration": Object { "percentiles": Object { - "field": "transaction.marks.agent.domInteractive", + "field": "transaction.duration.us", "hdr": Object { "number_of_significant_value_digits": 3, }, 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 index da65e69e7eb7c..6685a60f84f05 100644 --- 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 @@ -8,8 +8,8 @@ import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page import { mergeProjection } from '../../projections/util/merge_projection'; import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { - TRANSACTION_DOM_INTERACTIVE, TRANSACTION_TIME_TO_FIRST_BYTE, + TRANSACTION_DURATION, } from '../../../common/elasticsearch_fieldnames'; export async function getClientMetrics({ @@ -37,18 +37,18 @@ export async function getClientMetrics({ exists: { field: 'transaction.marks.navigationTiming.fetchStart' }, }, aggs: { - backEnd: { + totalPageLoadDuration: { percentiles: { - field: TRANSACTION_TIME_TO_FIRST_BYTE, + field: TRANSACTION_DURATION, percents: [percentile], hdr: { number_of_significant_value_digits: 3, }, }, }, - domInteractive: { + backEnd: { percentiles: { - field: TRANSACTION_DOM_INTERACTIVE, + field: TRANSACTION_TIME_TO_FIRST_BYTE, percents: [percentile], hdr: { number_of_significant_value_digits: 3, @@ -64,17 +64,19 @@ export async function getClientMetrics({ const { apmEventClient } = setup; const response = await apmEventClient.search(params); const { - hasFetchStartField: { backEnd, domInteractive }, + hasFetchStartField: { backEnd, totalPageLoadDuration }, } = response.aggregations!; const pkey = percentile.toFixed(1); - // Divide by 1000 to convert ms into seconds + const totalPageLoadDurationValue = totalPageLoadDuration.values[pkey] ?? 0; + const totalPageLoadDurationValueMs = totalPageLoadDurationValue / 1000; // Microseconds to milliseconds + const backendValue = backEnd.values[pkey] ?? 0; + return { pageViews: { value: response.hits.total.value ?? 0 }, - backEnd: { value: backEnd.values[pkey] || 0 }, - frontEnd: { - value: (domInteractive.values[pkey] || 0) - (backEnd.values[pkey] || 0), - }, + totalPageLoadDuration: { value: totalPageLoadDurationValueMs }, + backEnd: { value: backendValue }, + frontEnd: { value: totalPageLoadDurationValueMs - backendValue }, }; } From 59662eefd2dbfd98eaae20f04fd8120e15872c20 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Thu, 29 Oct 2020 16:06:12 +0100 Subject: [PATCH 32/80] [Lens] Add loading indicator during debounce time (#80158) --- ...ressions-public.reactexpressionrenderer.md | 2 +- ...c.reactexpressionrendererprops.debounce.md | 11 +++++++ ...ons-public.reactexpressionrendererprops.md | 1 + src/plugins/expressions/public/public.api.md | 4 ++- .../public/react_expression_renderer.test.tsx | 33 +++++++++++++++++++ .../public/react_expression_renderer.tsx | 32 ++++++++++++++---- .../editor_frame/suggestion_panel.tsx | 14 +++----- 7 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.debounce.md diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderer.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderer.md index 66c2e1e3c0c8d..32a7151578658 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderer.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderer.md @@ -7,5 +7,5 @@ Signature: ```typescript -ReactExpressionRenderer: ({ className, dataAttrs, padding, renderError, expression, onEvent, reload$, ...expressionLoaderOptions }: ReactExpressionRendererProps) => JSX.Element +ReactExpressionRenderer: ({ className, dataAttrs, padding, renderError, expression, onEvent, reload$, debounce, ...expressionLoaderOptions }: ReactExpressionRendererProps) => JSX.Element ``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.debounce.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.debounce.md new file mode 100644 index 0000000000000..3f7eb12fbb7a8 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.debounce.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ReactExpressionRendererProps](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md) > [debounce](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.debounce.md) + +## ReactExpressionRendererProps.debounce property + +Signature: + +```typescript +debounce?: number; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md index 5622516530edd..e4980ce04b9e2 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md @@ -16,6 +16,7 @@ export interface ReactExpressionRendererProps extends IExpressionLoaderParams | --- | --- | --- | | [className](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.classname.md) | string | | | [dataAttrs](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.dataattrs.md) | string[] | | +| [debounce](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.debounce.md) | number | | | [expression](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.expression.md) | string | ExpressionAstExpression | | | [onEvent](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.onevent.md) | (event: ExpressionRendererEvent) => void | | | [padding](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.padding.md) | 'xs' | 's' | 'm' | 'l' | 'xl' | | diff --git a/src/plugins/expressions/public/public.api.md b/src/plugins/expressions/public/public.api.md index fe95cf5eb0cda..68a3507bbf166 100644 --- a/src/plugins/expressions/public/public.api.md +++ b/src/plugins/expressions/public/public.api.md @@ -1039,7 +1039,7 @@ export interface Range { // Warning: (ae-missing-release-tag) "ReactExpressionRenderer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const ReactExpressionRenderer: ({ className, dataAttrs, padding, renderError, expression, onEvent, reload$, ...expressionLoaderOptions }: ReactExpressionRendererProps) => JSX.Element; +export const ReactExpressionRenderer: ({ className, dataAttrs, padding, renderError, expression, onEvent, reload$, debounce, ...expressionLoaderOptions }: ReactExpressionRendererProps) => JSX.Element; // Warning: (ae-missing-release-tag) "ReactExpressionRendererProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1050,6 +1050,8 @@ export interface ReactExpressionRendererProps extends IExpressionLoaderParams { // (undocumented) dataAttrs?: string[]; // (undocumented) + debounce?: number; + // (undocumented) expression: string | ExpressionAstExpression; // (undocumented) onEvent?: (event: ExpressionRendererEvent) => void; diff --git a/src/plugins/expressions/public/react_expression_renderer.test.tsx b/src/plugins/expressions/public/react_expression_renderer.test.tsx index 7c1711f056d69..052c2a9f6a24a 100644 --- a/src/plugins/expressions/public/react_expression_renderer.test.tsx +++ b/src/plugins/expressions/public/react_expression_renderer.test.tsx @@ -113,6 +113,39 @@ describe('ExpressionRenderer', () => { instance.unmount(); }); + it('waits for debounce period if specified', () => { + jest.useFakeTimers(); + + const refreshSubject = new Subject(); + const loaderUpdate = jest.fn(); + + (ExpressionLoader as jest.Mock).mockImplementation(() => { + return { + render$: new Subject(), + data$: new Subject(), + loading$: new Subject(), + update: loaderUpdate, + destroy: jest.fn(), + }; + }); + + const instance = mount( + + ); + + instance.setProps({ expression: 'abc' }); + + expect(loaderUpdate).toHaveBeenCalledTimes(1); + + act(() => { + jest.runAllTimers(); + }); + + expect(loaderUpdate).toHaveBeenCalledTimes(2); + + instance.unmount(); + }); + it('should display a custom error message if the user provides one and then remove it after successful render', () => { const dataSubject = new Subject(); const data$ = dataSubject.asObservable().pipe(share()); diff --git a/src/plugins/expressions/public/react_expression_renderer.tsx b/src/plugins/expressions/public/react_expression_renderer.tsx index 99d170c96666d..fecebf36ab7e6 100644 --- a/src/plugins/expressions/public/react_expression_renderer.tsx +++ b/src/plugins/expressions/public/react_expression_renderer.tsx @@ -45,6 +45,7 @@ export interface ReactExpressionRendererProps extends IExpressionLoaderParams { * An observable which can be used to re-run the expression without destroying the component */ reload$?: Observable; + debounce?: number; } export type ReactExpressionRendererType = React.ComponentType; @@ -71,6 +72,7 @@ export const ReactExpressionRenderer = ({ expression, onEvent, reload$, + debounce, ...expressionLoaderOptions }: ReactExpressionRendererProps) => { const mountpoint: React.MutableRefObject = useRef(null); @@ -85,12 +87,28 @@ export const ReactExpressionRenderer = ({ const errorRenderHandlerRef: React.MutableRefObject = useRef( null ); + const [debouncedExpression, setDebouncedExpression] = useState(expression); + useEffect(() => { + if (debounce === undefined) { + return; + } + const handler = setTimeout(() => { + setDebouncedExpression(expression); + }, debounce); + + return () => { + clearTimeout(handler); + }; + }, [expression, debounce]); + + const activeExpression = debounce !== undefined ? debouncedExpression : expression; + const waitingForDebounceToComplete = debounce !== undefined && expression !== debouncedExpression; /* eslint-disable react-hooks/exhaustive-deps */ // OK to ignore react-hooks/exhaustive-deps because options update is handled by calling .update() useEffect(() => { const subs: Subscription[] = []; - expressionLoaderRef.current = new ExpressionLoader(mountpoint.current!, expression, { + expressionLoaderRef.current = new ExpressionLoader(mountpoint.current!, activeExpression, { ...expressionLoaderOptions, // react component wrapper provides different // error handling api which is easier to work with from react @@ -146,21 +164,21 @@ export const ReactExpressionRenderer = ({ useEffect(() => { const subscription = reload$?.subscribe(() => { if (expressionLoaderRef.current) { - expressionLoaderRef.current.update(expression, expressionLoaderOptions); + expressionLoaderRef.current.update(activeExpression, expressionLoaderOptions); } }); return () => subscription?.unsubscribe(); - }, [reload$, expression, ...Object.values(expressionLoaderOptions)]); + }, [reload$, activeExpression, ...Object.values(expressionLoaderOptions)]); // Re-fetch data automatically when the inputs change useShallowCompareEffect( () => { if (expressionLoaderRef.current) { - expressionLoaderRef.current.update(expression, expressionLoaderOptions); + expressionLoaderRef.current.update(activeExpression, expressionLoaderOptions); } }, // when expression is changed by reference and when any other loaderOption is changed by reference - [{ expression, ...expressionLoaderOptions }] + [{ activeExpression, ...expressionLoaderOptions }] ); /* eslint-enable react-hooks/exhaustive-deps */ @@ -188,7 +206,9 @@ export const ReactExpressionRenderer = ({ return (
{state.isEmpty && } - {state.isLoading && } + {(state.isLoading || waitingForDebounceToComplete) && ( + + )} {!state.isLoading && state.error && renderError && diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx index 5e5e9cda954ee..63ee02ac0404d 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx @@ -32,16 +32,11 @@ import { ReactExpressionRendererType, } from '../../../../../../src/plugins/expressions/public'; import { prependDatasourceExpression } from './expression_helpers'; -import { debouncedComponent } from '../../debounced_component'; import { trackUiEvent, trackSuggestionEvent } from '../../lens_ui_telemetry'; import { DataPublicPluginStart } from '../../../../../../src/plugins/data/public'; const MAX_SUGGESTIONS_DISPLAYED = 5; -// TODO: Remove this when upstream fix is merged https://github.com/elastic/eui/issues/2329 -// eslint-disable-next-line -const EuiPanelFixed = EuiPanel as React.ComponentType; - export interface SuggestionPanelProps { activeDatasourceId: string | null; datasourceMap: Record; @@ -82,6 +77,7 @@ const PreviewRenderer = ({ className="lnsSuggestionPanel__expressionRenderer" padding="s" expression={expression} + debounce={2000} renderError={() => { return (
@@ -104,8 +100,6 @@ const PreviewRenderer = ({ ); }; -const DebouncedPreviewRenderer = debouncedComponent(PreviewRenderer, 2000); - const SuggestionPreview = ({ preview, ExpressionRenderer: ExpressionRendererComponent, @@ -126,7 +120,7 @@ const SuggestionPreview = ({ return (
- {preview.expression ? ( - {preview.title} )} - +
); From 995111ad8a4d74fe546f9c77627c865ce4d95747 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 29 Oct 2020 16:07:09 +0100 Subject: [PATCH 33/80] [Uptime] Use base path for screenshot url (#81930) --- .../monitor/synthetics/__tests__/executed_journey.test.tsx | 3 +++ .../components/monitor/synthetics/executed_journey.tsx | 1 + .../public/components/monitor/synthetics/executed_step.tsx | 3 +-- .../monitor/synthetics/step_screenshot_display.tsx | 6 ++++-- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/__tests__/executed_journey.test.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/__tests__/executed_journey.test.tsx index 5ab815a3c0b5d..9fec9439b3ad5 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/__tests__/executed_journey.test.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/__tests__/executed_journey.test.tsx @@ -253,6 +253,9 @@ describe('ExecutedJourney component', () => { } } /> + `); }); diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/executed_journey.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/executed_journey.tsx index 2ffb3f0feb4dd..9a3e045017f9a 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/executed_journey.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/executed_journey.tsx @@ -79,6 +79,7 @@ export const ExecutedJourney: FC = ({ journey }) => ( {journey.steps.filter(isStepEnd).map((step, index) => ( ))} +
); diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/executed_step.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/executed_step.tsx index 3c26ba12eea65..5966851973af2 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/executed_step.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/executed_step.tsx @@ -41,7 +41,7 @@ export const ExecutedStep: FC = ({ step, index }) => (
- +
@@ -87,6 +87,5 @@ export const ExecutedStep: FC = ({ step, index }) => (
- ); diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_screenshot_display.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_screenshot_display.tsx index 2e8ad4bd0c9a8..b81cf6bc1ec1d 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/step_screenshot_display.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/step_screenshot_display.tsx @@ -16,7 +16,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import React, { useContext, useEffect, useRef, useState, FC } from 'react'; import { useIntersection } from 'react-use'; -import { UptimeThemeContext } from '../../../contexts'; +import { UptimeSettingsContext, UptimeThemeContext } from '../../../contexts'; interface StepScreenshotDisplayProps { screenshotExists?: boolean; @@ -41,6 +41,8 @@ export const StepScreenshotDisplay: FC = ({ colors: { lightestShade: pageBackground }, } = useContext(UptimeThemeContext); + const { basePath } = useContext(UptimeSettingsContext); + const [isImagePopoverOpen, setIsImagePopoverOpen] = useState(false); const [isOverlayOpen, setIsOverlayOpen] = useState(false); @@ -59,7 +61,7 @@ export const StepScreenshotDisplay: FC = ({ }, [hasIntersected, isIntersecting, setHasIntersected]); let content: JSX.Element | null = null; - const imgSrc = `/api/uptime/journey/screenshot/${checkGroup}/${stepIndex}`; + const imgSrc = basePath + `/api/uptime/journey/screenshot/${checkGroup}/${stepIndex}`; if (hasIntersected && screenshotExists) { content = ( <> From 3ee665683732da596fe32ba3194733d0fee5d2ad Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Thu, 29 Oct 2020 10:37:50 -0500 Subject: [PATCH 34/80] [deb/rpm] remove sysv (#74424) Co-authored-by: Elastic Machine Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- docs/migration/migrate_8_0.asciidoc | 10 + docs/setup/install/deb-init.asciidoc | 20 -- docs/setup/install/deb.asciidoc | 8 - docs/setup/install/rpm-init.asciidoc | 20 -- docs/setup/install/rpm.asciidoc | 7 - docs/setup/start-stop.asciidoc | 21 +-- src/dev/build/tasks/os_packages/run_fpm.ts | 1 - .../{sysv => systemd}/etc/default/kibana | 0 .../service_templates/sysv/etc/init.d/kibana | 174 ------------------ 9 files changed, 12 insertions(+), 249 deletions(-) delete mode 100644 docs/setup/install/deb-init.asciidoc delete mode 100644 docs/setup/install/rpm-init.asciidoc rename src/dev/build/tasks/os_packages/service_templates/{sysv => systemd}/etc/default/kibana (100%) delete mode 100755 src/dev/build/tasks/os_packages/service_templates/sysv/etc/init.d/kibana diff --git a/docs/migration/migrate_8_0.asciidoc b/docs/migration/migrate_8_0.asciidoc index 0cb28ce0fb6e7..ef76121b21d29 100644 --- a/docs/migration/migrate_8_0.asciidoc +++ b/docs/migration/migrate_8_0.asciidoc @@ -167,4 +167,14 @@ The `xpack.` prefix has been removed for all telemetry configurations. *Impact:* For any configurations beginning with `xpack.telemetry`, remove the `xpack` prefix. Use {kibana-ref}/telemetry-settings-kbn.html#telemetry-general-settings[`telemetry.enabled`] instead. +[float] +=== SysV init support has been removed + +*Details:* +All supported operating systems support using systemd service files. Any system that doesn't already have service aliased to use kibana.service should use `systemctl start kibana.service` instead of the `service start kibana`. + +*Impact:* +Any installations using `.deb` or `.rpm` packages using SysV will need to migrate to systemd. + + // end::notable-breaking-changes[] diff --git a/docs/setup/install/deb-init.asciidoc b/docs/setup/install/deb-init.asciidoc deleted file mode 100644 index 6e21b8f97cf7e..0000000000000 --- a/docs/setup/install/deb-init.asciidoc +++ /dev/null @@ -1,20 +0,0 @@ -==== Run {kib} with SysV `init` - -Use the `update-rc.d` command to configure Kibana to start automatically -when the system boots up: - -[source,sh] --------------------------------------------------- -sudo update-rc.d kibana defaults 95 10 --------------------------------------------------- - -You can start and stop Kibana using the `service` command: - -[source,sh] --------------------------------------------- -sudo -i service kibana start -sudo -i service kibana stop --------------------------------------------- - -If Kibana fails to start for any reason, it will print the reason for -failure to `STDOUT`. Log files can be found in `/var/log/kibana/`. diff --git a/docs/setup/install/deb.asciidoc b/docs/setup/install/deb.asciidoc index 234c02cee0be1..c830faf1432d7 100644 --- a/docs/setup/install/deb.asciidoc +++ b/docs/setup/install/deb.asciidoc @@ -160,15 +160,7 @@ https://artifacts.elastic.co/downloads/kibana/kibana-oss-{version}-amd64.deb endif::[] -==== SysV `init` vs `systemd` - -include::init-systemd.asciidoc[] - -[[deb-running-init]] -include::deb-init.asciidoc[] - [[deb-running-systemd]] - include::systemd.asciidoc[] [[deb-configuring]] diff --git a/docs/setup/install/rpm-init.asciidoc b/docs/setup/install/rpm-init.asciidoc deleted file mode 100644 index 08282635a014f..0000000000000 --- a/docs/setup/install/rpm-init.asciidoc +++ /dev/null @@ -1,20 +0,0 @@ -==== Run {kib} with SysV `init` - -Use the `chkconfig` command to configure Kibana to start automatically -when the system boots up: - -[source,sh] --------------------------------------------------- -sudo chkconfig --add kibana --------------------------------------------------- - -You can start and stop Kibana using the `service` command: - -[source,sh] --------------------------------------------- -sudo -i service kibana start -sudo -i service kibana stop --------------------------------------------- - -If Kibana fails to start for any reason, it will print the reason for -failure to `STDOUT`. Log files can be found in `/var/log/kibana/`. diff --git a/docs/setup/install/rpm.asciidoc b/docs/setup/install/rpm.asciidoc index 1153353aa9a0f..0b63684808d7d 100644 --- a/docs/setup/install/rpm.asciidoc +++ b/docs/setup/install/rpm.asciidoc @@ -153,13 +153,6 @@ https://artifacts.elastic.co/downloads/kibana/kibana-oss-{version}-x86_64.rpm endif::[] -==== SysV `init` vs `systemd` - -include::init-systemd.asciidoc[] - -[[rpm-running-init]] -include::rpm-init.asciidoc[] - [[rpm-running-systemd]] include::systemd.asciidoc[] diff --git a/docs/setup/start-stop.asciidoc b/docs/setup/start-stop.asciidoc index 198bc76bbb400..8952cd3a23cd3 100644 --- a/docs/setup/start-stop.asciidoc +++ b/docs/setup/start-stop.asciidoc @@ -25,25 +25,8 @@ stop and start {kib} from the command line. include::install/windows-running.asciidoc[] [float] -[[start-stop-deb]] -=== Debian packages - -include::install/init-systemd.asciidoc[] - -[float] -include::install/deb-init.asciidoc[] - -[float] -include::install/systemd.asciidoc[] - -[float] -[[start-stop-rpm]] -=== RPM packages - -include::install/init-systemd.asciidoc[] - -[float] -include::install/rpm-init.asciidoc[] +[[start-stop-deb-rpm]] +=== Debian and RPM packages [float] include::install/systemd.asciidoc[] diff --git a/src/dev/build/tasks/os_packages/run_fpm.ts b/src/dev/build/tasks/os_packages/run_fpm.ts index b8289f1da194f..e5de760ea11d0 100644 --- a/src/dev/build/tasks/os_packages/run_fpm.ts +++ b/src/dev/build/tasks/os_packages/run_fpm.ts @@ -134,7 +134,6 @@ export async function runFpm( `${resolveWithTrailingSlash(fromBuild('data'))}=/var/lib/kibana/`, // copy package configurations - `${resolveWithTrailingSlash(__dirname, 'service_templates/sysv/')}=/`, `${resolveWithTrailingSlash(__dirname, 'service_templates/systemd/')}=/`, ]; diff --git a/src/dev/build/tasks/os_packages/service_templates/sysv/etc/default/kibana b/src/dev/build/tasks/os_packages/service_templates/systemd/etc/default/kibana similarity index 100% rename from src/dev/build/tasks/os_packages/service_templates/sysv/etc/default/kibana rename to src/dev/build/tasks/os_packages/service_templates/systemd/etc/default/kibana diff --git a/src/dev/build/tasks/os_packages/service_templates/sysv/etc/init.d/kibana b/src/dev/build/tasks/os_packages/service_templates/sysv/etc/init.d/kibana deleted file mode 100755 index eedd4898ce6c3..0000000000000 --- a/src/dev/build/tasks/os_packages/service_templates/sysv/etc/init.d/kibana +++ /dev/null @@ -1,174 +0,0 @@ -#!/bin/sh -# Init script for kibana -# Maintained by -# Generated by pleaserun. -# Implemented based on LSB Core 3.1: -# * Sections: 20.2, 20.3 -# -### BEGIN INIT INFO -# Provides: kibana -# Required-Start: $remote_fs $syslog -# Required-Stop: $remote_fs $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: -# Description: Kibana -### END INIT INFO - -# -# Source function libraries if present. -# (It improves integration with systemd) -# -# Red Hat -if [ -f /etc/rc.d/init.d/functions ]; then - . /etc/rc.d/init.d/functions - -# Debian -elif [ -f /lib/lsb/init-functions ]; then - . /lib/lsb/init-functions - -# SUSE -elif [ -f /etc/rc.status ]; then - . /etc/rc.status - rc_reset -fi - -name=kibana -program=/usr/share/kibana/bin/kibana -args="--logging.dest=/var/log/kibana/kibana.log" -pidfile="/var/run/kibana/$name.pid" - -[ -r /etc/default/$name ] && . /etc/default/$name -[ -r /etc/sysconfig/$name ] && . /etc/sysconfig/$name - -export KBN_PATH_CONF -export NODE_OPTIONS - -[ -z "$nice" ] && nice=0 - -trace() { - logger -t "/etc/init.d/kibana" "$@" -} - -emit() { - trace "$@" - echo "$@" -} - -start() { - [ ! -d "/var/run/kibana/" ] && mkdir "/var/run/kibana/" - chown "$user":"$group" "/var/run/kibana/" - chmod 755 "/var/run/kibana/" - - chroot --userspec "$user":"$group" "$chroot" sh -c " - - cd \"$chdir\" - exec \"$program $args\" - " >> /var/log/kibana/kibana.log 2>&1 & - - # Generate the pidfile from here. If we instead made the forked process - # generate it there will be a race condition between the pidfile writing - # and a process possibly asking for status. - echo $! > $pidfile - - emit "$name started" - return 0 -} - -stop() { - # Try a few times to kill TERM the program - if status ; then - pid=$(cat "$pidfile") - trace "Killing $name (pid $pid) with SIGTERM" - kill -TERM $pid - # Wait for it to exit. - for i in 1 2 3 4 5 ; do - trace "Waiting $name (pid $pid) to die..." - status || break - sleep 1 - done - if status ; then - if [ "$KILL_ON_STOP_TIMEOUT" -eq 1 ] ; then - trace "Timeout reached. Killing $name (pid $pid) with SIGKILL. This may result in data loss." - kill -KILL $pid - emit "$name killed with SIGKILL." - else - emit "$name stop failed; still running." - fi - else - emit "$name stopped." - fi - fi -} - -status() { - if [ -f "$pidfile" ] ; then - pid=$(cat "$pidfile") - if ps -p $pid > /dev/null 2> /dev/null ; then - # process by this pid is running. - # It may not be our pid, but that's what you get with just pidfiles. - # TODO(sissel): Check if this process seems to be the same as the one we - # expect. It'd be nice to use flock here, but flock uses fork, not exec, - # so it makes it quite awkward to use in this case. - return 0 - else - return 2 # program is dead but pid file exists - fi - else - return 3 # program is not running - fi -} - -force_stop() { - if status ; then - stop - status && kill -KILL $(cat "$pidfile") - fi -} - - -case "$1" in - force-start|start|stop|force-stop|restart) - trace "Attempting '$1' on kibana" - ;; -esac - -case "$1" in - force-start) - PRESTART=no - exec "$0" start - ;; - start) - status - code=$? - if [ $code -eq 0 ]; then - emit "$name is already running" - exit $code - else - start - exit $? - fi - ;; - stop) stop ;; - force-stop) force_stop ;; - status) - status - code=$? - if [ $code -eq 0 ] ; then - emit "$name is running" - else - emit "$name is not running" - fi - exit $code - ;; - restart) - - stop && start - ;; - *) - echo "Usage: $SCRIPTNAME {start|force-start|stop|force-start|force-stop|status|restart}" >&2 - exit 3 - ;; -esac - -exit $? From 6deafd06b84d4c94ead42e0860e75d39a0c70ca0 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Thu, 29 Oct 2020 16:43:22 +0100 Subject: [PATCH 35/80] [Search] Use session service on a dashboard (#81297) --- ...ugins-embeddable-public.embeddableinput.md | 1 + .../application/dashboard_app_controller.tsx | 17 +++---- .../embeddable/dashboard_container.test.tsx | 22 +++++++++ .../embeddable/dashboard_container.tsx | 12 ++++- .../data/public/search/expressions/esaggs.ts | 7 ++- .../embeddable/search_embeddable.ts | 9 +++- src/plugins/embeddable/common/types.ts | 5 ++ .../lib/embeddables/embeddable.test.tsx | 15 ++++++ .../public/lib/embeddables/embeddable.tsx | 7 +-- src/plugins/embeddable/public/public.api.md | 1 + .../common/adapters/request/types.ts | 1 + .../requests/components/requests_view.tsx | 15 ++++++ .../public/embeddable/visualize_embeddable.ts | 1 + .../embeddable/embeddable.test.tsx | 11 ++++- .../embeddable/embeddable.tsx | 1 + .../embeddable/expression_wrapper.tsx | 3 ++ .../dashboard/async_search/async_search.ts | 46 ++++++++++++++++-- .../dashboard/async_search/data.json | 48 +++++++++++++++++++ 18 files changed, 202 insertions(+), 20 deletions(-) diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md index d1d97d50f5948..f36f7b4ee77a4 100644 --- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md @@ -19,5 +19,6 @@ export declare type EmbeddableInput = { timeRange?: TimeRange; query?: Query; filters?: Filter[]; + searchSessionId?: string; }; ``` diff --git a/src/plugins/dashboard/public/application/dashboard_app_controller.tsx b/src/plugins/dashboard/public/application/dashboard_app_controller.tsx index fa45e433050ab..e5947b73b305b 100644 --- a/src/plugins/dashboard/public/application/dashboard_app_controller.tsx +++ b/src/plugins/dashboard/public/application/dashboard_app_controller.tsx @@ -139,7 +139,7 @@ export class DashboardAppController { dashboardCapabilities, scopedHistory, embeddableCapabilities: { visualizeCapabilities, mapsCapabilities }, - data: { query: queryService }, + data: { query: queryService, search: searchService }, core: { notifications, overlays, @@ -412,8 +412,9 @@ export class DashboardAppController { >(DASHBOARD_CONTAINER_TYPE); if (dashboardFactory) { + const searchSessionId = searchService.session.start(); dashboardFactory - .create(getDashboardInput()) + .create({ ...getDashboardInput(), searchSessionId }) .then((container: DashboardContainer | ErrorEmbeddable | undefined) => { if (container && !isErrorEmbeddable(container)) { dashboardContainer = container; @@ -572,7 +573,7 @@ export class DashboardAppController { differences.filters = appStateDashboardInput.filters; } - Object.keys(_.omit(containerInput, ['filters'])).forEach((key) => { + Object.keys(_.omit(containerInput, ['filters', 'searchSessionId'])).forEach((key) => { const containerValue = (containerInput as { [key: string]: unknown })[key]; const appStateValue = ((appStateDashboardInput as unknown) as { [key: string]: unknown })[ key @@ -590,7 +591,8 @@ export class DashboardAppController { const refreshDashboardContainer = () => { const changes = getChangesFromAppStateForContainerState(); if (changes && dashboardContainer) { - dashboardContainer.updateInput(changes); + const searchSessionId = searchService.session.start(); + dashboardContainer.updateInput({ ...changes, searchSessionId }); } }; @@ -1109,12 +1111,6 @@ export class DashboardAppController { $scope.model.filters = filterManager.getFilters(); $scope.model.query = queryStringManager.getQuery(); dashboardStateManager.applyFilters($scope.model.query, $scope.model.filters); - if (dashboardContainer) { - dashboardContainer.updateInput({ - filters: $scope.model.filters, - query: $scope.model.query, - }); - } }, }); @@ -1159,6 +1155,7 @@ export class DashboardAppController { if (dashboardContainer) { dashboardContainer.destroy(); } + searchService.session.clear(); }); } } diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx index a7226082d3dce..89aacf2a84029 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx @@ -134,3 +134,25 @@ test('Container view mode change propagates to new children', async () => { expect(embeddable.getInput().viewMode).toBe(ViewMode.EDIT); }); + +test('searchSessionId propagates to children', async () => { + const searchSessionId1 = 'searchSessionId1'; + const container = new DashboardContainer( + getSampleDashboardInput({ searchSessionId: searchSessionId1 }), + options + ); + const embeddable = await container.addNewEmbeddable< + ContactCardEmbeddableInput, + ContactCardEmbeddableOutput, + ContactCardEmbeddable + >(CONTACT_CARD_EMBEDDABLE, { + firstName: 'Bob', + }); + + expect(embeddable.getInput().searchSessionId).toBe(searchSessionId1); + + const searchSessionId2 = 'searchSessionId2'; + container.updateInput({ searchSessionId: searchSessionId2 }); + + expect(embeddable.getInput().searchSessionId).toBe(searchSessionId2); +}); diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx index 036880a1d088b..757488185fe8e 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx @@ -78,6 +78,7 @@ export interface InheritedChildInput extends IndexSignature { viewMode: ViewMode; hidePanelTitles?: boolean; id: string; + searchSessionId?: string; } export interface DashboardContainerOptions { @@ -228,7 +229,15 @@ export class DashboardContainer extends Container { // Create a new search source that inherits the original search source // but has the appropriate timeRange applied via a filter. @@ -143,6 +145,7 @@ const handleCourierRequest = async ({ defaultMessage: 'This request queries Elasticsearch to fetch the data for the visualization.', }), + searchSessionId, } ); request.stats(getRequestInspectorStats(requestSearchSource)); @@ -150,6 +153,7 @@ const handleCourierRequest = async ({ try { const response = await requestSearchSource.fetch({ abortSignal, + sessionId: searchSessionId, }); request.stats(getResponseInspectorStats(response, searchSource)).ok({ json: response }); @@ -248,7 +252,7 @@ export const esaggs = (): EsaggsExpressionFunctionDefinition => ({ multi: true, }, }, - async fn(input, args, { inspectorAdapters, abortSignal }) { + async fn(input, args, { inspectorAdapters, abortSignal, getSearchSessionId }) { const indexPatterns = getIndexPatterns(); const { filterManager } = getQueryService(); const searchService = getSearchService(); @@ -276,6 +280,7 @@ export const esaggs = (): EsaggsExpressionFunctionDefinition => ({ inspectorAdapters: inspectorAdapters as Adapters, filterManager, abortSignal: (abortSignal as unknown) as AbortSignal, + searchSessionId: getSearchSessionId(), }); const table: Datatable = { diff --git a/src/plugins/discover/public/application/embeddable/search_embeddable.ts b/src/plugins/discover/public/application/embeddable/search_embeddable.ts index af88cacfcf992..170078076ec6f 100644 --- a/src/plugins/discover/public/application/embeddable/search_embeddable.ts +++ b/src/plugins/discover/public/application/embeddable/search_embeddable.ts @@ -266,6 +266,8 @@ export class SearchEmbeddable } private fetch = async () => { + const searchSessionId = this.input.searchSessionId; + if (!this.searchScope) return; const { searchSource } = this.savedSearch; @@ -292,7 +294,11 @@ export class SearchEmbeddable const description = i18n.translate('discover.embeddable.inspectorRequestDescription', { defaultMessage: 'This request queries Elasticsearch to fetch the data for the search.', }); - const inspectorRequest = this.inspectorAdaptors.requests.start(title, { description }); + + const inspectorRequest = this.inspectorAdaptors.requests.start(title, { + description, + searchSessionId, + }); inspectorRequest.stats(getRequestInspectorStats(searchSource)); searchSource.getSearchRequestBody().then((body: Record) => { inspectorRequest.json(body); @@ -303,6 +309,7 @@ export class SearchEmbeddable // Make the request const resp = await searchSource.fetch({ abortSignal: this.abortController.signal, + sessionId: searchSessionId, }); this.updateOutput({ loading: false, error: undefined }); diff --git a/src/plugins/embeddable/common/types.ts b/src/plugins/embeddable/common/types.ts index 68b842c934de8..2737f2678ff32 100644 --- a/src/plugins/embeddable/common/types.ts +++ b/src/plugins/embeddable/common/types.ts @@ -67,4 +67,9 @@ export type EmbeddableInput = { * Visualization filters used to narrow down results. */ filters?: Filter[]; + + /** + * Search session id to group searches + */ + searchSessionId?: string; }; diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable.test.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable.test.tsx index 340d851f3eedf..b020006c0c2bb 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable.test.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable.test.tsx @@ -25,6 +25,7 @@ import { EmbeddableOutput, EmbeddableInput } from './i_embeddable'; import { ViewMode } from '../types'; import { ContactCardEmbeddable } from '../test_samples/embeddables/contact_card/contact_card_embeddable'; import { FilterableEmbeddable } from '../test_samples/embeddables/filterable_embeddable'; +import type { Filter } from '../../../../data/public'; class TestClass { constructor() {} @@ -79,6 +80,20 @@ test('Embeddable reload is called if lastReloadRequest input time changes', asyn expect(hello.reload).toBeCalledTimes(1); }); +test('Embeddable reload is called if lastReloadRequest input time changed and new input is used', async () => { + const hello = new FilterableEmbeddable({ id: '123', filters: [], lastReloadRequestTime: 0 }); + + const aFilter = ({} as unknown) as Filter; + hello.reload = jest.fn(() => { + // when reload is called embeddable already has new input + expect(hello.getInput().filters).toEqual([aFilter]); + }); + + hello.updateInput({ lastReloadRequestTime: 1, filters: [aFilter] }); + + expect(hello.reload).toBeCalledTimes(1); +}); + test('Embeddable reload is not called if lastReloadRequest input time does not change', async () => { const hello = new FilterableEmbeddable({ id: '123', filters: [], lastReloadRequestTime: 1 }); diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx index 9267d600360cf..c7afc157c1452 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx @@ -195,14 +195,15 @@ export abstract class Embeddable< private onResetInput(newInput: TEmbeddableInput) { if (!isEqual(this.input, newInput)) { - if (this.input.lastReloadRequestTime !== newInput.lastReloadRequestTime) { - this.reload(); - } + const oldLastReloadRequestTime = this.input.lastReloadRequestTime; this.input = newInput; this.input$.next(newInput); this.updateOutput({ title: getPanelTitle(this.input, this.output), } as Partial); + if (oldLastReloadRequestTime !== newInput.lastReloadRequestTime) { + this.reload(); + } } } diff --git a/src/plugins/embeddable/public/public.api.md b/src/plugins/embeddable/public/public.api.md index 84dd97c8288fc..9939ba2a0f8a1 100644 --- a/src/plugins/embeddable/public/public.api.md +++ b/src/plugins/embeddable/public/public.api.md @@ -425,6 +425,7 @@ export type EmbeddableInput = { timeRange?: TimeRange; query?: Query; filters?: Filter[]; + searchSessionId?: string; }; // Warning: (ae-missing-release-tag) "EmbeddableInstanceConfiguration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/src/plugins/inspector/common/adapters/request/types.ts b/src/plugins/inspector/common/adapters/request/types.ts index 0a62df7c8d10c..c08c2ef6f706f 100644 --- a/src/plugins/inspector/common/adapters/request/types.ts +++ b/src/plugins/inspector/common/adapters/request/types.ts @@ -49,6 +49,7 @@ export interface Request extends RequestParams { export interface RequestParams { id?: string; description?: string; + searchSessionId?: string; } export interface RequestStatistics { diff --git a/src/plugins/inspector/public/views/requests/components/requests_view.tsx b/src/plugins/inspector/public/views/requests/components/requests_view.tsx index a433ea70dc35c..13575de0c5064 100644 --- a/src/plugins/inspector/public/views/requests/components/requests_view.tsx +++ b/src/plugins/inspector/public/views/requests/components/requests_view.tsx @@ -153,6 +153,21 @@ export class RequestsViewComponent extends Component )} + {this.state.request && this.state.request.searchSessionId && ( + +

+ +

+
+ )} + {this.state.request && } diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts index a810b4b65528f..c12a0f0759018 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts @@ -374,6 +374,7 @@ export class VisualizeEmbeddable query: this.input.query, filters: this.input.filters, }, + searchSessionId: this.input.searchSessionId, uiState: this.vis.uiState, inspectorAdapters: this.inspectorAdapters, }; diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx index 3e05d4ddfbc20..9dc59eacd40d3 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx @@ -172,6 +172,7 @@ describe('embeddable', () => { timeRange, query, filters, + searchSessionId: 'searchSessionId', }); expect(expressionRenderer).toHaveBeenCalledTimes(2); @@ -182,7 +183,13 @@ describe('embeddable', () => { const query: Query = { language: 'kquery', query: '' }; const filters: Filter[] = [{ meta: { alias: 'test', negate: false, disabled: false } }]; - const input = { savedObjectId: '123', timeRange, query, filters } as LensEmbeddableInput; + const input = { + savedObjectId: '123', + timeRange, + query, + filters, + searchSessionId: 'searchSessionId', + } as LensEmbeddableInput; const embeddable = new Embeddable( { @@ -214,6 +221,8 @@ describe('embeddable', () => { filters, }) ); + + expect(expressionRenderer.mock.calls[0][0].searchSessionId).toBe(input.searchSessionId); }); it('should merge external context with query and filters of the saved object', async () => { diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx index d245b7f2fcde4..10c243a272138 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx @@ -177,6 +177,7 @@ export class Embeddable ExpressionRenderer={this.expressionRenderer} expression={this.expression || null} searchContext={this.getMergedSearchContext()} + searchSessionId={this.input.searchSessionId} handleEvent={this.handleEvent} />, domNode diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/expression_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/expression_wrapper.tsx index 4fb0630a305e7..13376e56e2144 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/expression_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/expression_wrapper.tsx @@ -19,6 +19,7 @@ export interface ExpressionWrapperProps { ExpressionRenderer: ReactExpressionRendererType; expression: string | null; searchContext: ExecutionContextSearch; + searchSessionId?: string; handleEvent: (event: ExpressionRendererEvent) => void; } @@ -27,6 +28,7 @@ export function ExpressionWrapper({ expression, searchContext, handleEvent, + searchSessionId, }: ExpressionWrapperProps) { return ( @@ -51,6 +53,7 @@ export function ExpressionWrapper({ padding="m" expression={expression} searchContext={searchContext} + searchSessionId={searchSessionId} renderError={(errorMessage, error) => (
diff --git a/x-pack/test/functional/apps/dashboard/async_search/async_search.ts b/x-pack/test/functional/apps/dashboard/async_search/async_search.ts index 6932a88635a67..4d37ee1589169 100644 --- a/x-pack/test/functional/apps/dashboard/async_search/async_search.ts +++ b/x-pack/test/functional/apps/dashboard/async_search/async_search.ts @@ -12,6 +12,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const log = getService('log'); const PageObjects = getPageObjects(['common', 'header', 'dashboard', 'visChart']); + const dashboardPanelActions = getService('dashboardPanelActions'); + const inspector = getService('inspector'); + const queryBar = getService('queryBar'); describe('dashboard with async search', () => { before(async function () { @@ -24,7 +27,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('not delayed should load', async () => { await PageObjects.common.navigateToApp('dashboard'); - await PageObjects.dashboard.gotoDashboardEditMode('Not Delayed'); + await PageObjects.dashboard.loadSavedDashboard('Not Delayed'); await PageObjects.header.waitUntilLoadingHasFinished(); await testSubjects.missingOrFail('embeddableErrorLabel'); const data = await PageObjects.visChart.getBarChartData('Sum of bytes'); @@ -33,7 +36,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('delayed should load', async () => { await PageObjects.common.navigateToApp('dashboard'); - await PageObjects.dashboard.gotoDashboardEditMode('Delayed 5s'); + await PageObjects.dashboard.loadSavedDashboard('Delayed 5s'); await PageObjects.header.waitUntilLoadingHasFinished(); await testSubjects.missingOrFail('embeddableErrorLabel'); const data = await PageObjects.visChart.getBarChartData(''); @@ -42,10 +45,47 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('timed out should show error', async () => { await PageObjects.common.navigateToApp('dashboard'); - await PageObjects.dashboard.gotoDashboardEditMode('Delayed 15s'); + await PageObjects.dashboard.loadSavedDashboard('Delayed 15s'); await PageObjects.header.waitUntilLoadingHasFinished(); await testSubjects.existOrFail('embeddableErrorLabel'); await testSubjects.existOrFail('searchTimeoutError'); }); + + it('multiple searches are grouped and only single error popup is shown', async () => { + await PageObjects.common.navigateToApp('dashboard'); + await PageObjects.dashboard.loadSavedDashboard('Multiple delayed'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.existOrFail('embeddableErrorLabel'); + // there should be two failed panels + expect((await testSubjects.findAll('embeddableErrorLabel')).length).to.be(2); + // but only single error toast because searches are grouped + expect((await testSubjects.findAll('searchTimeoutError')).length).to.be(1); + + // check that session ids are the same + const getSearchSessionIdByPanel = async (panelTitle: string) => { + await dashboardPanelActions.openInspectorByTitle(panelTitle); + await inspector.openInspectorRequestsView(); + const searchSessionId = await ( + await testSubjects.find('inspectorRequestSearchSessionId') + ).getAttribute('data-search-session-id'); + await inspector.close(); + return searchSessionId; + }; + + const panel1SessionId1 = await getSearchSessionIdByPanel('Sum of Bytes by Extension'); + const panel2SessionId1 = await getSearchSessionIdByPanel( + 'Sum of Bytes by Extension (Delayed 5s)' + ); + expect(panel1SessionId1).to.be(panel2SessionId1); + + await queryBar.clickQuerySubmitButton(); + + const panel1SessionId2 = await getSearchSessionIdByPanel('Sum of Bytes by Extension'); + const panel2SessionId2 = await getSearchSessionIdByPanel( + 'Sum of Bytes by Extension (Delayed 5s)' + ); + expect(panel1SessionId2).to.be(panel2SessionId2); + expect(panel1SessionId1).not.to.be(panel1SessionId2); + }); }); } diff --git a/x-pack/test/functional/es_archives/dashboard/async_search/data.json b/x-pack/test/functional/es_archives/dashboard/async_search/data.json index 2990097e88d00..486c73f711a6b 100644 --- a/x-pack/test/functional/es_archives/dashboard/async_search/data.json +++ b/x-pack/test/functional/es_archives/dashboard/async_search/data.json @@ -194,4 +194,52 @@ } } +{ + "type": "doc", + "value": { + "id": "dashboard:a41c6790-075d-11eb-be70-0bd5e8b57d03", + "index": ".kibana", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}" + }, + "optionsJSON": "{\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"ec585931-ce8e-43fd-aa94-a1a9612d24ba\"},\"panelIndex\":\"ec585931-ce8e-43fd-aa94-a1a9612d24ba\",\"embeddableConfig\":{},\"panelRefName\":\"panel_0\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":15,\"i\":\"c7b18010-462b-4e55-a974-fdec2ae64b06\"},\"panelIndex\":\"c7b18010-462b-4e55-a974-fdec2ae64b06\",\"embeddableConfig\":{},\"panelRefName\":\"panel_1\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":15,\"w\":24,\"h\":15,\"i\":\"e67704f7-20b7-4ade-8dee-972a9d187107\"},\"panelIndex\":\"e67704f7-20b7-4ade-8dee-972a9d187107\",\"embeddableConfig\":{},\"panelRefName\":\"panel_2\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":24,\"y\":15,\"w\":24,\"h\":15,\"i\":\"f0b03592-10f1-41cd-9929-0cb4163bcd16\"},\"panelIndex\":\"f0b03592-10f1-41cd-9929-0cb4163bcd16\",\"embeddableConfig\":{},\"panelRefName\":\"panel_3\"}]", + "refreshInterval": { "pause": true, "value": 0 }, + "timeFrom": "2015-09-19T17:34:10.297Z", + "timeRestore": true, + "timeTo": "2015-09-23T00:09:17.180Z", + "title": "Multiple delayed", + "version": 1 + }, + "references": [ + { + "id": "14501a50-01e3-11eb-9b63-176d7b28a352", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "50a67010-075d-11eb-be70-0bd5e8b57d02", + "name": "panel_1", + "type": "visualization" + }, + { + "id": "6c9f3830-01e3-11eb-9b63-176d7b28a352", + "name": "panel_2", + "type": "visualization" + }, + { + "id": "50a67010-075d-11eb-be70-0bd5e8b57d02", + "name": "panel_3", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2020-03-19T11:59:53.701Z" + } + } +} From afd5fe3b8a197ee0177a661fa65f816031708970 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Thu, 29 Oct 2020 16:47:34 +0100 Subject: [PATCH 36/80] Date column utilities (#81007) --- packages/kbn-optimizer/limits.yml | 2 +- .../common/search/aggs/aggs_service.test.ts | 5 +- .../data/common/search/aggs/aggs_service.ts | 20 ++- .../search/aggs/buckets/date_histogram.ts | 21 +-- src/plugins/data/common/search/aggs/types.ts | 15 +++ .../data/common/search/aggs/utils/index.ts | 1 + .../search/aggs/utils/infer_time_zone.test.ts | 79 ++++++++++++ .../search/aggs/utils/infer_time_zone.ts | 46 +++++++ .../aggs/utils/time_column_meta.test.ts | 121 ++++++++++++++++++ .../search/aggs/utils/time_column_meta.ts | 66 ++++++++++ src/plugins/data/public/public.api.md | 3 +- .../public/search/aggs/aggs_service.test.ts | 5 +- .../data/public/search/aggs/aggs_service.ts | 17 ++- src/plugins/data/public/search/aggs/mocks.ts | 1 + .../data/public/search/expressions/esaggs.ts | 7 + .../data/public/search/search_service.ts | 2 +- .../data/server/index_patterns/mocks.ts | 2 +- .../server/search/aggs/aggs_service.test.ts | 2 + .../data/server/search/aggs/aggs_service.ts | 19 ++- src/plugins/data/server/search/aggs/mocks.ts | 1 + .../data/server/search/search_service.ts | 2 +- src/plugins/data/server/server.api.md | 1 + src/plugins/embeddable/public/public.api.md | 1 + .../snapshots/baseline/combined_test2.json | 2 +- .../snapshots/baseline/combined_test3.json | 2 +- .../snapshots/baseline/final_output_test.json | 2 +- .../snapshots/baseline/metric_all_data.json | 2 +- .../baseline/metric_multi_metric_data.json | 2 +- .../baseline/metric_percentage_mode.json | 2 +- .../baseline/metric_single_metric_data.json | 2 +- .../snapshots/baseline/partial_test_1.json | 2 +- .../snapshots/baseline/partial_test_2.json | 2 +- .../snapshots/baseline/partial_test_3.json | 2 +- .../snapshots/baseline/step_output_test2.json | 2 +- .../snapshots/baseline/step_output_test3.json | 2 +- .../snapshots/baseline/tagcloud_all_data.json | 2 +- .../snapshots/baseline/tagcloud_fontsize.json | 2 +- .../baseline/tagcloud_metric_data.json | 2 +- .../snapshots/baseline/tagcloud_options.json | 2 +- .../snapshots/session/combined_test2.json | 2 +- .../snapshots/session/combined_test3.json | 2 +- .../snapshots/session/final_output_test.json | 2 +- .../snapshots/session/metric_all_data.json | 2 +- .../session/metric_multi_metric_data.json | 2 +- .../session/metric_percentage_mode.json | 2 +- .../session/metric_single_metric_data.json | 2 +- .../snapshots/session/partial_test_1.json | 2 +- .../snapshots/session/partial_test_2.json | 2 +- .../snapshots/session/partial_test_3.json | 2 +- .../snapshots/session/step_output_test2.json | 2 +- .../snapshots/session/step_output_test3.json | 2 +- .../snapshots/session/tagcloud_all_data.json | 2 +- .../snapshots/session/tagcloud_fontsize.json | 2 +- .../session/tagcloud_metric_data.json | 2 +- .../snapshots/session/tagcloud_options.json | 2 +- 55 files changed, 436 insertions(+), 67 deletions(-) create mode 100644 src/plugins/data/common/search/aggs/utils/infer_time_zone.test.ts create mode 100644 src/plugins/data/common/search/aggs/utils/infer_time_zone.ts create mode 100644 src/plugins/data/common/search/aggs/utils/time_column_meta.test.ts create mode 100644 src/plugins/data/common/search/aggs/utils/time_column_meta.ts diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index c660d37222504..3f9fdb164e759 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -14,7 +14,7 @@ pageLoadAssetSize: dashboard: 374194 dashboardEnhanced: 65646 dashboardMode: 22716 - data: 1287839 + data: 1317839 dataEnhanced: 50420 devTools: 38637 discover: 105145 diff --git a/src/plugins/data/common/search/aggs/aggs_service.test.ts b/src/plugins/data/common/search/aggs/aggs_service.test.ts index bcf2101704c80..160860bcce591 100644 --- a/src/plugins/data/common/search/aggs/aggs_service.test.ts +++ b/src/plugins/data/common/search/aggs/aggs_service.test.ts @@ -44,6 +44,8 @@ describe('Aggs service', () => { }; startDeps = { getConfig: jest.fn(), + getIndexPattern: jest.fn(), + isDefaultTimezone: jest.fn(), }; }); @@ -201,8 +203,9 @@ describe('Aggs service', () => { describe('start()', () => { test('exposes proper contract', () => { const start = service.start(startDeps); - expect(Object.keys(start).length).toBe(3); + expect(Object.keys(start).length).toBe(4); expect(start).toHaveProperty('calculateAutoTimeExpression'); + expect(start).toHaveProperty('getDateMetaByDatatableColumn'); expect(start).toHaveProperty('createAggConfigs'); expect(start).toHaveProperty('types'); }); diff --git a/src/plugins/data/common/search/aggs/aggs_service.ts b/src/plugins/data/common/search/aggs/aggs_service.ts index 6f3e3904dbbd5..b6afa708f9e6f 100644 --- a/src/plugins/data/common/search/aggs/aggs_service.ts +++ b/src/plugins/data/common/search/aggs/aggs_service.ts @@ -18,7 +18,7 @@ */ import { ExpressionsServiceSetup } from 'src/plugins/expressions/common'; -import { UI_SETTINGS } from '../../../common'; +import { IndexPattern, UI_SETTINGS } from '../../../common'; import { GetConfigFn } from '../../types'; import { AggConfigs, @@ -28,6 +28,7 @@ import { getCalculateAutoTimeExpression, } from './'; import { AggsCommonSetup, AggsCommonStart } from './types'; +import { getDateMetaByDatatableColumn } from './utils/time_column_meta'; /** @internal */ export const aggsRequiredUiSettings = [ @@ -50,6 +51,8 @@ export interface AggsCommonSetupDependencies { /** @internal */ export interface AggsCommonStartDependencies { getConfig: GetConfigFn; + getIndexPattern(id: string): Promise; + isDefaultTimezone: () => boolean; } /** @@ -77,11 +80,22 @@ export class AggsCommonService { }; } - public start({ getConfig }: AggsCommonStartDependencies): AggsCommonStart { + public start({ + getConfig, + getIndexPattern, + isDefaultTimezone, + }: AggsCommonStartDependencies): AggsCommonStart { const aggTypesStart = this.aggTypesRegistry.start(); + const calculateAutoTimeExpression = getCalculateAutoTimeExpression(getConfig); return { - calculateAutoTimeExpression: getCalculateAutoTimeExpression(getConfig), + calculateAutoTimeExpression, + getDateMetaByDatatableColumn: getDateMetaByDatatableColumn({ + calculateAutoTimeExpression, + getIndexPattern, + getConfig, + isDefaultTimezone, + }), createAggConfigs: (indexPattern, configStates = [], schemas) => { return new AggConfigs(indexPattern, configStates, { typesRegistry: aggTypesStart, diff --git a/src/plugins/data/common/search/aggs/buckets/date_histogram.ts b/src/plugins/data/common/search/aggs/buckets/date_histogram.ts index c273ca53a5fed..694b03f660452 100644 --- a/src/plugins/data/common/search/aggs/buckets/date_histogram.ts +++ b/src/plugins/data/common/search/aggs/buckets/date_histogram.ts @@ -34,6 +34,7 @@ import { writeParams } from '../agg_params'; import { isMetricAggType } from '../metrics/metric_agg_type'; import { BaseAggParams } from '../types'; import { dateHistogramInterval } from '../utils'; +import { inferTimeZone } from '../utils'; /** @internal */ export type CalculateBoundsFn = (timeRange: TimeRange) => TimeRangeBounds; @@ -235,25 +236,7 @@ export const getDateHistogramBucketAgg = ({ // time_zones being persisted into saved_objects serialize: noop, write(agg, output) { - // If a time_zone has been set explicitly always prefer this. - let tz = agg.params.time_zone; - if (!tz && agg.params.field) { - // If a field has been configured check the index pattern's typeMeta if a date_histogram on that - // field requires a specific time_zone - tz = get(agg.getIndexPattern(), [ - 'typeMeta', - 'aggs', - 'date_histogram', - agg.params.field.name, - 'time_zone', - ]); - } - if (!tz) { - // If the index pattern typeMeta data, didn't had a time zone assigned for the selected field use the configured tz - const detectedTimezone = moment.tz.guess(); - const tzOffset = moment().format('Z'); - tz = isDefaultTimezone() ? detectedTimezone || tzOffset : getConfig('dateFormat:tz'); - } + const tz = inferTimeZone(agg.params, agg.getIndexPattern(), isDefaultTimezone, getConfig); output.params.time_zone = tz; }, }, diff --git a/src/plugins/data/common/search/aggs/types.ts b/src/plugins/data/common/search/aggs/types.ts index aec3dcc9d068c..09a13762d4d70 100644 --- a/src/plugins/data/common/search/aggs/types.ts +++ b/src/plugins/data/common/search/aggs/types.ts @@ -18,7 +18,9 @@ */ import { Assign } from '@kbn/utility-types'; +import { DatatableColumn } from 'src/plugins/expressions'; import { IndexPattern } from '../../index_patterns/index_patterns/index_pattern'; +import { TimeRange } from '../../query'; import { AggConfigSerialized, AggConfigs, @@ -80,6 +82,19 @@ export interface AggsCommonSetup { /** @internal */ export interface AggsCommonStart { calculateAutoTimeExpression: ReturnType; + /** + * Helper function returning meta data about use date intervals for a data table column. + * If the column is not a column created by a date histogram aggregation of the esaggs data source, + * this function will return undefined. + * + * Otherwise, it will return the following attributes in an object: + * * `timeZone` time zone used to create the buckets (important e.g. for DST), + * * `timeRange` total time range of the fetch data (to infer partial buckets at the beginning and end of the data) + * * `interval` Interval used on elasticsearch (`auto` resolved to the actual interval) + */ + getDateMetaByDatatableColumn: ( + column: DatatableColumn + ) => Promise; createAggConfigs: ( indexPattern: IndexPattern, configStates?: CreateAggConfigParams[], diff --git a/src/plugins/data/common/search/aggs/utils/index.ts b/src/plugins/data/common/search/aggs/utils/index.ts index 99ce44207d80d..7d6cb1c7ef33f 100644 --- a/src/plugins/data/common/search/aggs/utils/index.ts +++ b/src/plugins/data/common/search/aggs/utils/index.ts @@ -23,3 +23,4 @@ export * from './get_format_with_aggs'; export * from './ipv4_address'; export * from './prop_filter'; export * from './to_angular_json'; +export * from './infer_time_zone'; diff --git a/src/plugins/data/common/search/aggs/utils/infer_time_zone.test.ts b/src/plugins/data/common/search/aggs/utils/infer_time_zone.test.ts new file mode 100644 index 0000000000000..8fc3726ee1b32 --- /dev/null +++ b/src/plugins/data/common/search/aggs/utils/infer_time_zone.test.ts @@ -0,0 +1,79 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +jest.mock('moment', () => { + const moment: any = jest.fn(() => { + return { + format: jest.fn(() => '-1;00'), + }; + }); + moment.tz = { + guess: jest.fn(() => 'CET'), + }; + return moment; +}); + +import { IndexPattern } from '../../../index_patterns'; +import { AggParamsDateHistogram } from '../buckets'; +import { inferTimeZone } from './infer_time_zone'; + +describe('inferTimeZone', () => { + it('reads time zone from agg params', () => { + const params: AggParamsDateHistogram = { + time_zone: 'CEST', + }; + expect(inferTimeZone(params, {} as IndexPattern, () => false, jest.fn())).toEqual('CEST'); + }); + + it('reads time zone from index pattern type meta if available', () => { + expect( + inferTimeZone( + { field: 'mydatefield' }, + ({ + typeMeta: { + aggs: { + date_histogram: { + mydatefield: { + time_zone: 'UTC', + }, + }, + }, + }, + } as unknown) as IndexPattern, + () => false, + jest.fn() + ) + ).toEqual('UTC'); + }); + + it('reads time zone from moment if set to default', () => { + expect(inferTimeZone({}, {} as IndexPattern, () => true, jest.fn())).toEqual('CET'); + }); + + it('reads time zone from config if not set to default', () => { + expect( + inferTimeZone( + {}, + {} as IndexPattern, + () => false, + () => 'CET' as any + ) + ).toEqual('CET'); + }); +}); diff --git a/src/plugins/data/common/search/aggs/utils/infer_time_zone.ts b/src/plugins/data/common/search/aggs/utils/infer_time_zone.ts new file mode 100644 index 0000000000000..282238c5a0459 --- /dev/null +++ b/src/plugins/data/common/search/aggs/utils/infer_time_zone.ts @@ -0,0 +1,46 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import moment from 'moment'; +import { IndexPattern } from '../../../index_patterns'; +import { AggParamsDateHistogram } from '../buckets'; + +export function inferTimeZone( + params: AggParamsDateHistogram, + indexPattern: IndexPattern, + isDefaultTimezone: () => boolean, + getConfig: (key: string) => T +) { + let tz = params.time_zone; + if (!tz && params.field) { + // If a field has been configured check the index pattern's typeMeta if a date_histogram on that + // field requires a specific time_zone + tz = indexPattern.typeMeta?.aggs?.date_histogram?.[params.field]?.time_zone; + } + if (!tz) { + // If the index pattern typeMeta data, didn't had a time zone assigned for the selected field use the configured tz + const detectedTimezone = moment.tz.guess(); + const tzOffset = moment().format('Z'); + tz = isDefaultTimezone() + ? detectedTimezone || tzOffset + : // if timezone is not the default, this will always return a string + (getConfig('dateFormat:tz') as string); + } + return tz; +} diff --git a/src/plugins/data/common/search/aggs/utils/time_column_meta.test.ts b/src/plugins/data/common/search/aggs/utils/time_column_meta.test.ts new file mode 100644 index 0000000000000..e56d622734554 --- /dev/null +++ b/src/plugins/data/common/search/aggs/utils/time_column_meta.test.ts @@ -0,0 +1,121 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { BUCKET_TYPES } from '../buckets'; +import { DateMetaByColumnDeps, getDateMetaByDatatableColumn } from './time_column_meta'; + +describe('getDateMetaByDatatableColumn', () => { + let params: DateMetaByColumnDeps; + beforeEach(() => { + params = { + calculateAutoTimeExpression: jest.fn().mockReturnValue('5m'), + getIndexPattern: jest.fn().mockResolvedValue({}), + isDefaultTimezone: jest.fn().mockReturnValue(true), + getConfig: jest.fn(), + }; + }); + + it('returns nothing on column from other data source', async () => { + expect( + await getDateMetaByDatatableColumn(params)({ + id: 'test', + name: 'test', + meta: { + type: 'date', + source: 'essql', + }, + }) + ).toEqual(undefined); + }); + + it('returns nothing on non date histogram column', async () => { + expect( + await getDateMetaByDatatableColumn(params)({ + id: 'test', + name: 'test', + meta: { + type: 'date', + source: 'esaggs', + sourceParams: { + type: BUCKET_TYPES.TERMS, + }, + }, + }) + ).toEqual(undefined); + }); + + it('returns time range, time zone and interval', async () => { + expect( + await getDateMetaByDatatableColumn(params)({ + id: 'test', + name: 'test', + meta: { + type: 'date', + source: 'esaggs', + sourceParams: { + type: BUCKET_TYPES.DATE_HISTOGRAM, + params: { + time_zone: 'UTC', + interval: '1h', + }, + appliedTimeRange: { + from: 'now-5d', + to: 'now', + }, + }, + }, + }) + ).toEqual({ + timeZone: 'UTC', + timeRange: { + from: 'now-5d', + to: 'now', + }, + interval: '1h', + }); + }); + + it('returns resolved auto interval', async () => { + expect( + await getDateMetaByDatatableColumn(params)({ + id: 'test', + name: 'test', + meta: { + type: 'date', + source: 'esaggs', + sourceParams: { + type: BUCKET_TYPES.DATE_HISTOGRAM, + params: { + time_zone: 'UTC', + interval: 'auto', + }, + appliedTimeRange: { + from: 'now-5d', + to: 'now', + }, + }, + }, + }) + ).toEqual( + expect.objectContaining({ + interval: '5m', + }) + ); + }); +}); diff --git a/src/plugins/data/common/search/aggs/utils/time_column_meta.ts b/src/plugins/data/common/search/aggs/utils/time_column_meta.ts new file mode 100644 index 0000000000000..1bea716c6a049 --- /dev/null +++ b/src/plugins/data/common/search/aggs/utils/time_column_meta.ts @@ -0,0 +1,66 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { DatatableColumn } from 'src/plugins/expressions/common'; +import { IndexPattern } from '../../../index_patterns'; + +import { TimeRange } from '../../../types'; +import { AggParamsDateHistogram, BUCKET_TYPES } from '../buckets'; +import { inferTimeZone } from './infer_time_zone'; + +export interface DateMetaByColumnDeps { + calculateAutoTimeExpression: (range: TimeRange) => string | undefined; + getIndexPattern: (id: string) => Promise; + isDefaultTimezone: () => boolean; + getConfig: (key: string) => T; +} + +export const getDateMetaByDatatableColumn = ({ + calculateAutoTimeExpression, + getIndexPattern, + isDefaultTimezone, + getConfig, +}: DateMetaByColumnDeps) => async ( + column: DatatableColumn +): Promise => { + if (column.meta.source !== 'esaggs') return; + if (column.meta.sourceParams?.type !== BUCKET_TYPES.DATE_HISTOGRAM) return; + const params = column.meta.sourceParams.params as AggParamsDateHistogram; + const appliedTimeRange = column.meta.sourceParams.appliedTimeRange as TimeRange; + + const tz = inferTimeZone( + params, + await getIndexPattern(column.meta.sourceParams.indexPatternId as string), + isDefaultTimezone, + getConfig + ); + + const interval = + params.interval === 'auto' ? calculateAutoTimeExpression(appliedTimeRange) : params.interval; + + if (!interval) { + throw new Error('time interval could not be determined'); + } + + return { + timeZone: tz, + timeRange: appliedTimeRange, + interval, + }; +}; diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 81fa6d4ba20db..7ee21236c1c79 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -16,6 +16,7 @@ import { CoreSetup } from 'src/core/public'; import { CoreSetup as CoreSetup_2 } from 'kibana/public'; import { CoreStart } from 'kibana/public'; import { CoreStart as CoreStart_2 } from 'src/core/public'; +import { DatatableColumn as DatatableColumn_2 } from 'src/plugins/expressions'; import { Ensure } from '@kbn/utility-types'; import { EnvironmentMode } from '@kbn/config'; import { ErrorToastOptions } from 'src/core/public/notifications'; @@ -2285,7 +2286,7 @@ export const UI_SETTINGS: { // src/plugins/data/common/es_query/filters/phrase_filter.ts:33:3 - (ae-forgotten-export) The symbol "PhraseFilterMeta" needs to be exported by the entry point index.d.ts // src/plugins/data/common/es_query/filters/phrases_filter.ts:31:3 - (ae-forgotten-export) The symbol "PhrasesFilterMeta" needs to be exported by the entry point index.d.ts // src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:62:5 - (ae-forgotten-export) The symbol "FormatFieldFn" needs to be exported by the entry point index.d.ts -// src/plugins/data/common/search/aggs/types.ts:98:51 - (ae-forgotten-export) The symbol "AggTypesRegistryStart" needs to be exported by the entry point index.d.ts +// src/plugins/data/common/search/aggs/types.ts:113:51 - (ae-forgotten-export) The symbol "AggTypesRegistryStart" needs to be exported by the entry point index.d.ts // src/plugins/data/public/field_formats/field_formats_service.ts:67:3 - (ae-forgotten-export) The symbol "FormatFactory" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "FILTERS" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "getDisplayValueFromFilter" needs to be exported by the entry point index.d.ts diff --git a/src/plugins/data/public/search/aggs/aggs_service.test.ts b/src/plugins/data/public/search/aggs/aggs_service.test.ts index db25dfb300d11..de747d234b441 100644 --- a/src/plugins/data/public/search/aggs/aggs_service.test.ts +++ b/src/plugins/data/public/search/aggs/aggs_service.test.ts @@ -23,6 +23,7 @@ import { coreMock } from '../../../../../core/public/mocks'; import { expressionsPluginMock } from '../../../../../plugins/expressions/public/mocks'; import { BucketAggType, getAggTypes, MetricAggType } from '../../../common'; import { fieldFormatsServiceMock } from '../../field_formats/mocks'; +import { dataPluginMock } from '../../mocks'; import { AggsService, @@ -46,6 +47,7 @@ describe('AggsService - public', () => { }; startDeps = { fieldFormats: fieldFormatsServiceMock.createStartContract(), + indexPatterns: dataPluginMock.createStartContract().indexPatterns, uiSettings, }; }); @@ -86,8 +88,9 @@ describe('AggsService - public', () => { describe('start()', () => { test('exposes proper contract', () => { const start = service.start(startDeps); - expect(Object.keys(start).length).toBe(3); + expect(Object.keys(start).length).toBe(4); expect(start).toHaveProperty('calculateAutoTimeExpression'); + expect(start).toHaveProperty('getDateMetaByDatatableColumn'); expect(start).toHaveProperty('createAggConfigs'); expect(start).toHaveProperty('types'); }); diff --git a/src/plugins/data/public/search/aggs/aggs_service.ts b/src/plugins/data/public/search/aggs/aggs_service.ts index 4b088ddfe314f..85e0f604bb8b5 100644 --- a/src/plugins/data/public/search/aggs/aggs_service.ts +++ b/src/plugins/data/public/search/aggs/aggs_service.ts @@ -32,6 +32,7 @@ import { AggTypesDependencies, } from '../../../common/search/aggs'; import { AggsSetup, AggsStart } from './types'; +import { IndexPatternsContract } from '../../index_patterns'; /** * Aggs needs synchronous access to specific uiSettings. Since settings can change @@ -68,6 +69,7 @@ export interface AggsSetupDependencies { export interface AggsStartDependencies { fieldFormats: FieldFormatsStart; uiSettings: IUiSettingsClient; + indexPatterns: IndexPatternsContract; } /** @@ -94,9 +96,17 @@ export class AggsService { return this.aggsCommonService.setup({ registerFunction }); } - public start({ fieldFormats, uiSettings }: AggsStartDependencies): AggsStart { - const { calculateAutoTimeExpression, types } = this.aggsCommonService.start({ + public start({ fieldFormats, uiSettings, indexPatterns }: AggsStartDependencies): AggsStart { + const isDefaultTimezone = () => uiSettings.isDefault('dateFormat:tz'); + + const { + calculateAutoTimeExpression, + getDateMetaByDatatableColumn, + types, + } = this.aggsCommonService.start({ getConfig: this.getConfig!, + getIndexPattern: indexPatterns.get, + isDefaultTimezone, }); const aggTypesDependencies: AggTypesDependencies = { @@ -106,7 +116,7 @@ export class AggsService { deserialize: fieldFormats.deserialize, getDefaultInstance: fieldFormats.getDefaultInstance, }), - isDefaultTimezone: () => uiSettings.isDefault('dateFormat:tz'), + isDefaultTimezone, }; // initialize each agg type and store in memory @@ -137,6 +147,7 @@ export class AggsService { return { calculateAutoTimeExpression, + getDateMetaByDatatableColumn, createAggConfigs: (indexPattern, configStates = [], schemas) => { return new AggConfigs(indexPattern, configStates, { typesRegistry }); }, diff --git a/src/plugins/data/public/search/aggs/mocks.ts b/src/plugins/data/public/search/aggs/mocks.ts index ca13343777e63..abc930f00b594 100644 --- a/src/plugins/data/public/search/aggs/mocks.ts +++ b/src/plugins/data/public/search/aggs/mocks.ts @@ -67,6 +67,7 @@ export const searchAggsSetupMock = (): AggsSetup => ({ export const searchAggsStartMock = (): AggsStart => ({ calculateAutoTimeExpression: getCalculateAutoTimeExpression(getConfig), + getDateMetaByDatatableColumn: jest.fn(), createAggConfigs: jest.fn().mockImplementation((indexPattern, configStates = [], schemas) => { return new AggConfigs(indexPattern, configStates, { typesRegistry: mockAggTypesRegistry(), diff --git a/src/plugins/data/public/search/expressions/esaggs.ts b/src/plugins/data/public/search/expressions/esaggs.ts index 0aab345a4ebc0..dba77d398c8b6 100644 --- a/src/plugins/data/public/search/expressions/esaggs.ts +++ b/src/plugins/data/public/search/expressions/esaggs.ts @@ -298,6 +298,13 @@ export const esaggs = (): EsaggsExpressionFunctionDefinition => ({ source: 'esaggs', sourceParams: { indexPatternId: indexPattern.id, + appliedTimeRange: + column.aggConfig.params.field?.name && + input?.timeRange && + args.timeFields && + args.timeFields.includes(column.aggConfig.params.field?.name) + ? { from: input.timeRange.from, to: input.timeRange.to } + : undefined, ...column.aggConfig.serialize(), }, }, diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts index f955dc5b6ebd5..3dbabfc68fdbc 100644 --- a/src/plugins/data/public/search/search_service.ts +++ b/src/plugins/data/public/search/search_service.ts @@ -143,7 +143,7 @@ export class SearchService implements Plugin { }; return { - aggs: this.aggsService.start({ fieldFormats, uiSettings }), + aggs: this.aggsService.start({ fieldFormats, uiSettings, indexPatterns }), search, showError: (e: Error) => { this.searchInterceptor.showError(e); diff --git a/src/plugins/data/server/index_patterns/mocks.ts b/src/plugins/data/server/index_patterns/mocks.ts index 8f95afe3b3c9d..52d8aa1e35093 100644 --- a/src/plugins/data/server/index_patterns/mocks.ts +++ b/src/plugins/data/server/index_patterns/mocks.ts @@ -19,6 +19,6 @@ export function createIndexPatternsStartMock() { return { - indexPatternsServiceFactory: jest.fn(), + indexPatternsServiceFactory: jest.fn().mockResolvedValue({ get: jest.fn() }), }; } diff --git a/src/plugins/data/server/search/aggs/aggs_service.test.ts b/src/plugins/data/server/search/aggs/aggs_service.test.ts index d9a945a15fb67..cb4239cc339c4 100644 --- a/src/plugins/data/server/search/aggs/aggs_service.test.ts +++ b/src/plugins/data/server/search/aggs/aggs_service.test.ts @@ -23,6 +23,7 @@ import { coreMock } from '../../../../../core/server/mocks'; import { expressionsPluginMock } from '../../../../../plugins/expressions/server/mocks'; import { BucketAggType, getAggTypes, MetricAggType } from '../../../common'; import { createFieldFormatsStartMock } from '../../field_formats/mocks'; +import { createIndexPatternsStartMock } from '../../index_patterns/mocks'; import { AggsService, AggsSetupDependencies, AggsStartDependencies } from './aggs_service'; @@ -40,6 +41,7 @@ describe('AggsService - server', () => { }; startDeps = { fieldFormats: createFieldFormatsStartMock(), + indexPatterns: createIndexPatternsStartMock(), uiSettings, }; }); diff --git a/src/plugins/data/server/search/aggs/aggs_service.ts b/src/plugins/data/server/search/aggs/aggs_service.ts index 3e5cd8adb44a6..c805c8af6694c 100644 --- a/src/plugins/data/server/search/aggs/aggs_service.ts +++ b/src/plugins/data/server/search/aggs/aggs_service.ts @@ -30,6 +30,7 @@ import { TimeRange, } from '../../../common'; import { FieldFormatsStart } from '../../field_formats'; +import { IndexPatternsServiceStart } from '../../index_patterns'; import { AggsSetup, AggsStart } from './types'; /** @internal */ @@ -41,6 +42,7 @@ export interface AggsSetupDependencies { export interface AggsStartDependencies { fieldFormats: FieldFormatsStart; uiSettings: UiSettingsServiceStart; + indexPatterns: IndexPatternsServiceStart; } /** @@ -61,7 +63,7 @@ export class AggsService { return this.aggsCommonService.setup({ registerFunction }); } - public start({ fieldFormats, uiSettings }: AggsStartDependencies): AggsStart { + public start({ fieldFormats, uiSettings, indexPatterns }: AggsStartDependencies): AggsStart { return { asScopedToClient: async (savedObjectsClient: SavedObjectsClientContract) => { const uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient); @@ -72,8 +74,18 @@ export class AggsService { const getConfig = (key: string): T => { return uiSettingsCache[key]; }; + const isDefaultTimezone = () => getConfig('dateFormat:tz') === 'Browser'; - const { calculateAutoTimeExpression, types } = this.aggsCommonService.start({ getConfig }); + const { + calculateAutoTimeExpression, + getDateMetaByDatatableColumn, + types, + } = this.aggsCommonService.start({ + getConfig, + getIndexPattern: (await indexPatterns.indexPatternsServiceFactory(savedObjectsClient)) + .get, + isDefaultTimezone, + }); const aggTypesDependencies: AggTypesDependencies = { calculateBounds: this.calculateBounds, @@ -87,7 +99,7 @@ export class AggsService { * default timezone, but `isDefault` is not currently offered on the * server, so we need to manually check for the default value. */ - isDefaultTimezone: () => getConfig('dateFormat:tz') === 'Browser', + isDefaultTimezone, }; const typesRegistry = { @@ -109,6 +121,7 @@ export class AggsService { return { calculateAutoTimeExpression, + getDateMetaByDatatableColumn, createAggConfigs: (indexPattern, configStates = [], schemas) => { return new AggConfigs(indexPattern, configStates, { typesRegistry }); }, diff --git a/src/plugins/data/server/search/aggs/mocks.ts b/src/plugins/data/server/search/aggs/mocks.ts index b50e22fe87b7c..be060de73b9ff 100644 --- a/src/plugins/data/server/search/aggs/mocks.ts +++ b/src/plugins/data/server/search/aggs/mocks.ts @@ -68,6 +68,7 @@ export const searchAggsSetupMock = (): AggsSetup => ({ const commonStartMock = (): AggsCommonStart => ({ calculateAutoTimeExpression: getCalculateAutoTimeExpression(getConfig), + getDateMetaByDatatableColumn: jest.fn(), createAggConfigs: jest.fn().mockImplementation((indexPattern, configStates = [], schemas) => { return new AggConfigs(indexPattern, configStates, { typesRegistry: mockAggTypesRegistry(), diff --git a/src/plugins/data/server/search/search_service.ts b/src/plugins/data/server/search/search_service.ts index 0130d3aacc91f..04ee0e95c7f08 100644 --- a/src/plugins/data/server/search/search_service.ts +++ b/src/plugins/data/server/search/search_service.ts @@ -149,7 +149,7 @@ export class SearchService implements Plugin { { fieldFormats, indexPatterns }: SearchServiceStartDependencies ): ISearchStart { return { - aggs: this.aggsService.start({ fieldFormats, uiSettings }), + aggs: this.aggsService.start({ fieldFormats, uiSettings, indexPatterns }), getSearchStrategy: this.getSearchStrategy, search: this.search.bind(this), searchSource: { diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index e5882a6cff809..a3edbbd3844b3 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -13,6 +13,7 @@ import { CoreSetup } from 'src/core/server'; import { CoreSetup as CoreSetup_2 } from 'kibana/server'; import { CoreStart } from 'src/core/server'; import { CoreStart as CoreStart_2 } from 'kibana/server'; +import { DatatableColumn } from 'src/plugins/expressions'; import { Duration } from 'moment'; import { ElasticsearchClient } from 'kibana/server'; import { Ensure } from '@kbn/utility-types'; diff --git a/src/plugins/embeddable/public/public.api.md b/src/plugins/embeddable/public/public.api.md index 9939ba2a0f8a1..00971ed37db3a 100644 --- a/src/plugins/embeddable/public/public.api.md +++ b/src/plugins/embeddable/public/public.api.md @@ -17,6 +17,7 @@ import { CoreSetup as CoreSetup_2 } from 'src/core/public'; import { CoreSetup as CoreSetup_3 } from 'kibana/public'; import { CoreStart as CoreStart_2 } from 'kibana/public'; import * as CSS from 'csstype'; +import { DatatableColumn as DatatableColumn_2 } from 'src/plugins/expressions'; import { EmbeddableStart as EmbeddableStart_2 } from 'src/plugins/embeddable/public/plugin'; import { Ensure } from '@kbn/utility-types'; import { EnvironmentMode } from '@kbn/config'; diff --git a/test/interpreter_functional/snapshots/baseline/combined_test2.json b/test/interpreter_functional/snapshots/baseline/combined_test2.json index 550b3b5df12be..4870694e6adbc 100644 --- a/test/interpreter_functional/snapshots/baseline/combined_test2.json +++ b/test/interpreter_functional/snapshots/baseline/combined_test2.json @@ -1 +1 @@ -{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"} \ No newline at end of file +{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/combined_test3.json b/test/interpreter_functional/snapshots/baseline/combined_test3.json index 59de1f285799b..2aa601a8d3631 100644 --- a/test/interpreter_functional/snapshots/baseline/combined_test3.json +++ b/test/interpreter_functional/snapshots/baseline/combined_test3.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/final_output_test.json b/test/interpreter_functional/snapshots/baseline/final_output_test.json index 59de1f285799b..2aa601a8d3631 100644 --- a/test/interpreter_functional/snapshots/baseline/final_output_test.json +++ b/test/interpreter_functional/snapshots/baseline/final_output_test.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/metric_all_data.json b/test/interpreter_functional/snapshots/baseline/metric_all_data.json index cf488ac7f3ffa..dd779800cd452 100644 --- a/test/interpreter_functional/snapshots/baseline/metric_all_data.json +++ b/test/interpreter_functional/snapshots/baseline/metric_all_data.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":2,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":2,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/metric_multi_metric_data.json b/test/interpreter_functional/snapshots/baseline/metric_multi_metric_data.json index 8c272901c4e84..992d667fdce9f 100644 --- a/test/interpreter_functional/snapshots/baseline/metric_multi_metric_data.json +++ b/test/interpreter_functional/snapshots/baseline/metric_multi_metric_data.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/metric_percentage_mode.json b/test/interpreter_functional/snapshots/baseline/metric_percentage_mode.json index abc0d3a446987..031c9f9ea5504 100644 --- a/test/interpreter_functional/snapshots/baseline/metric_percentage_mode.json +++ b/test/interpreter_functional/snapshots/baseline/metric_percentage_mode.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":1000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":true,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":1000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":true,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/metric_single_metric_data.json b/test/interpreter_functional/snapshots/baseline/metric_single_metric_data.json index 1809df5e709f0..8c6fde201c8f1 100644 --- a/test/interpreter_functional/snapshots/baseline/metric_single_metric_data.json +++ b/test/interpreter_functional/snapshots/baseline/metric_single_metric_data.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/partial_test_1.json b/test/interpreter_functional/snapshots/baseline/partial_test_1.json index ec32b07ed9f2e..14c8428c6d432 100644 --- a/test/interpreter_functional/snapshots/baseline/partial_test_1.json +++ b/test/interpreter_functional/snapshots/baseline/partial_test_1.json @@ -1 +1 @@ -{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":72,"metric":{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file +{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":72,"metric":{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/partial_test_2.json b/test/interpreter_functional/snapshots/baseline/partial_test_2.json index 59de1f285799b..2aa601a8d3631 100644 --- a/test/interpreter_functional/snapshots/baseline/partial_test_2.json +++ b/test/interpreter_functional/snapshots/baseline/partial_test_2.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/partial_test_3.json b/test/interpreter_functional/snapshots/baseline/partial_test_3.json index 09602eca4abf2..595127526156e 100644 --- a/test/interpreter_functional/snapshots/baseline/partial_test_3.json +++ b/test/interpreter_functional/snapshots/baseline/partial_test_3.json @@ -1 +1 @@ -{"as":"visualization","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"bucket":{"accessor":0},"metric":{"accessor":1,"format":{"id":"number"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"region_map"}} \ No newline at end of file +{"as":"visualization","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"bucket":{"accessor":0},"metric":{"accessor":1,"format":{"id":"number"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"region_map"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/step_output_test2.json b/test/interpreter_functional/snapshots/baseline/step_output_test2.json index 550b3b5df12be..4870694e6adbc 100644 --- a/test/interpreter_functional/snapshots/baseline/step_output_test2.json +++ b/test/interpreter_functional/snapshots/baseline/step_output_test2.json @@ -1 +1 @@ -{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"} \ No newline at end of file +{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/step_output_test3.json b/test/interpreter_functional/snapshots/baseline/step_output_test3.json index 59de1f285799b..2aa601a8d3631 100644 --- a/test/interpreter_functional/snapshots/baseline/step_output_test3.json +++ b/test/interpreter_functional/snapshots/baseline/step_output_test3.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/tagcloud_all_data.json b/test/interpreter_functional/snapshots/baseline/tagcloud_all_data.json index 071172c698ad7..073fca760b9a2 100644 --- a/test/interpreter_functional/snapshots/baseline/tagcloud_all_data.json +++ b/test/interpreter_functional/snapshots/baseline/tagcloud_all_data.json @@ -1 +1 @@ -{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":72,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file +{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":72,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/tagcloud_fontsize.json b/test/interpreter_functional/snapshots/baseline/tagcloud_fontsize.json index ad38bb28b3329..93f8d8a27d233 100644 --- a/test/interpreter_functional/snapshots/baseline/tagcloud_fontsize.json +++ b/test/interpreter_functional/snapshots/baseline/tagcloud_fontsize.json @@ -1 +1 @@ -{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":40,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":20,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file +{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":40,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":20,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/tagcloud_metric_data.json b/test/interpreter_functional/snapshots/baseline/tagcloud_metric_data.json index 997285adfe5f4..e8c47efdbe622 100644 --- a/test/interpreter_functional/snapshots/baseline/tagcloud_metric_data.json +++ b/test/interpreter_functional/snapshots/baseline/tagcloud_metric_data.json @@ -1 +1 @@ -{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"maxFontSize":72,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file +{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"maxFontSize":72,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/baseline/tagcloud_options.json b/test/interpreter_functional/snapshots/baseline/tagcloud_options.json index 10e23d860637c..38683082975f8 100644 --- a/test/interpreter_functional/snapshots/baseline/tagcloud_options.json +++ b/test/interpreter_functional/snapshots/baseline/tagcloud_options.json @@ -1 +1 @@ -{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":72,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"multiple","scale":"log","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file +{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":72,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"multiple","scale":"log","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/combined_test2.json b/test/interpreter_functional/snapshots/session/combined_test2.json index 550b3b5df12be..4870694e6adbc 100644 --- a/test/interpreter_functional/snapshots/session/combined_test2.json +++ b/test/interpreter_functional/snapshots/session/combined_test2.json @@ -1 +1 @@ -{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"} \ No newline at end of file +{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/combined_test3.json b/test/interpreter_functional/snapshots/session/combined_test3.json index 59de1f285799b..2aa601a8d3631 100644 --- a/test/interpreter_functional/snapshots/session/combined_test3.json +++ b/test/interpreter_functional/snapshots/session/combined_test3.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/final_output_test.json b/test/interpreter_functional/snapshots/session/final_output_test.json index 59de1f285799b..2aa601a8d3631 100644 --- a/test/interpreter_functional/snapshots/session/final_output_test.json +++ b/test/interpreter_functional/snapshots/session/final_output_test.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/metric_all_data.json b/test/interpreter_functional/snapshots/session/metric_all_data.json index cf488ac7f3ffa..dd779800cd452 100644 --- a/test/interpreter_functional/snapshots/session/metric_all_data.json +++ b/test/interpreter_functional/snapshots/session/metric_all_data.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":2,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":2,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/metric_multi_metric_data.json b/test/interpreter_functional/snapshots/session/metric_multi_metric_data.json index 8c272901c4e84..992d667fdce9f 100644 --- a/test/interpreter_functional/snapshots/session/metric_multi_metric_data.json +++ b/test/interpreter_functional/snapshots/session/metric_multi_metric_data.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/metric_percentage_mode.json b/test/interpreter_functional/snapshots/session/metric_percentage_mode.json index abc0d3a446987..031c9f9ea5504 100644 --- a/test/interpreter_functional/snapshots/session/metric_percentage_mode.json +++ b/test/interpreter_functional/snapshots/session/metric_percentage_mode.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":1000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":true,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":1000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":true,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/metric_single_metric_data.json b/test/interpreter_functional/snapshots/session/metric_single_metric_data.json index 1809df5e709f0..8c6fde201c8f1 100644 --- a/test/interpreter_functional/snapshots/session/metric_single_metric_data.json +++ b/test/interpreter_functional/snapshots/session/metric_single_metric_data.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"metrics":[{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"},{"id":"col-2-1","meta":{"field":"bytes","index":"logstash-*","params":{"id":"bytes","params":null},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{"field":"bytes"},"schema":"metric","type":"max"},"type":"number"},"name":"Max bytes"}],"rows":[{"col-0-2":"200","col-1-1":12891,"col-2-1":19986},{"col-0-2":"404","col-1-1":696,"col-2-1":19881},{"col-0-2":"503","col-1-1":417,"col-2-1":0}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/partial_test_1.json b/test/interpreter_functional/snapshots/session/partial_test_1.json index ec32b07ed9f2e..14c8428c6d432 100644 --- a/test/interpreter_functional/snapshots/session/partial_test_1.json +++ b/test/interpreter_functional/snapshots/session/partial_test_1.json @@ -1 +1 @@ -{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":72,"metric":{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file +{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":72,"metric":{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/partial_test_2.json b/test/interpreter_functional/snapshots/session/partial_test_2.json index 59de1f285799b..2aa601a8d3631 100644 --- a/test/interpreter_functional/snapshots/session/partial_test_2.json +++ b/test/interpreter_functional/snapshots/session/partial_test_2.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/partial_test_3.json b/test/interpreter_functional/snapshots/session/partial_test_3.json index 09602eca4abf2..595127526156e 100644 --- a/test/interpreter_functional/snapshots/session/partial_test_3.json +++ b/test/interpreter_functional/snapshots/session/partial_test_3.json @@ -1 +1 @@ -{"as":"visualization","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"bucket":{"accessor":0},"metric":{"accessor":1,"format":{"id":"number"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"region_map"}} \ No newline at end of file +{"as":"visualization","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"bucket":{"accessor":0},"metric":{"accessor":1,"format":{"id":"number"}}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"region_map"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/step_output_test2.json b/test/interpreter_functional/snapshots/session/step_output_test2.json index 550b3b5df12be..4870694e6adbc 100644 --- a/test/interpreter_functional/snapshots/session/step_output_test2.json +++ b/test/interpreter_functional/snapshots/session/step_output_test2.json @@ -1 +1 @@ -{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"} \ No newline at end of file +{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/step_output_test3.json b/test/interpreter_functional/snapshots/session/step_output_test3.json index 59de1f285799b..2aa601a8d3631 100644 --- a/test/interpreter_functional/snapshots/session/step_output_test3.json +++ b/test/interpreter_functional/snapshots/session/step_output_test3.json @@ -1 +1 @@ -{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file +{"as":"metric_vis","type":"render","value":{"params":{"listenOnChange":true},"visConfig":{"dimensions":{"bucket":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"metrics":[{"accessor":1,"format":{"id":"number","params":{}},"type":"vis_dimension"}]},"metric":{"colorSchema":"Green to Red","colorsRange":[{"from":0,"to":10000,"type":"range"}],"invertColors":false,"labels":{"show":true},"metricColorMode":"None","percentageMode":false,"style":{"bgColor":false,"bgFill":"#000","fontSize":60,"labelColor":false,"subText":""},"useRanges":false}},"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visType":"metric"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/tagcloud_all_data.json b/test/interpreter_functional/snapshots/session/tagcloud_all_data.json index 071172c698ad7..073fca760b9a2 100644 --- a/test/interpreter_functional/snapshots/session/tagcloud_all_data.json +++ b/test/interpreter_functional/snapshots/session/tagcloud_all_data.json @@ -1 +1 @@ -{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":72,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file +{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":72,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/tagcloud_fontsize.json b/test/interpreter_functional/snapshots/session/tagcloud_fontsize.json index ad38bb28b3329..93f8d8a27d233 100644 --- a/test/interpreter_functional/snapshots/session/tagcloud_fontsize.json +++ b/test/interpreter_functional/snapshots/session/tagcloud_fontsize.json @@ -1 +1 @@ -{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":40,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":20,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file +{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":40,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":20,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/tagcloud_metric_data.json b/test/interpreter_functional/snapshots/session/tagcloud_metric_data.json index 997285adfe5f4..e8c47efdbe622 100644 --- a/test/interpreter_functional/snapshots/session/tagcloud_metric_data.json +++ b/test/interpreter_functional/snapshots/session/tagcloud_metric_data.json @@ -1 +1 @@ -{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"maxFontSize":72,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file +{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"maxFontSize":72,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"single","scale":"linear","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file diff --git a/test/interpreter_functional/snapshots/session/tagcloud_options.json b/test/interpreter_functional/snapshots/session/tagcloud_options.json index 10e23d860637c..38683082975f8 100644 --- a/test/interpreter_functional/snapshots/session/tagcloud_options.json +++ b/test/interpreter_functional/snapshots/session/tagcloud_options.json @@ -1 +1 @@ -{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":72,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"multiple","scale":"log","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file +{"as":"tagloud_vis","type":"render","value":{"visData":{"columns":[{"id":"col-0-2","meta":{"field":"response.raw","index":"logstash-*","params":{"id":"terms","params":{"id":"string","missingBucketLabel":"Missing","otherBucketLabel":"Other"}},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"2","indexPatternId":"logstash-*","params":{"field":"response.raw","missingBucket":false,"missingBucketLabel":"Missing","order":"desc","orderBy":"1","otherBucket":false,"otherBucketLabel":"Other","size":4},"schema":"segment","type":"terms"},"type":"string"},"name":"response.raw: Descending"},{"id":"col-1-1","meta":{"field":null,"index":"logstash-*","params":{"id":"number"},"source":"esaggs","sourceParams":{"appliedTimeRange":null,"enabled":true,"id":"1","indexPatternId":"logstash-*","params":{},"schema":"metric","type":"count"},"type":"number"},"name":"Count"}],"rows":[{"col-0-2":"200","col-1-1":12891},{"col-0-2":"404","col-1-1":696},{"col-0-2":"503","col-1-1":417}],"type":"datatable"},"visParams":{"bucket":{"accessor":1,"format":{"id":"string","params":{}},"type":"vis_dimension"},"maxFontSize":72,"metric":{"accessor":0,"format":{"id":"string","params":{}},"type":"vis_dimension"},"minFontSize":18,"orientation":"multiple","scale":"log","showLabel":true},"visType":"tagcloud"}} \ No newline at end of file From 4434c393350ec41f84dce0d3567f0fd52a1dde79 Mon Sep 17 00:00:00 2001 From: Angela Chuang <6295984+angorayc@users.noreply.github.com> Date: Thu, 29 Oct 2020 16:02:32 +0000 Subject: [PATCH 37/80] fix toast message (#81687) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../detection_engine/rules/api.test.ts | 14 +- .../containers/detection_engine/rules/api.ts | 18 +- .../detection_engine/rules/translations.ts | 16 +- .../rules/use_pre_packaged_rules.test.tsx | 274 +++++++++++++++++- .../rules/use_pre_packaged_rules.tsx | 34 ++- 5 files changed, 338 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.test.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.test.ts index 8076733be2d7d..0b708133d947b 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.test.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.test.ts @@ -411,7 +411,12 @@ describe('Detections Rules API', () => { describe('createPrepackagedRules', () => { beforeEach(() => { fetchMock.mockClear(); - fetchMock.mockResolvedValue('unknown'); + fetchMock.mockResolvedValue({ + rules_installed: 0, + rules_updated: 0, + timelines_installed: 0, + timelines_updated: 0, + }); }); test('check parameter url when creating pre-packaged rules', async () => { @@ -423,7 +428,12 @@ describe('Detections Rules API', () => { }); test('happy path', async () => { const resp = await createPrepackagedRules({ signal: abortCtrl.signal }); - expect(resp).toEqual(true); + expect(resp).toEqual({ + rules_installed: 0, + rules_updated: 0, + timelines_installed: 0, + timelines_updated: 0, + }); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.ts index 23adfe0228333..ce1fdd18dbdef 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.ts @@ -245,13 +245,25 @@ export const duplicateRules = async ({ rules }: DuplicateRulesProps): Promise => { - await KibanaServices.get().http.fetch(DETECTION_ENGINE_PREPACKAGED_URL, { +export const createPrepackagedRules = async ({ + signal, +}: BasicFetchProps): Promise<{ + rules_installed: number; + rules_updated: number; + timelines_installed: number; + timelines_updated: number; +}> => { + const result = await KibanaServices.get().http.fetch<{ + rules_installed: number; + rules_updated: number; + timelines_installed: number; + timelines_updated: number; + }>(DETECTION_ENGINE_PREPACKAGED_URL, { method: 'PUT', signal, }); - return true; + return result; }; /** diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/translations.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/translations.ts index 721790a36b27f..6e2aee9658658 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/translations.ts @@ -30,7 +30,21 @@ export const RULE_AND_TIMELINE_PREPACKAGED_FAILURE = i18n.translate( export const RULE_AND_TIMELINE_PREPACKAGED_SUCCESS = i18n.translate( 'xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleAndTimelineSuccesDescription', { - defaultMessage: 'Installed pre-packaged rules and timelines from elastic', + defaultMessage: 'Installed pre-packaged rules and timeline templates from elastic', + } +); + +export const RULE_PREPACKAGED_SUCCESS = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleSuccesDescription', + { + defaultMessage: 'Installed pre-packaged rules from elastic', + } +); + +export const TIMELINE_PREPACKAGED_SUCCESS = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.createPrePackagedTimelineSuccesDescription', + { + defaultMessage: 'Installed pre-packaged timeline templates from elastic', } ); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx index 7f74e92584494..f6bd8c4359d6e 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx @@ -3,12 +3,17 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import { ReactElement } from 'react'; import { renderHook, act } from '@testing-library/react-hooks'; import { ReturnPrePackagedRulesAndTimelines, usePrePackagedRules } from './use_pre_packaged_rules'; import * as api from './api'; +import { shallow } from 'enzyme'; +import * as i18n from './translations'; -jest.mock('./api'); +jest.mock('./api', () => ({ + getPrePackagedRulesStatus: jest.fn(), + createPrepackagedRules: jest.fn(), +})); describe('usePrePackagedRules', () => { beforeEach(() => { @@ -52,6 +57,21 @@ describe('usePrePackagedRules', () => { }); test('fetch getPrePackagedRulesStatus', async () => { + (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ + rules_custom_installed: 33, + rules_installed: 12, + rules_not_installed: 0, + rules_not_updated: 0, + timelines_installed: 0, + timelines_not_installed: 0, + timelines_not_updated: 0, + }); + (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ + rules_installed: 0, + rules_updated: 0, + timelines_installed: 0, + timelines_updated: 0, + }); await act(async () => { const { result, waitForNextUpdate } = renderHook( () => @@ -87,7 +107,6 @@ describe('usePrePackagedRules', () => { }); test('happy path to createPrePackagedRules', async () => { - const spyOnCreatePrepackagedRules = jest.spyOn(api, 'createPrepackagedRules'); await act(async () => { const { result, waitForNextUpdate } = renderHook( () => @@ -106,7 +125,7 @@ describe('usePrePackagedRules', () => { resp = await result.current.createPrePackagedRules(); } expect(resp).toEqual(true); - expect(spyOnCreatePrepackagedRules).toHaveBeenCalled(); + expect(api.createPrepackagedRules).toHaveBeenCalled(); expect(result.current).toEqual({ getLoadPrebuiltRulesAndTemplatesButton: result.current.getLoadPrebuiltRulesAndTemplatesButton, @@ -127,6 +146,253 @@ describe('usePrePackagedRules', () => { }); }); + test('getLoadPrebuiltRulesAndTemplatesButton - LOAD_PREPACKAGED_RULES', async () => { + (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ + rules_custom_installed: 0, + rules_installed: 0, + rules_not_installed: 1, + rules_not_updated: 0, + timelines_installed: 0, + timelines_not_installed: 0, + timelines_not_updated: 0, + }); + (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ + rules_installed: 0, + rules_updated: 0, + timelines_installed: 0, + timelines_updated: 0, + }); + await act(async () => { + const { result, waitForNextUpdate } = renderHook( + () => + usePrePackagedRules({ + canUserCRUD: true, + hasIndexWrite: true, + isAuthenticated: true, + hasEncryptionKey: true, + isSignalIndexExists: true, + }) + ); + await waitForNextUpdate(); + await waitForNextUpdate(); + + const button = result.current.getLoadPrebuiltRulesAndTemplatesButton({ + isDisabled: false, + onClick: jest.fn(), + 'data-test-subj': 'button', + }); + const wrapper = shallow(button as ReactElement); + expect(wrapper.find('[data-test-subj="button"]').text()).toEqual(i18n.LOAD_PREPACKAGED_RULES); + }); + }); + + test('getLoadPrebuiltRulesAndTemplatesButton - LOAD_PREPACKAGED_TIMELINE_TEMPLATES', async () => { + (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ + rules_custom_installed: 0, + rules_installed: 0, + rules_not_installed: 0, + rules_not_updated: 0, + timelines_installed: 0, + timelines_not_installed: 1, + timelines_not_updated: 0, + }); + (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ + rules_installed: 0, + rules_updated: 0, + timelines_installed: 0, + timelines_updated: 0, + }); + await act(async () => { + const { result, waitForNextUpdate } = renderHook( + () => + usePrePackagedRules({ + canUserCRUD: true, + hasIndexWrite: true, + isAuthenticated: true, + hasEncryptionKey: true, + isSignalIndexExists: true, + }) + ); + await waitForNextUpdate(); + await waitForNextUpdate(); + + const button = result.current.getLoadPrebuiltRulesAndTemplatesButton({ + isDisabled: false, + onClick: jest.fn(), + 'data-test-subj': 'button', + }); + const wrapper = shallow(button as ReactElement); + expect(wrapper.find('[data-test-subj="button"]').text()).toEqual( + i18n.LOAD_PREPACKAGED_TIMELINE_TEMPLATES + ); + }); + }); + + test('getLoadPrebuiltRulesAndTemplatesButton - LOAD_PREPACKAGED_RULES_AND_TEMPLATES', async () => { + (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ + rules_custom_installed: 0, + rules_installed: 0, + rules_not_installed: 1, + rules_not_updated: 0, + timelines_installed: 0, + timelines_not_installed: 1, + timelines_not_updated: 0, + }); + (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ + rules_installed: 0, + rules_updated: 0, + timelines_installed: 0, + timelines_updated: 0, + }); + await act(async () => { + const { result, waitForNextUpdate } = renderHook( + () => + usePrePackagedRules({ + canUserCRUD: true, + hasIndexWrite: true, + isAuthenticated: true, + hasEncryptionKey: true, + isSignalIndexExists: true, + }) + ); + await waitForNextUpdate(); + await waitForNextUpdate(); + + const button = result.current.getLoadPrebuiltRulesAndTemplatesButton({ + isDisabled: false, + onClick: jest.fn(), + 'data-test-subj': 'button', + }); + const wrapper = shallow(button as ReactElement); + expect(wrapper.find('[data-test-subj="button"]').text()).toEqual( + i18n.LOAD_PREPACKAGED_RULES_AND_TEMPLATES + ); + }); + }); + + test('getReloadPrebuiltRulesAndTemplatesButton - missing rules and templates', async () => { + (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ + rules_custom_installed: 0, + rules_installed: 1, + rules_not_installed: 1, + rules_not_updated: 0, + timelines_installed: 0, + timelines_not_installed: 1, + timelines_not_updated: 0, + }); + (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ + rules_installed: 0, + rules_updated: 0, + timelines_installed: 0, + timelines_updated: 0, + }); + await act(async () => { + const { result, waitForNextUpdate } = renderHook( + () => + usePrePackagedRules({ + canUserCRUD: true, + hasIndexWrite: true, + isAuthenticated: true, + hasEncryptionKey: true, + isSignalIndexExists: true, + }) + ); + await waitForNextUpdate(); + await waitForNextUpdate(); + + const button = result.current.getReloadPrebuiltRulesAndTemplatesButton({ + isDisabled: false, + onClick: jest.fn(), + }); + const wrapper = shallow(button as ReactElement); + expect(wrapper.find('[data-test-subj="reloadPrebuiltRulesBtn"]').text()).toEqual( + 'Install 1 Elastic prebuilt rule and 1 Elastic prebuilt timeline ' + ); + }); + }); + + test('getReloadPrebuiltRulesAndTemplatesButton - missing rules', async () => { + (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ + rules_custom_installed: 0, + rules_installed: 1, + rules_not_installed: 1, + rules_not_updated: 0, + timelines_installed: 0, + timelines_not_installed: 0, + timelines_not_updated: 0, + }); + (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ + rules_installed: 0, + rules_updated: 0, + timelines_installed: 0, + timelines_updated: 0, + }); + await act(async () => { + const { result, waitForNextUpdate } = renderHook( + () => + usePrePackagedRules({ + canUserCRUD: true, + hasIndexWrite: true, + isAuthenticated: true, + hasEncryptionKey: true, + isSignalIndexExists: true, + }) + ); + await waitForNextUpdate(); + await waitForNextUpdate(); + + const button = result.current.getReloadPrebuiltRulesAndTemplatesButton({ + isDisabled: false, + onClick: jest.fn(), + }); + const wrapper = shallow(button as ReactElement); + expect(wrapper.find('[data-test-subj="reloadPrebuiltRulesBtn"]').text()).toEqual( + 'Install 1 Elastic prebuilt rule ' + ); + }); + }); + + test('getReloadPrebuiltRulesAndTemplatesButton - missing templates', async () => { + (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ + rules_custom_installed: 0, + rules_installed: 1, + rules_not_installed: 0, + rules_not_updated: 0, + timelines_installed: 1, + timelines_not_installed: 1, + timelines_not_updated: 0, + }); + (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ + rules_installed: 0, + rules_updated: 0, + timelines_installed: 0, + timelines_updated: 0, + }); + await act(async () => { + const { result, waitForNextUpdate } = renderHook( + () => + usePrePackagedRules({ + canUserCRUD: true, + hasIndexWrite: true, + isAuthenticated: true, + hasEncryptionKey: true, + isSignalIndexExists: true, + }) + ); + await waitForNextUpdate(); + await waitForNextUpdate(); + + const button = result.current.getReloadPrebuiltRulesAndTemplatesButton({ + isDisabled: false, + onClick: jest.fn(), + }); + const wrapper = shallow(button as ReactElement); + expect(wrapper.find('[data-test-subj="reloadPrebuiltRulesBtn"]').text()).toEqual( + 'Install 1 Elastic prebuilt timeline ' + ); + }); + }); + test('unhappy path to createPrePackagedRules', async () => { const spyOnCreatePrepackagedRules = jest.spyOn(api, 'createPrepackagedRules'); spyOnCreatePrepackagedRules.mockImplementation(() => { diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.tsx index 4d19f44bcfc84..48530ddeb181e 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.tsx @@ -114,6 +114,27 @@ export const usePrePackagedRules = ({ const [loadingCreatePrePackagedRules, setLoadingCreatePrePackagedRules] = useState(false); const [loading, setLoading] = useState(true); const [, dispatchToaster] = useStateToaster(); + const getSuccessToastMessage = (result: { + rules_installed: number; + rules_updated: number; + timelines_installed: number; + timelines_updated: number; + }) => { + const { + rules_installed: rulesInstalled, + rules_updated: rulesUpdated, + timelines_installed: timelinesInstalled, + timelines_updated: timelinesUpdated, + } = result; + if (rulesInstalled === 0 && (timelinesInstalled > 0 || timelinesUpdated > 0)) { + return i18n.TIMELINE_PREPACKAGED_SUCCESS; + } else if ((rulesInstalled > 0 || rulesUpdated > 0) && timelinesInstalled === 0) { + return i18n.RULE_PREPACKAGED_SUCCESS; + } else { + return i18n.RULE_AND_TIMELINE_PREPACKAGED_SUCCESS; + } + }; + useEffect(() => { let isSubscribed = true; const abortCtrl = new AbortController(); @@ -170,7 +191,7 @@ export const usePrePackagedRules = ({ isSignalIndexExists ) { setLoadingCreatePrePackagedRules(true); - await createPrepackagedRules({ + const result = await createPrepackagedRules({ signal: abortCtrl.signal, }); @@ -209,11 +230,7 @@ export const usePrePackagedRules = ({ timelinesNotInstalled: prePackagedRuleStatusResponse.timelines_not_installed, timelinesNotUpdated: prePackagedRuleStatusResponse.timelines_not_updated, }); - - displaySuccessToast( - i18n.RULE_AND_TIMELINE_PREPACKAGED_SUCCESS, - dispatchToaster - ); + displaySuccessToast(getSuccessToastMessage(result), dispatchToaster); stopTimeOut(); resolve(true); } else { @@ -277,8 +294,9 @@ export const usePrePackagedRules = ({ ); const getLoadPrebuiltRulesAndTemplatesButton = useCallback( ({ isDisabled, onClick, fill, 'data-test-subj': dataTestSubj = 'loadPrebuiltRulesBtn' }) => { - return prePackagedRuleStatus === 'ruleNotInstalled' || - prePackagedTimelineStatus === 'timelinesNotInstalled' ? ( + return (prePackagedRuleStatus === 'ruleNotInstalled' || + prePackagedTimelineStatus === 'timelinesNotInstalled') && + prePackagedRuleStatus !== 'someRuleUninstall' ? ( Date: Thu, 29 Oct 2020 11:23:39 -0500 Subject: [PATCH 38/80] Service overview tab and route (#81972) Placeholder tab and route for service overview page. Fixes #81718. --- .../app/Main/route_config/index.tsx | 14 + .../app/ServiceDetails/ServiceDetailTabs.tsx | 16 +- .../components/app/service_overview/index.tsx | 246 ++++++++++++++++++ .../service_overview.test.tsx | 29 +++ .../Links/apm/service_overview_link.tsx | 23 ++ 5 files changed, 324 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/apm/public/components/app/service_overview/index.tsx create mode 100644 x-pack/plugins/apm/public/components/app/service_overview/service_overview.test.tsx create mode 100644 x-pack/plugins/apm/public/components/shared/Links/apm/service_overview_link.tsx 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 0d61ca8e39845..f96dc14e34264 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 @@ -92,6 +92,12 @@ function ServiceDetailsNodes( return ; } +function ServiceDetailsOverview( + props: RouteComponentProps<{ serviceName: string }> +) { + return ; +} + function ServiceDetailsServiceMap( props: RouteComponentProps<{ serviceName: string }> ) { @@ -215,6 +221,14 @@ export const routes: APMRouteDefinition[] = [ `/services/${props.match.params.serviceName}/transactions` )(props), } as APMRouteDefinition<{ serviceName: string }>, + { + exact: true, + path: '/services/:serviceName/overview', + breadcrumb: i18n.translate('xpack.apm.breadcrumb.overviewTitle', { + defaultMessage: 'Overview', + }), + component: ServiceDetailsOverview, + } as APMRouteDefinition<{ serviceName: string }>, // errors { exact: true, 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 76c8a289b830c..d51e4a2dd3d7c 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx @@ -16,16 +16,24 @@ import { ErrorOverviewLink } from '../../shared/Links/apm/ErrorOverviewLink'; import { MetricOverviewLink } from '../../shared/Links/apm/MetricOverviewLink'; import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink'; import { ServiceNodeOverviewLink } from '../../shared/Links/apm/ServiceNodeOverviewLink'; +import { ServiceOverviewLink } from '../../shared/Links/apm/service_overview_link'; import { TransactionOverviewLink } from '../../shared/Links/apm/TransactionOverviewLink'; import { ErrorGroupOverview } from '../ErrorGroupOverview'; import { ServiceMap } from '../ServiceMap'; import { ServiceMetrics } from '../ServiceMetrics'; import { ServiceNodeOverview } from '../ServiceNodeOverview'; +import { ServiceOverview } from '../service_overview'; import { TransactionOverview } from '../TransactionOverview'; interface Props { serviceName: string; - tab: 'transactions' | 'errors' | 'metrics' | 'nodes' | 'service-map'; + tab: + | 'errors' + | 'metrics' + | 'nodes' + | 'overview' + | 'service-map' + | 'transactions'; } export function ServiceDetailTabs({ serviceName, tab }: Props) { @@ -34,13 +42,13 @@ export function ServiceDetailTabs({ serviceName, tab }: Props) { const overviewTab = { link: ( - + {i18n.translate('xpack.apm.serviceDetails.overviewTabLabel', { defaultMessage: 'Overview', })} - + ), - render: () => <>, + render: () => , name: 'overview', }; diff --git a/x-pack/plugins/apm/public/components/app/service_overview/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/index.tsx new file mode 100644 index 0000000000000..81f23b6427508 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/service_overview/index.tsx @@ -0,0 +1,246 @@ +/* + * 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, EuiPanel, EuiTitle } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import styled from 'styled-components'; +import { useTrackPageview } from '../../../../../observability/public'; +import { ErrorOverviewLink } from '../../shared/Links/apm/ErrorOverviewLink'; +import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink'; +import { TransactionOverviewLink } from '../../shared/Links/apm/TransactionOverviewLink'; + +const rowHeight = 310; +const latencyChartRowHeight = 230; + +const Row = styled(EuiFlexItem)` + height: ${rowHeight}px; +`; + +const LatencyChartRow = styled(EuiFlexItem)` + height: ${latencyChartRowHeight}px; +`; + +const TableLinkFlexItem = styled(EuiFlexItem)` + & > a { + text-align: right; + } +`; + +interface ServiceOverviewProps { + serviceName: string; +} + +export function ServiceOverview({ serviceName }: ServiceOverviewProps) { + useTrackPageview({ app: 'apm', path: 'service_overview' }); + useTrackPageview({ app: 'apm', path: 'service_overview', delay: 15000 }); + + return ( + + + + + Search bar + + + Comparison picker + + + Date picker + + + + + + +

+ {i18n.translate('xpack.apm.serviceOverview.latencyChartTitle', { + defaultMessage: 'Latency', + })} +

+
+
+
+ + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.trafficChartTitle', + { + defaultMessage: 'Traffic', + } + )} +

+
+
+
+ + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.transactionsTableTitle', + { + defaultMessage: 'Transactions', + } + )} +

+
+
+ + + {i18n.translate( + 'xpack.apm.serviceOverview.transactionsTableLinkText', + { + defaultMessage: 'View transactions', + } + )} + + +
+
+
+
+
+ + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.errorRateChartTitle', + { + defaultMessage: 'Error rate', + } + )} +

+
+
+
+ + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.errorsTableTitle', + { + defaultMessage: 'Errors', + } + )} +

+
+
+ + + {i18n.translate( + 'xpack.apm.serviceOverview.errorsTableLinkText', + { + defaultMessage: 'View errors', + } + )} + + +
+
+
+
+
+ + + + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.averageDurationBySpanTypeChartTitle', + { + defaultMessage: 'Average duration by span type', + } + )} +

+
+
+
+
+
+ + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.dependenciesTableTitle', + { + defaultMessage: 'Dependencies', + } + )} +

+
+
+ + + {i18n.translate( + 'xpack.apm.serviceOverview.dependenciesTableLinkText', + { + defaultMessage: 'View service map', + } + )} + + +
+
+
+
+
+ + + + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.instancesLatencyDistributionChartTitle', + { + defaultMessage: 'Instances latency distribution', + } + )} +

+
+
+
+ + + +

+ {i18n.translate( + 'xpack.apm.serviceOverview.instancesTableTitle', + { + defaultMessage: 'Instances', + } + )} +

+
+
+
+
+
+
+ ); +} diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview.test.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview.test.tsx new file mode 100644 index 0000000000000..4e2063930a9c9 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview.test.tsx @@ -0,0 +1,29 @@ +/* + * 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 { render } from '@testing-library/react'; +import React, { ReactNode } from 'react'; +import { MemoryRouter } from 'react-router-dom'; +import { MockApmPluginContextWrapper } from '../../../context/ApmPluginContext/MockApmPluginContext'; +import { ServiceOverview } from './'; + +function Wrapper({ children }: { children?: ReactNode }) { + return ( + + {children} + + ); +} + +describe('ServiceOverview', () => { + it('renders', () => { + expect(() => + render(, { + wrapper: Wrapper, + }) + ).not.toThrowError(); + }); +}); diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/service_overview_link.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/service_overview_link.tsx new file mode 100644 index 0000000000000..5d7859e7362c7 --- /dev/null +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/service_overview_link.tsx @@ -0,0 +1,23 @@ +/* + * 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'; + +interface ServiceOverviewLinkProps extends APMLinkExtendProps { + serviceName: string; +} + +export function ServiceOverviewLink({ + serviceName, + ...rest +}: ServiceOverviewLinkProps) { + return ; +} From 84b23b6d7ca021d2674563d7c6cb2ec6c33d08b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20C=C3=B4t=C3=A9?= Date: Thu, 29 Oct 2020 12:39:20 -0400 Subject: [PATCH 39/80] Move task manager README.md to root of plugin (#82012) * Move task manager README.md to root of plugin * Fix failing test, update task manager plugin description in docs --- docs/developer/plugin-list.asciidoc | 4 ++-- x-pack/plugins/task_manager/{server => }/README.md | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) rename x-pack/plugins/task_manager/{server => }/README.md (99%) diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 8e08c3806446d..914bd8fce6dff 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -488,8 +488,8 @@ the alertTypes by the Stack in the alerting plugin, register associated HTTP routes, etc. -|{kib-repo}blob/{branch}/x-pack/plugins/task_manager[taskManager] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/x-pack/plugins/task_manager/README.md[taskManager] +|The task manager is a generic system for running background tasks. |{kib-repo}blob/{branch}/x-pack/plugins/telemetry_collection_xpack/README.md[telemetryCollectionXpack] diff --git a/x-pack/plugins/task_manager/server/README.md b/x-pack/plugins/task_manager/README.md similarity index 99% rename from x-pack/plugins/task_manager/server/README.md rename to x-pack/plugins/task_manager/README.md index a0b35ad094537..b25d3cc49f980 100644 --- a/x-pack/plugins/task_manager/server/README.md +++ b/x-pack/plugins/task_manager/README.md @@ -1,7 +1,8 @@ # Kibana task manager -The task manager is a generic system for running background tasks. It supports: +The task manager is a generic system for running background tasks. +It supports: - Single-run and recurring tasks - Scheduling tasks to run after a specified datetime - Basic retry logic From 052f8277fea0df42e41cab0dc021b7ef7bddc893 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Thu, 29 Oct 2020 10:56:42 -0700 Subject: [PATCH 40/80] Add READMEs for ES UI plugins (#81973) * Add Search Profiler README. * Add Upgrade Assistant README. * Add name of plugin to Watcher README. * Add Console Extensions README. * Add Grok Debugger README. * Add Painless Lab README. * Add License Management README. * Add Remote Clusters README. * Add Console README. --- docs/developer/plugin-list.asciidoc | 37 +++++++----- src/plugins/console/README.md | 5 ++ x-pack/plugins/console_extensions/README.md | 3 + x-pack/plugins/grokdebugger/README.md | 6 ++ x-pack/plugins/license_management/README.md | 5 ++ x-pack/plugins/painless_lab/README.md | 5 ++ x-pack/plugins/remote_clusters/README.md | 5 ++ x-pack/plugins/searchprofiler/README.md | 8 +++ x-pack/plugins/upgrade_assistant/README.md | 67 +++++++++++++++++++++ x-pack/plugins/watcher/README.md | 4 +- 10 files changed, 127 insertions(+), 18 deletions(-) create mode 100644 src/plugins/console/README.md create mode 100644 x-pack/plugins/console_extensions/README.md create mode 100644 x-pack/plugins/grokdebugger/README.md create mode 100644 x-pack/plugins/license_management/README.md create mode 100644 x-pack/plugins/painless_lab/README.md create mode 100644 x-pack/plugins/remote_clusters/README.md create mode 100644 x-pack/plugins/searchprofiler/README.md create mode 100644 x-pack/plugins/upgrade_assistant/README.md diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 914bd8fce6dff..f30afce3ee02c 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -38,8 +38,8 @@ NOTE: |The Charts plugin is a way to create easier integration of shared colors, themes, types and other utilities across all Kibana charts and visualizations. -|{kib-repo}blob/{branch}/src/plugins/console[console] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/src/plugins/console/README.md[console] +|Console provides the user with tools for storing and executing requests against Elasticsearch. |<> @@ -307,8 +307,8 @@ Failure to have auth enabled in Kibana will make for a broken UI. UI-based error |WARNING: Missing README. -|{kib-repo}blob/{branch}/x-pack/plugins/console_extensions[consoleExtensions] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/x-pack/plugins/console_extensions/README.md[consoleExtensions] +|This plugin provides autocomplete definitions of licensed APIs to the OSS Console plugin. |{kib-repo}blob/{branch}/x-pack/plugins/cross_cluster_replication/README.md[crossClusterReplication] @@ -376,8 +376,9 @@ or dashboards from the Kibana instance, from both server and client-side plugins |This is the main source folder of the Graph plugin. It contains all of the Kibana server and client source code. x-pack/test/functional/apps/graph contains additional functional tests. -|{kib-repo}blob/{branch}/x-pack/plugins/grokdebugger[grokdebugger] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/x-pack/plugins/grokdebugger/README.md[grokdebugger] +|This plugin helps users define Grok patterns, +which are particularly useful for ingesting logs. |{kib-repo}blob/{branch}/x-pack/plugins/index_lifecycle_management/README.md[indexLifecycleManagement] @@ -406,8 +407,8 @@ the infrastructure monitoring use-case within Kibana. |Run all tests from the x-pack root directory -|{kib-repo}blob/{branch}/x-pack/plugins/license_management[licenseManagement] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/x-pack/plugins/license_management/README.md[licenseManagement] +|This plugin enables users to activate a trial license, downgrade to Basic, and upload a new license. |{kib-repo}blob/{branch}/x-pack/plugins/licensing/README.md[licensing] @@ -444,12 +445,12 @@ Elastic. |This plugin provides shared components and services for use across observability solutions, as well as the observability landing page UI. -|{kib-repo}blob/{branch}/x-pack/plugins/painless_lab[painlessLab] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/x-pack/plugins/painless_lab/README.md[painlessLab] +|This plugin helps users learn how to use the Painless scripting language. -|{kib-repo}blob/{branch}/x-pack/plugins/remote_clusters[remoteClusters] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/x-pack/plugins/remote_clusters/README.md[remoteClusters] +|This plugin helps users manage their remote clusters, which enable cross-cluster search and cross-cluster replication. |{kib-repo}blob/{branch}/x-pack/plugins/reporting/README.md[reporting] @@ -460,8 +461,11 @@ Elastic. |Welcome to the Kibana rollup plugin! This plugin provides Kibana support for Elasticsearch's rollup feature. Please refer to the Elasticsearch documentation to understand rollup indices and how to create rollup jobs. -|{kib-repo}blob/{branch}/x-pack/plugins/searchprofiler[searchprofiler] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/x-pack/plugins/searchprofiler/README.md[searchprofiler] +|The search profiler consumes the Profile API +by sending a search API with profile: true enabled in the request body. The response contains +detailed information on how Elasticsearch executed the search request. People use this information +to understand why a search request might be slow. |{kib-repo}blob/{branch}/x-pack/plugins/security/README.md[security] @@ -513,8 +517,9 @@ As a developer you can reuse and extend built-in alerts and actions UI functiona |Registers commercially licensed generic actions like per panel time range and contains some code that supports drilldown work. -|{kib-repo}blob/{branch}/x-pack/plugins/upgrade_assistant[upgradeAssistant] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/x-pack/plugins/upgrade_assistant/README.md[upgradeAssistant] +|Upgrade Assistant helps users prepare their Stack for being upgraded to the next major. Its primary +purposes are to: |{kib-repo}blob/{branch}/x-pack/plugins/uptime/README.md[uptime] diff --git a/src/plugins/console/README.md b/src/plugins/console/README.md new file mode 100644 index 0000000000000..07421151f8087 --- /dev/null +++ b/src/plugins/console/README.md @@ -0,0 +1,5 @@ +# Console + +## About + +Console provides the user with tools for storing and executing requests against Elasticsearch. \ No newline at end of file diff --git a/x-pack/plugins/console_extensions/README.md b/x-pack/plugins/console_extensions/README.md new file mode 100644 index 0000000000000..49d83d2888d6b --- /dev/null +++ b/x-pack/plugins/console_extensions/README.md @@ -0,0 +1,3 @@ +# Console extensions + +This plugin provides autocomplete definitions of licensed APIs to the OSS Console plugin. \ No newline at end of file diff --git a/x-pack/plugins/grokdebugger/README.md b/x-pack/plugins/grokdebugger/README.md new file mode 100644 index 0000000000000..80729b35500b6 --- /dev/null +++ b/x-pack/plugins/grokdebugger/README.md @@ -0,0 +1,6 @@ +# Grok Debugger + +## About + +This plugin helps users define [Grok patterns](https://www.elastic.co/guide/en/elasticsearch/reference/current/grok-processor.html), +which are particularly useful for ingesting logs. \ No newline at end of file diff --git a/x-pack/plugins/license_management/README.md b/x-pack/plugins/license_management/README.md new file mode 100644 index 0000000000000..b103c8fcd6721 --- /dev/null +++ b/x-pack/plugins/license_management/README.md @@ -0,0 +1,5 @@ +# License Management + +## About + +This plugin enables users to activate a trial license, downgrade to Basic, and upload a new license. \ No newline at end of file diff --git a/x-pack/plugins/painless_lab/README.md b/x-pack/plugins/painless_lab/README.md new file mode 100644 index 0000000000000..519b6a9dea8ed --- /dev/null +++ b/x-pack/plugins/painless_lab/README.md @@ -0,0 +1,5 @@ +# Painless Lab + +## About + +This plugin helps users learn how to use the [Painless scripting language](https://www.elastic.co/guide/en/elasticsearch/reference/master/modules-scripting-painless.html). \ No newline at end of file diff --git a/x-pack/plugins/remote_clusters/README.md b/x-pack/plugins/remote_clusters/README.md new file mode 100644 index 0000000000000..1119c98ffe84a --- /dev/null +++ b/x-pack/plugins/remote_clusters/README.md @@ -0,0 +1,5 @@ +# Remote Clusters + +## About + +This plugin helps users manage their [remote clusters](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-remote-clusters.html), which enable cross-cluster search and cross-cluster replication. \ No newline at end of file diff --git a/x-pack/plugins/searchprofiler/README.md b/x-pack/plugins/searchprofiler/README.md new file mode 100644 index 0000000000000..6e25163470488 --- /dev/null +++ b/x-pack/plugins/searchprofiler/README.md @@ -0,0 +1,8 @@ +# Search Profiler + +## About + +The search profiler consumes the [Profile API](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-profile.html) +by sending a `search` API with `profile: true` enabled in the request body. The response contains +detailed information on how Elasticsearch executed the search request. People use this information +to understand why a search request might be slow. \ No newline at end of file diff --git a/x-pack/plugins/upgrade_assistant/README.md b/x-pack/plugins/upgrade_assistant/README.md new file mode 100644 index 0000000000000..a6cb3b431c82b --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/README.md @@ -0,0 +1,67 @@ +# Upgrade Assistant + +## About + +Upgrade Assistant helps users prepare their Stack for being upgraded to the next major. Its primary +purposes are to: + +* **Surface deprecations.** Deprecations are features that are currently being used that will be +removed in the next major. Surfacing tells the user that there's a problem preventing them +from upgrading. +* **Migrate from deprecation features to supported features.** This addresses the problem, clearing +the path for the upgrade. Generally speaking, once all deprecations are addressed, the user can +safely upgrade. + +### Deprecations + +There are two sources of deprecation information: + +* [**Deprecation Info API.**](https://www.elastic.co/guide/en/elasticsearch/reference/master/migration-api-deprecation.html) +This is information about cluster, node, and index level settings that use deprecated features that +will be removed or changed in the next major version. Currently, only cluster and index deprecations +will be surfaced in the Upgrade Assistant. ES server engineers are responsible for adding +deprecations to the Deprecation Info API. +* [**Deprecation logs.**](https://www.elastic.co/guide/en/elasticsearch/reference/current/logging.html#deprecation-logging) +These surface runtime deprecations, e.g. a Painless script that uses a deprecated accessor or a +request to a deprecated API. These are also generally surfaced as deprecation headers within the +response. Even if the cluster state is good, app maintainers need to watch the logs in case +deprecations are discovered as data is migrated. + +### Fixing problems + +Problems can be fixed at various points in the upgrade process. The Upgrade Assistant supports +various upgrade paths and surfaces various types of upgrade-related issues. + +* **Fixing deprecated cluster settings pre-upgrade.** This generally requires fixing some settings +in `elasticsearch.yml`. +* **Migrating indices data pre-upgrade.** This can involve deleting indices so that ES can rebuild +them in the new version, reindexing them so that they're built using a new Lucene version, or +applying a migration script that reindexes them with new settings/mappings/etc. +* **Migrating indices data post-upgrade.** As was the case with APM in the 6.8->7.x upgrade, +sometimes the new data format isn't forwards-compatible. In these cases, the user will perform the +upgrade first and then use the Upgrade Assistant to reindex their data to be compatible with the new +version. + +Deprecations can be handled in a number of ways: + +* **Reindexing.** When a user's index contains deprecations (e.g. mappings) a reindex solves them. +Upgrade Assistant contains migration scripts that are executed as part of the reindex process. +The user will see a "Reindex" button they can click which will apply this script and perform the +reindex. + * Reindexing is an atomic process in Upgrade Assistant, so that ingestion is never disrupted. + It works like this: + * Create a new index with a "reindexed-" prefix ([#30114](https://github.com/elastic/kibana/pull/30114)). + * Create an index alias pointing from the original index name to the prefixed index name. + * Reindex from the original index into the prefixed index. + * Delete the old index and rename the prefixed index. + * Some apps might require custom scripts, as was the case with APM ([#29845](https://github.com/elastic/kibana/pull/29845)). + In that case the migration performed a reindex with a Painless script (covered by automated tests) + that made the required changes to the data. +* **Update index settings.** Some index settings will need to be updated, which doesn't require a +reindex. An example of this is the "Fix" button that was added for metricbeat and filebeat indices +([#32829](https://github.com/elastic/kibana/pull/32829), [#33439](https://github.com/elastic/kibana/pull/33439)). +* **Following the docs.** The Deprecation Info API provides links to the deprecation docs. Users +will follow these docs to address the problem and make these warnings or errors disappear in the +Upgrade Assistant. +* **Stopping/restarting tasks and jobs.** Users had to stop watches and ML jobs and restart them as +soon as reindexing was complete ([#29663](https://github.com/elastic/kibana/pull/29663)). \ No newline at end of file diff --git a/x-pack/plugins/watcher/README.md b/x-pack/plugins/watcher/README.md index 4f9111760a0a6..c849a65019174 100644 --- a/x-pack/plugins/watcher/README.md +++ b/x-pack/plugins/watcher/README.md @@ -1,4 +1,4 @@ -# Conventions +# Watcher This plugins adopts some conventions in addition to or in place of conventions in Kibana (at the time of the plugin's creation): @@ -69,4 +69,4 @@ encapsulating operations around such relationships — for example, updating the ### Kibana client code This layer deals almost exclusively with data in the form of client models. The one exception to this rule is when the client code needs -to bootstrap a model instance from a bare JS object — for example, creating a new `Watch` model from the contents of the Add/Edit Watch Form. +to bootstrap a model instance from a bare JS object — for example, creating a new `Watch` model from the contents of the Add/Edit Watch Form. \ No newline at end of file From d84ac13a4abd5de1f97aede2843b7c62745d191b Mon Sep 17 00:00:00 2001 From: Jason Rhodes Date: Thu, 29 Oct 2020 14:04:37 -0400 Subject: [PATCH 41/80] [Logs App] Fix logs permissions for alert management (#81199) * Mimics metrics permissions for alert mgmt in logs feature * Updates logs security functional tests Alert management permissions were added for read and all logs users in this PR, so both of these users now have "Stack Management" appear in the nav. Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/infra/server/features.ts | 9 +++++++++ .../apps/infra/feature_controls/logs_security.ts | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/infra/server/features.ts b/x-pack/plugins/infra/server/features.ts index d49755b6f68c1..c768cae247a99 100644 --- a/x-pack/plugins/infra/server/features.ts +++ b/x-pack/plugins/infra/server/features.ts @@ -68,6 +68,9 @@ export const LOGS_FEATURE = { category: DEFAULT_APP_CATEGORIES.observability, app: ['infra', 'logs', 'kibana'], catalogue: ['infralogging', 'logs'], + management: { + insightsAndAlerting: ['triggersActions'], + }, alerting: [LOG_DOCUMENT_COUNT_ALERT_TYPE_ID], privileges: { all: { @@ -81,6 +84,9 @@ export const LOGS_FEATURE = { alerting: { all: [LOG_DOCUMENT_COUNT_ALERT_TYPE_ID], }, + management: { + insightsAndAlerting: ['triggersActions'], + }, ui: ['show', 'configureSource', 'save'], }, read: { @@ -90,6 +96,9 @@ export const LOGS_FEATURE = { alerting: { read: [LOG_DOCUMENT_COUNT_ALERT_TYPE_ID], }, + management: { + insightsAndAlerting: ['triggersActions'], + }, savedObject: { all: [], read: ['infrastructure-ui-source'], diff --git a/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts b/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts index de6353d6b0456..78edbafa4ae47 100644 --- a/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts +++ b/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts @@ -58,7 +58,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows logs navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'Logs']); + expect(navLinks).to.eql(['Overview', 'Logs', 'Stack Management']); }); describe('logs landing page without data', () => { @@ -121,7 +121,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows logs navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'Logs']); + expect(navLinks).to.eql(['Overview', 'Logs', 'Stack Management']); }); describe('logs landing page without data', () => { From ee7ce25048818611416e9cc3a9791aa82d19583c Mon Sep 17 00:00:00 2001 From: Jane Miller <57721870+jmiller263@users.noreply.github.com> Date: Thu, 29 Oct 2020 14:09:01 -0400 Subject: [PATCH 42/80] [SECURITY_SOLUTION] 145: Advanced Policy UI (#80390) * Create Policies for each generated host * Refactor Ingest setup to also setup Fleet * Rename prop name * Add generic response type to KbnClient.request + support for headers * first attempt at adding fleet agent registration * a little closer with fleet integration * SUCCESS. Able to enroll agent and set it to online * update names to be policy * policy generator has advanced types in endpoint confit * linting * flesh out callback * add submit button for verify_peer * add verify hostname field * 145 generalize cb * 145 fix setAgain and getValue * 145 merge conflict * 145 add verify_hostname back, start loop for form * 145 remove OS trick * 145 make AdvancedPolicyForms its own component * 145 grid partially working * 145 back to basics * 145 back to basics * 145 rolled back grid * 145 flex table working * 145 undo accidental change * 145 remove extra schema file * 145 remove unused variable * 145 kevin's PR feedback * 145 fix type check and jest * 145 EuiFlexGroups * 145 use simple EuiFormRow and add show/hide buttons * 145 move all advanced policy code to advanced file; remove unnec test code * 145 fix IDs * 145 take out unnecessary stuff * 145 removed a couple more lines * 145 add some fields back in * 145 add spacer Co-authored-by: Paul Tavares Co-authored-by: Elastic Machine Co-authored-by: kevinlog Co-authored-by: Candace Park --- .../common/endpoint/types/index.ts | 9 +- .../policy/models/advanced_policy_schema.ts | 315 ++++++++++++++++++ .../policy/models/policy_details_config.ts | 41 +-- .../policy/store/policy_details/index.test.ts | 8 +- .../policy/store/policy_details/selectors.ts | 3 + .../management/pages/policy/view/index.ts | 1 + .../pages/policy/view/policy_advanced.tsx | 124 +++++++ .../pages/policy/view/policy_details.tsx | 18 + .../view/policy_forms/protections/malware.tsx | 8 +- 9 files changed, 477 insertions(+), 50 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/models/advanced_policy_schema.ts create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_advanced.tsx diff --git a/x-pack/plugins/security_solution/common/endpoint/types/index.ts b/x-pack/plugins/security_solution/common/endpoint/types/index.ts index 882b3e5182bf3..79157018c315a 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/index.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/index.ts @@ -860,6 +860,7 @@ type KbnConfigSchemaNonOptionalProps> = Pi */ export interface PolicyConfig { windows: { + advanced?: {}; events: { dll_and_driver_load: boolean; dns: boolean; @@ -881,6 +882,7 @@ export interface PolicyConfig { }; }; mac: { + advanced?: {}; events: { file: boolean; process: boolean; @@ -898,6 +900,7 @@ export interface PolicyConfig { }; }; linux: { + advanced?: {}; events: { file: boolean; process: boolean; @@ -916,15 +919,15 @@ export interface UIPolicyConfig { /** * Windows-specific policy configuration that is supported via the UI */ - windows: Pick; + windows: Pick; /** * Mac-specific policy configuration that is supported via the UI */ - mac: Pick; + mac: Pick; /** * Linux-specific policy configuration that is supported via the UI */ - linux: Pick; + linux: Pick; } /** Policy: Malware protection fields */ diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/models/advanced_policy_schema.ts b/x-pack/plugins/security_solution/public/management/pages/policy/models/advanced_policy_schema.ts new file mode 100644 index 0000000000000..d25588dabedc6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/models/advanced_policy_schema.ts @@ -0,0 +1,315 @@ +/* + * 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. + */ + +interface AdvancedPolicySchemaType { + key: string; + first_supported_version: string; + last_supported_version?: string; + documentation: string; +} + +export const AdvancedPolicySchema: AdvancedPolicySchemaType[] = [ + { + key: 'linux.advanced.agent.connection_delay', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'linux.advanced.artifacts.global.base_url', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'linux.advanced.artifacts.global.manifest_relative_url', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'linux.advanced.artifacts.global.ca_cert', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'linux.advanced.artifacts.global.public_key', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'linux.advanced.artifacts.global.interval', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'linux.advanced.artifacts.user.base_url', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'linux.advanced.artifacts.user.ca_cert', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'linux.advanced.artifacts.user.public_key', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'linux.advanced.artifacts.user.interval', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'linux.advanced.elasticsearch.delay', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'linux.advanced.elasticsearch.tls.verify_peer', + first_supported_version: '7.11', + documentation: 'default is true', + }, + { + key: 'linux.advanced.elasticsearch.tls.verify_hostname', + first_supported_version: '7.11', + documentation: 'default is true', + }, + { + key: 'linux.advanced.elasticsearch.tls.ca_cert', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.agent.connection_delay', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.artifacts.global.base_url', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.artifacts.global.manifest_relative_url', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.artifacts.global.ca_cert', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.artifacts.global.public_key', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.artifacts.global.interval', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.artifacts.user.base_url', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.artifacts.user.ca_cert', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.artifacts.user.public_key', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.artifacts.user.interval', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.elasticsearch.delay', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.elasticsearch.tls.verify_peer', + first_supported_version: '7.11', + documentation: 'default is true', + }, + { + key: 'mac.advanced.elasticsearch.tls.verify_hostname', + first_supported_version: '7.11', + documentation: 'default is true', + }, + { + key: 'mac.advanced.elasticsearch.tls.ca_cert', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.malware.quarantine', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.kernel.connect', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.kernel.harden', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.kernel.process', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.kernel.filewrite', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'mac.advanced.kernel.network', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.agent.connection_delay', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.artifacts.global.base_url', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.artifacts.global.manifest_relative_url', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.artifacts.global.ca_cert', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.artifacts.global.public_key', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.artifacts.global.interval', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.artifacts.user.base_url', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.artifacts.user.ca_cert', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.artifacts.user.public_key', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.artifacts.user.interval', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.elasticsearch.delay', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.elasticsearch.tls.verify_peer', + first_supported_version: '7.11', + documentation: 'default is true', + }, + { + key: 'windows.advanced.elasticsearch.tls.verify_hostname', + first_supported_version: '7.11', + documentation: 'default is true', + }, + { + key: 'windows.advanced.elasticsearch.tls.ca_cert', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.malware.quarantine', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.ransomware.mbr', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.ransomware.canary', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.kernel.connect', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.kernel.harden', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.kernel.process', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.kernel.filewrite', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.kernel.network', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.kernel.fileopen', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.kernel.asyncimageload', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.kernel.syncimageload', + first_supported_version: '7.11', + documentation: '', + }, + { + key: 'windows.advanced.kernel.registry', + first_supported_version: '7.11', + documentation: '', + }, +]; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/models/policy_details_config.ts b/x-pack/plugins/security_solution/public/management/pages/policy/models/policy_details_config.ts index 4d32a9fbec694..8d5c19a9e489a 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/models/policy_details_config.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/models/policy_details_config.ts @@ -4,46 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ +import { cloneDeep } from 'lodash'; import { UIPolicyConfig } from '../../../../../common/endpoint/types'; -/** - * A typed Object.entries() function where the keys and values are typed based on the given object - */ -const entries = (o: T): Array<[keyof T, T[keyof T]]> => - Object.entries(o) as Array<[keyof T, T[keyof T]]>; -type DeepPartial = { [K in keyof T]?: DeepPartial }; - -/** - * Returns a deep copy of `UIPolicyConfig` object - */ -export function clone(policyDetailsConfig: UIPolicyConfig): UIPolicyConfig { - const clonedConfig: DeepPartial = {}; - for (const [key, val] of entries(policyDetailsConfig)) { - if (typeof val === 'object') { - const valClone: Partial = {}; - clonedConfig[key] = valClone; - for (const [key2, val2] of entries(val)) { - if (typeof val2 === 'object') { - valClone[key2] = { - ...val2, - }; - } else { - clonedConfig[key] = { - ...val, - }; - } - } - } else { - clonedConfig[key] = val; - } - } - - /** - * clonedConfig is typed as DeepPartial so we can construct the copy from an empty object - */ - return clonedConfig as UIPolicyConfig; -} - /** * Returns value from `configuration` */ @@ -69,7 +32,7 @@ export const setIn = (a: UIPolicyConfig) => (k >( v: V ): UIPolicyConfig => { - const c = clone(a); + const c = cloneDeep(a); c[key][subKey][leafKey] = v; return c; }; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/index.test.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/index.test.ts index b76e0c8acf4c3..89ba05547f447 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/index.test.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/index.test.ts @@ -8,7 +8,6 @@ import { PolicyDetailsState } from '../../types'; import { applyMiddleware, createStore, Dispatch, Store } from 'redux'; import { policyDetailsReducer, PolicyDetailsAction, policyDetailsMiddlewareFactory } from './index'; import { policyConfig } from './selectors'; -import { clone } from '../../models/policy_details_config'; import { factory as policyConfigFactory } from '../../../../../../common/endpoint/models/policy_config'; import { PolicyData } from '../../../../../../common/endpoint/types'; import { @@ -20,6 +19,7 @@ import { createAppRootMockRenderer, } from '../../../../../common/mock/endpoint'; import { HttpFetchOptions } from 'kibana/public'; +import { cloneDeep } from 'lodash'; describe('policy details: ', () => { let store: Store; @@ -93,7 +93,7 @@ describe('policy details: ', () => { throw new Error(); } - const newPayload1 = clone(config); + const newPayload1 = cloneDeep(config); newPayload1.windows.events.process = true; dispatch({ @@ -115,7 +115,7 @@ describe('policy details: ', () => { throw new Error(); } - const newPayload1 = clone(config); + const newPayload1 = cloneDeep(config); newPayload1.mac.events.file = true; dispatch({ @@ -137,7 +137,7 @@ describe('policy details: ', () => { throw new Error(); } - const newPayload1 = clone(config); + const newPayload1 = cloneDeep(config); newPayload1.linux.events.file = true; dispatch({ diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors.ts index 953438526b87e..f275124a73527 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors.ts @@ -103,16 +103,19 @@ export const policyConfig: (s: PolicyDetailsState) => UIPolicyConfig = createSel (windows, mac, linux) => { return { windows: { + advanced: windows.advanced, events: windows.events, malware: windows.malware, popup: windows.popup, }, mac: { + advanced: mac.advanced, events: mac.events, malware: mac.malware, popup: mac.popup, }, linux: { + advanced: linux.advanced, events: linux.events, }, }; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/index.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/index.ts index 9c227ca81a426..ce942205b1620 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/index.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/index.ts @@ -6,3 +6,4 @@ export * from './policy_list'; export * from './policy_details'; +export * from './policy_advanced'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_advanced.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_advanced.tsx new file mode 100644 index 0000000000000..b4b82b7f692b9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_advanced.tsx @@ -0,0 +1,124 @@ +/* + * 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, { useCallback } from 'react'; +import { useDispatch } from 'react-redux'; +import { EuiFieldText, EuiFormRow, EuiPanel, EuiText } from '@elastic/eui'; +import { cloneDeep } from 'lodash'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { policyConfig } from '../store/policy_details/selectors'; +import { usePolicyDetailsSelector } from './policy_hooks'; +import { AdvancedPolicySchema } from '../models/advanced_policy_schema'; + +function setValue(obj: Record, value: string, path: string[]) { + let newPolicyConfig = obj; + for (let i = 0; i < path.length - 1; i++) { + if (!newPolicyConfig[path[i]]) { + newPolicyConfig[path[i]] = {} as Record; + } + newPolicyConfig = newPolicyConfig[path[i]] as Record; + } + newPolicyConfig[path[path.length - 1]] = value; +} + +function getValue(obj: Record, path: string[]) { + let currentPolicyConfig = obj; + + for (let i = 0; i < path.length - 1; i++) { + if (currentPolicyConfig[path[i]]) { + currentPolicyConfig = currentPolicyConfig[path[i]] as Record; + } else { + return undefined; + } + } + return currentPolicyConfig[path[path.length - 1]]; +} + +export const AdvancedPolicyForms = React.memo(() => { + return ( + <> + +

+ +

+
+ + {AdvancedPolicySchema.map((advancedField, index) => { + const configPath = advancedField.key.split('.'); + return ( + + ); + })} + + + ); +}); + +AdvancedPolicyForms.displayName = 'AdvancedPolicyForms'; + +const PolicyAdvanced = React.memo( + ({ + configPath, + firstSupportedVersion, + lastSupportedVersion, + }: { + configPath: string[]; + firstSupportedVersion: string; + lastSupportedVersion?: string; + }) => { + const dispatch = useDispatch(); + const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); + const onChange = useCallback( + (event) => { + if (policyDetailsConfig) { + const newPayload = cloneDeep(policyDetailsConfig); + setValue( + (newPayload as unknown) as Record, + event.target.value, + configPath + ); + dispatch({ + type: 'userChangedPolicyConfig', + payload: { policyConfig: newPayload }, + }); + } + }, + [dispatch, policyDetailsConfig, configPath] + ); + + const value = + policyDetailsConfig && + getValue((policyDetailsConfig as unknown) as Record, configPath); + + return ( + <> + + {lastSupportedVersion + ? `${firstSupportedVersion}-${lastSupportedVersion}` + : `${firstSupportedVersion}+`} + + } + > + + + + ); + } +); + +PolicyAdvanced.displayName = 'PolicyAdvanced'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx index 40c982cfc071b..8fc5de48f36db 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx @@ -47,6 +47,7 @@ import { MANAGEMENT_APP_ID } from '../../../common/constants'; import { PolicyDetailsRouteState } from '../../../../../common/endpoint/types'; import { WrapperPage } from '../../../../common/components/wrapper_page'; import { HeaderPage } from '../../../../common/components/header_page'; +import { AdvancedPolicyForms } from './policy_advanced'; export const PolicyDetails = React.memo(() => { const dispatch = useDispatch<(action: AppAction) => void>(); @@ -69,6 +70,7 @@ export const PolicyDetails = React.memo(() => { // Local state const [showConfirm, setShowConfirm] = useState(false); const [routeState, setRouteState] = useState(); + const [showAdvancedPolicy, setShowAdvancedPolicy] = useState(false); const policyName = policyItem?.name ?? ''; const hostListRouterPath = getEndpointListPath({ name: 'endpointList' }); @@ -128,6 +130,10 @@ export const PolicyDetails = React.memo(() => { setShowConfirm(false); }, []); + const handleAdvancedPolicyClick = useCallback(() => { + setShowAdvancedPolicy(!showAdvancedPolicy); + }, [showAdvancedPolicy]); + useEffect(() => { if (!routeState && locationRouteState) { setRouteState(locationRouteState); @@ -245,6 +251,18 @@ export const PolicyDetails = React.memo(() => { + + + + + + + + {showAdvancedPolicy && } diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx index 6773ed6541927..215851fb28152 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx @@ -19,6 +19,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { cloneDeep } from 'lodash'; import { APP_ID } from '../../../../../../../common/constants'; import { SecurityPageName } from '../../../../../../app/types'; @@ -27,7 +28,6 @@ import { OS, MalwareProtectionOSes } from '../../../types'; import { ConfigForm } from '../config_form'; import { policyConfig } from '../../../store/policy_details/selectors'; import { usePolicyDetailsSelector } from '../../policy_hooks'; -import { clone } from '../../../models/policy_details_config'; import { LinkToApp } from '../../../../../../common/components/endpoint/link_to_app'; import { popupVersionsMap } from './popup_options_to_versions'; @@ -50,7 +50,7 @@ const ProtectionRadio = React.memo(({ id, label }: { id: ProtectionModes; label: const handleRadioChange = useCallback(() => { if (policyDetailsConfig) { - const newPayload = clone(policyDetailsConfig); + const newPayload = cloneDeep(policyDetailsConfig); for (const os of OSes) { newPayload[os][protection].mode = id; if (id === ProtectionModes.prevent) { @@ -141,7 +141,7 @@ export const MalwareProtections = React.memo(() => { const handleSwitchChange = useCallback( (event) => { if (policyDetailsConfig) { - const newPayload = clone(policyDetailsConfig); + const newPayload = cloneDeep(policyDetailsConfig); if (event.target.checked === false) { for (const os of OSes) { newPayload[os][protection].mode = ProtectionModes.off; @@ -165,7 +165,7 @@ export const MalwareProtections = React.memo(() => { const handleUserNotificationCheckbox = useCallback( (event) => { if (policyDetailsConfig) { - const newPayload = clone(policyDetailsConfig); + const newPayload = cloneDeep(policyDetailsConfig); for (const os of OSes) { newPayload[os].popup[protection].enabled = event.target.checked; } From 5752b7a8ddd28d245bd5f2887b1d146fe99936aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Oct 2020 14:21:36 -0400 Subject: [PATCH 43/80] Bump xml-crypto from 1.4.0 to 2.0.0 (#81859) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/package.json b/x-pack/package.json index ec4388c0b8b7d..ba464a21263d7 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -259,7 +259,7 @@ "venn.js": "0.2.20", "vinyl-fs": "^3.0.3", "whatwg-fetch": "^3.0.0", - "xml-crypto": "^1.4.0", + "xml-crypto": "^2.0.0", "yargs": "^15.4.1" }, "dependencies": { diff --git a/yarn.lock b/yarn.lock index b2216537bbd7c..6b77b14f09d42 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29247,10 +29247,10 @@ xhr@^2.0.1: parse-headers "^2.0.0" xtend "^4.0.0" -xml-crypto@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/xml-crypto/-/xml-crypto-1.4.0.tgz#de1cec8cd31cbd689cd90d3d6e8a27d4ae807de7" - integrity sha512-K8FRdRxICVulK4WhiTUcJrRyAIJFPVOqxfurA3x/JlmXBTxy+SkEENF6GeRt7p/rB6WSOUS9g0gXNQw5n+407g== +xml-crypto@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xml-crypto/-/xml-crypto-2.0.0.tgz#54cd268ad9d31930afcf7092cbb664258ca9e826" + integrity sha512-/a04qr7RpONRZHOxROZ6iIHItdsQQjN3sj8lJkYDDss8tAkEaAs0VrFjb3tlhmS5snQru5lTs9/5ISSMdPDHlg== dependencies: xmldom "0.1.27" xpath "0.0.27" From e0b6b0ba5cabe78fb884e629144e4d088bdf92c6 Mon Sep 17 00:00:00 2001 From: Nick Partridge Date: Thu, 29 Oct 2020 13:34:41 -0500 Subject: [PATCH 44/80] Vislib visualization renderer (#80744) --- .../public/components/tag_cloud_chart.tsx | 4 +- .../public/timelion_vis_renderer.tsx | 6 - .../public/__snapshots__/pie_fn.test.ts.snap | 5 +- .../public/__snapshots__/to_ast.test.ts.snap | 22 + .../__snapshots__/to_ast_pie.test.ts.snap | 19 + src/plugins/vis_type_vislib/public/area.ts | 19 +- .../public/components/options/gauge/index.tsx | 4 +- .../components/options/heatmap/index.tsx | 4 +- .../public/components/options/index.tsx | 51 + .../options/metrics_axes/index.test.tsx | 2 +- .../components/options/metrics_axes/index.tsx | 4 +- .../public/components/options/pie.tsx | 4 +- .../components/options/point_series/index.ts | 4 +- src/plugins/vis_type_vislib/public/gauge.ts | 11 +- src/plugins/vis_type_vislib/public/goal.ts | 11 +- src/plugins/vis_type_vislib/public/heatmap.ts | 20 +- .../vis_type_vislib/public/histogram.ts | 19 +- .../vis_type_vislib/public/horizontal_bar.ts | 19 +- src/plugins/vis_type_vislib/public/index.scss | 2 +- src/plugins/vis_type_vislib/public/line.ts | 19 +- src/plugins/vis_type_vislib/public/pie.ts | 16 +- src/plugins/vis_type_vislib/public/pie_fn.ts | 37 +- src/plugins/vis_type_vislib/public/plugin.ts | 73 +- .../public/sample_vis.test.mocks.ts | 3307 +++++++++++++++++ .../vis_type_vislib/public/services.ts | 5 - .../vis_type_vislib/public/to_ast.test.ts | 60 + src/plugins/vis_type_vislib/public/to_ast.ts | 103 + .../options/index.ts => to_ast_esaggs.ts} | 26 +- .../vis_type_vislib/public/to_ast_pie.test.ts | 60 + .../vis_type_vislib/public/to_ast_pie.ts | 50 + src/plugins/vis_type_vislib/public/types.ts | 6 + .../vis_type_vislib/public/vis_controller.tsx | 172 +- .../vis_type_vislib/public/vis_renderer.tsx | 61 + .../public/vis_type_vislib_vis_fn.ts | 42 +- .../public/vis_type_vislib_vis_types.ts | 27 +- .../vis_type_vislib/public/vis_wrapper.tsx | 89 + .../public/vislib/_vislib_vis_type.scss | 14 +- .../vislib/components/legend/_legend.scss | 9 +- .../vislib/components/legend/legend.test.tsx | 36 +- .../vislib/components/legend/legend.tsx | 49 +- .../helpers/point_series/_init_x_axis.ts | 4 +- .../helpers/point_series/point_series.ts | 5 +- .../public/vislib/lib/_handler.scss | 17 - .../public/vislib/lib/_index.scss | 1 - .../public/vislib/lib/dispatch.js | 4 - .../public/vislib/lib/handler.js | 22 +- .../public/vislib/lib/handler.test.js | 2 +- .../public/vislib/lib/vis_config.js | 1 - .../vis_type_vislib/public/vislib/vis.js | 13 +- .../public/vislib/visualizations/_chart.js | 4 +- .../vislib/visualizations/_vis_fixture.js | 17 +- .../vislib/visualizations/gauge_chart.test.js | 4 +- .../public/vislib/visualizations/pie_chart.js | 4 +- .../vislib/visualizations/pie_chart.test.js | 8 +- .../vislib/visualizations/point_series.js | 14 +- .../visualizations/point_series/area_chart.js | 4 +- .../point_series/area_chart.test.js | 4 +- .../point_series/column_chart.js | 4 +- .../point_series/column_chart.test.js | 16 +- .../point_series/heatmap_chart.test.js | 4 +- .../visualizations/point_series/line_chart.js | 4 +- .../point_series/line_chart.test.js | 4 +- .../public/components/_visualization.scss | 4 +- src/plugins/visualizations/public/index.ts | 1 + .../__snapshots__/build_pipeline.test.ts.snap | 2 - .../public/legacy/build_pipeline.test.ts | 164 - .../public/legacy/build_pipeline.ts | 96 - src/plugins/visualizations/public/types.ts | 2 +- .../page_objects/visualize_chart_page.ts | 2 +- 69 files changed, 4235 insertions(+), 687 deletions(-) create mode 100644 src/plugins/vis_type_vislib/public/__snapshots__/to_ast.test.ts.snap create mode 100644 src/plugins/vis_type_vislib/public/__snapshots__/to_ast_pie.test.ts.snap create mode 100644 src/plugins/vis_type_vislib/public/components/options/index.tsx create mode 100644 src/plugins/vis_type_vislib/public/sample_vis.test.mocks.ts create mode 100644 src/plugins/vis_type_vislib/public/to_ast.test.ts create mode 100644 src/plugins/vis_type_vislib/public/to_ast.ts rename src/plugins/vis_type_vislib/public/{components/options/index.ts => to_ast_esaggs.ts} (51%) create mode 100644 src/plugins/vis_type_vislib/public/to_ast_pie.test.ts create mode 100644 src/plugins/vis_type_vislib/public/to_ast_pie.ts create mode 100644 src/plugins/vis_type_vislib/public/vis_renderer.tsx create mode 100644 src/plugins/vis_type_vislib/public/vis_wrapper.tsx delete mode 100644 src/plugins/vis_type_vislib/public/vislib/lib/_handler.scss diff --git a/src/plugins/vis_type_tagcloud/public/components/tag_cloud_chart.tsx b/src/plugins/vis_type_tagcloud/public/components/tag_cloud_chart.tsx index cb0daa6d29382..a14328ac994f0 100644 --- a/src/plugins/vis_type_tagcloud/public/components/tag_cloud_chart.tsx +++ b/src/plugins/vis_type_tagcloud/public/components/tag_cloud_chart.tsx @@ -45,7 +45,9 @@ export const TagCloudChart = ({ const visController = useRef(null); useEffect(() => { - visController.current = new TagCloudVisualization(chartDiv.current, colors, fireEvent); + if (chartDiv.current) { + visController.current = new TagCloudVisualization(chartDiv.current, colors, fireEvent); + } return () => { visController.current.destroy(); visController.current = null; diff --git a/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx b/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx index 04579407105e8..2c914d3c5b662 100644 --- a/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx +++ b/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx @@ -42,12 +42,6 @@ export const getTimelionVisRenderer: ( const [seriesList] = visData.sheet; const showNoResult = !seriesList || !seriesList.list.length; - if (showNoResult) { - // send the render complete event when there is no data to show - // to notify that a chart is updated - handlers.done(); - } - render( diff --git a/src/plugins/vis_type_vislib/public/__snapshots__/pie_fn.test.ts.snap b/src/plugins/vis_type_vislib/public/__snapshots__/pie_fn.test.ts.snap index 2cee55e4751c2..b64366c1ce0f3 100644 --- a/src/plugins/vis_type_vislib/public/__snapshots__/pie_fn.test.ts.snap +++ b/src/plugins/vis_type_vislib/public/__snapshots__/pie_fn.test.ts.snap @@ -2,12 +2,9 @@ exports[`interpreter/functions#pie returns an object with the correct structure 1`] = ` Object { - "as": "visualization", + "as": "vislib_vis", "type": "render", "value": Object { - "params": Object { - "listenOnChange": true, - }, "visConfig": Object { "addLegend": true, "addTooltip": true, diff --git a/src/plugins/vis_type_vislib/public/__snapshots__/to_ast.test.ts.snap b/src/plugins/vis_type_vislib/public/__snapshots__/to_ast.test.ts.snap new file mode 100644 index 0000000000000..c3ffc0dd08412 --- /dev/null +++ b/src/plugins/vis_type_vislib/public/__snapshots__/to_ast.test.ts.snap @@ -0,0 +1,22 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`vislib vis toExpressionAst function should match basic snapshot 1`] = ` +Object { + "addArgument": [Function], + "arguments": Object { + "type": Array [ + "area", + ], + "visConfig": Array [ + "{\\"type\\":\\"area\\",\\"grid\\":{\\"categoryLines\\":false,\\"style\\":{\\"color\\":\\"#eee\\"}},\\"categoryAxes\\":[{\\"id\\":\\"CategoryAxis-1\\",\\"type\\":\\"category\\",\\"position\\":\\"bottom\\",\\"show\\":true,\\"style\\":{},\\"scale\\":{\\"type\\":\\"linear\\"},\\"labels\\":{\\"show\\":true,\\"truncate\\":100},\\"title\\":{}}],\\"valueAxes\\":[{\\"id\\":\\"ValueAxis-1\\",\\"name\\":\\"LeftAxis-1\\",\\"type\\":\\"value\\",\\"position\\":\\"left\\",\\"show\\":true,\\"style\\":{},\\"scale\\":{\\"type\\":\\"linear\\",\\"mode\\":\\"normal\\"},\\"labels\\":{\\"show\\":true,\\"rotate\\":0,\\"filter\\":false,\\"truncate\\":100},\\"title\\":{\\"text\\":\\"Sum of total_quantity\\"}}],\\"seriesParams\\":[{\\"show\\":\\"true\\",\\"type\\":\\"area\\",\\"mode\\":\\"stacked\\",\\"data\\":{\\"label\\":\\"Sum of total_quantity\\",\\"id\\":\\"1\\"},\\"drawLinesBetweenPoints\\":true,\\"showCircles\\":true,\\"interpolate\\":\\"linear\\",\\"valueAxis\\":\\"ValueAxis-1\\"}],\\"addTooltip\\":true,\\"addLegend\\":true,\\"legendPosition\\":\\"top\\",\\"times\\":[],\\"addTimeMarker\\":false,\\"thresholdLine\\":{\\"show\\":false,\\"value\\":10,\\"width\\":1,\\"style\\":\\"full\\",\\"color\\":\\"#E7664C\\"},\\"labels\\":{},\\"dimensions\\":{\\"x\\":{\\"accessor\\":1,\\"format\\":{\\"id\\":\\"date\\",\\"params\\":{\\"pattern\\":\\"HH:mm:ss.SSS\\"}},\\"params\\":{}},\\"y\\":[{\\"accessor\\":0,\\"format\\":{\\"id\\":\\"number\\",\\"params\\":{\\"parsedUrl\\":{\\"origin\\":\\"http://localhost:5801\\",\\"pathname\\":\\"/app/visualize\\",\\"basePath\\":\\"\\"}}},\\"params\\":{}}],\\"series\\":[{\\"accessor\\":2,\\"format\\":{\\"id\\":\\"terms\\",\\"params\\":{\\"id\\":\\"string\\",\\"otherBucketLabel\\":\\"Other\\",\\"missingBucketLabel\\":\\"Missing\\",\\"parsedUrl\\":{\\"origin\\":\\"http://localhost:5801\\",\\"pathname\\":\\"/app/visualize\\",\\"basePath\\":\\"\\"}}},\\"params\\":{}}]}}", + ], + }, + "getArgument": [Function], + "name": "vislib_vis", + "removeArgument": [Function], + "replaceArgument": [Function], + "toAst": [Function], + "toString": [Function], + "type": "expression_function_builder", +} +`; diff --git a/src/plugins/vis_type_vislib/public/__snapshots__/to_ast_pie.test.ts.snap b/src/plugins/vis_type_vislib/public/__snapshots__/to_ast_pie.test.ts.snap new file mode 100644 index 0000000000000..b8dc4b31747c4 --- /dev/null +++ b/src/plugins/vis_type_vislib/public/__snapshots__/to_ast_pie.test.ts.snap @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`vislib pie vis toExpressionAst function should match basic snapshot 1`] = ` +Object { + "addArgument": [Function], + "arguments": Object { + "visConfig": Array [ + "{\\"type\\":\\"pie\\",\\"addTooltip\\":true,\\"addLegend\\":true,\\"legendPosition\\":\\"right\\",\\"isDonut\\":true,\\"labels\\":{\\"show\\":true,\\"values\\":true,\\"last_level\\":true,\\"truncate\\":100},\\"dimensions\\":{\\"metric\\":{\\"accessor\\":0,\\"format\\":{\\"id\\":\\"number\\"},\\"params\\":{}},\\"buckets\\":[{\\"accessor\\":1,\\"format\\":{\\"id\\":\\"terms\\",\\"params\\":{\\"id\\":\\"string\\",\\"otherBucketLabel\\":\\"Other\\",\\"missingBucketLabel\\":\\"Missing\\",\\"parsedUrl\\":{\\"origin\\":\\"http://localhost:5801\\",\\"pathname\\":\\"/app/visualize\\",\\"basePath\\":\\"\\"}}},\\"params\\":{}}]}}", + ], + }, + "getArgument": [Function], + "name": "vislib_pie_vis", + "removeArgument": [Function], + "replaceArgument": [Function], + "toAst": [Function], + "toString": [Function], + "type": "expression_function_builder", +} +`; diff --git a/src/plugins/vis_type_vislib/public/area.ts b/src/plugins/vis_type_vislib/public/area.ts index ec90fbd1746a1..531958d6b3db3 100644 --- a/src/plugins/vis_type_vislib/public/area.ts +++ b/src/plugins/vis_type_vislib/public/area.ts @@ -37,22 +37,20 @@ import { getConfigCollections, } from './utils/collections'; import { getAreaOptionTabs, countLabel } from './utils/common_config'; -import { createVislibVisController } from './vis_controller'; -import { VisTypeVislibDependencies } from './plugin'; import { Rotates } from '../../charts/public'; -import { VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { BaseVisTypeOptions, VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { toExpressionAst } from './to_ast'; +import { BasicVislibParams } from './types'; -export const createAreaVisTypeDefinition = (deps: VisTypeVislibDependencies) => ({ +export const areaVisTypeDefinition: BaseVisTypeOptions = { name: 'area', title: i18n.translate('visTypeVislib.area.areaTitle', { defaultMessage: 'Area' }), icon: 'visArea', description: i18n.translate('visTypeVislib.area.areaDescription', { defaultMessage: 'Emphasize the quantity beneath a line chart', }), - visualization: createVislibVisController(deps), - getSupportedTriggers: () => { - return [VIS_EVENT_TO_TRIGGER.filter, VIS_EVENT_TO_TRIGGER.brush]; - }, + getSupportedTriggers: () => [VIS_EVENT_TO_TRIGGER.filter, VIS_EVENT_TO_TRIGGER.brush], + toExpressionAst, visConfig: { defaults: { type: 'area', @@ -131,9 +129,6 @@ export const createAreaVisTypeDefinition = (deps: VisTypeVislibDependencies) => labels: {}, }, }, - events: { - brush: { disabled: false }, - }, editorConfig: { collections: getConfigCollections(), optionTabs: getAreaOptionTabs(), @@ -190,4 +185,4 @@ export const createAreaVisTypeDefinition = (deps: VisTypeVislibDependencies) => }, ]), }, -}); +}; diff --git a/src/plugins/vis_type_vislib/public/components/options/gauge/index.tsx b/src/plugins/vis_type_vislib/public/components/options/gauge/index.tsx index 6109b548f9412..911ee293f580e 100644 --- a/src/plugins/vis_type_vislib/public/components/options/gauge/index.tsx +++ b/src/plugins/vis_type_vislib/public/components/options/gauge/index.tsx @@ -60,4 +60,6 @@ function GaugeOptions(props: VisOptionsProps) { ); } -export { GaugeOptions }; +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { GaugeOptions as default }; diff --git a/src/plugins/vis_type_vislib/public/components/options/heatmap/index.tsx b/src/plugins/vis_type_vislib/public/components/options/heatmap/index.tsx index 7a89496d9441e..312cf60fda6b0 100644 --- a/src/plugins/vis_type_vislib/public/components/options/heatmap/index.tsx +++ b/src/plugins/vis_type_vislib/public/components/options/heatmap/index.tsx @@ -185,4 +185,6 @@ function HeatmapOptions(props: VisOptionsProps) { ); } -export { HeatmapOptions }; +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { HeatmapOptions as default }; diff --git a/src/plugins/vis_type_vislib/public/components/options/index.tsx b/src/plugins/vis_type_vislib/public/components/options/index.tsx new file mode 100644 index 0000000000000..18c41bf289b11 --- /dev/null +++ b/src/plugins/vis_type_vislib/public/components/options/index.tsx @@ -0,0 +1,51 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { lazy } from 'react'; + +import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; +import { ValidationVisOptionsProps } from '../common'; +import { GaugeVisParams } from '../../gauge'; +import { PieVisParams } from '../../pie'; +import { BasicVislibParams } from '../../types'; +import { HeatmapVisParams } from '../../heatmap'; + +const GaugeOptionsLazy = lazy(() => import('./gauge')); +const PieOptionsLazy = lazy(() => import('./pie')); +const PointSeriesOptionsLazy = lazy(() => import('./point_series')); +const HeatmapOptionsLazy = lazy(() => import('./heatmap')); +const MetricsAxisOptionsLazy = lazy(() => import('./metrics_axes')); + +export const GaugeOptions = (props: VisOptionsProps) => ( + +); + +export const PieOptions = (props: VisOptionsProps) => ; + +export const PointSeriesOptions = (props: ValidationVisOptionsProps) => ( + +); + +export const HeatmapOptions = (props: VisOptionsProps) => ( + +); + +export const MetricsAxisOptions = (props: ValidationVisOptionsProps) => ( + +); diff --git a/src/plugins/vis_type_vislib/public/components/options/metrics_axes/index.test.tsx b/src/plugins/vis_type_vislib/public/components/options/metrics_axes/index.test.tsx index 0cc737f19e5c6..63881fea1ad88 100644 --- a/src/plugins/vis_type_vislib/public/components/options/metrics_axes/index.test.tsx +++ b/src/plugins/vis_type_vislib/public/components/options/metrics_axes/index.test.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { mount, shallow } from 'enzyme'; import { IAggConfig, IAggType } from 'src/plugins/data/public'; -import { MetricsAxisOptions } from './index'; +import MetricsAxisOptions from './index'; import { BasicVislibParams, SeriesParam, ValueAxis } from '../../../types'; import { ValidationVisOptionsProps } from '../../common'; import { Positions } from '../../../utils/collections'; diff --git a/src/plugins/vis_type_vislib/public/components/options/metrics_axes/index.tsx b/src/plugins/vis_type_vislib/public/components/options/metrics_axes/index.tsx index 18687404b9114..0862c47c35cff 100644 --- a/src/plugins/vis_type_vislib/public/components/options/metrics_axes/index.tsx +++ b/src/plugins/vis_type_vislib/public/components/options/metrics_axes/index.tsx @@ -325,4 +325,6 @@ function MetricsAxisOptions(props: ValidationVisOptionsProps) ) : null; } -export { MetricsAxisOptions }; +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { MetricsAxisOptions as default }; diff --git a/src/plugins/vis_type_vislib/public/components/options/pie.tsx b/src/plugins/vis_type_vislib/public/components/options/pie.tsx index 54ba307982967..30828bfc6a3ea 100644 --- a/src/plugins/vis_type_vislib/public/components/options/pie.tsx +++ b/src/plugins/vis_type_vislib/public/components/options/pie.tsx @@ -99,4 +99,6 @@ function PieOptions(props: VisOptionsProps) { ); } -export { PieOptions }; +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { PieOptions as default }; diff --git a/src/plugins/vis_type_vislib/public/components/options/point_series/index.ts b/src/plugins/vis_type_vislib/public/components/options/point_series/index.ts index fb94ec6743faa..937b92c950430 100644 --- a/src/plugins/vis_type_vislib/public/components/options/point_series/index.ts +++ b/src/plugins/vis_type_vislib/public/components/options/point_series/index.ts @@ -17,4 +17,6 @@ * under the License. */ -export { PointSeriesOptions } from './point_series'; +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { PointSeriesOptions as default } from './point_series'; diff --git a/src/plugins/vis_type_vislib/public/gauge.ts b/src/plugins/vis_type_vislib/public/gauge.ts index 561c45d26fa7f..86e3b8793d618 100644 --- a/src/plugins/vis_type_vislib/public/gauge.ts +++ b/src/plugins/vis_type_vislib/public/gauge.ts @@ -24,8 +24,9 @@ import { AggGroupNames } from '../../data/public'; import { GaugeOptions } from './components/options'; import { getGaugeCollections, Alignments, GaugeTypes } from './utils/collections'; import { ColorModes, ColorSchemas, ColorSchemaParams, Labels, Style } from '../../charts/public'; -import { createVislibVisController } from './vis_controller'; -import { VisTypeVislibDependencies } from './plugin'; +import { toExpressionAst } from './to_ast'; +import { BaseVisTypeOptions } from '../../visualizations/public'; +import { BasicVislibParams } from './types'; export interface Gauge extends ColorSchemaParams { backStyle: 'Full'; @@ -55,7 +56,7 @@ export interface GaugeVisParams { gauge: Gauge; } -export const createGaugeVisTypeDefinition = (deps: VisTypeVislibDependencies) => ({ +export const gaugeVisTypeDefinition: BaseVisTypeOptions = { name: 'gauge', title: i18n.translate('visTypeVislib.gauge.gaugeTitle', { defaultMessage: 'Gauge' }), icon: 'visGauge', @@ -63,6 +64,7 @@ export const createGaugeVisTypeDefinition = (deps: VisTypeVislibDependencies) => defaultMessage: "Gauges indicate the status of a metric. Use it to show how a metric's value relates to reference threshold values.", }), + toExpressionAst, visConfig: { defaults: { type: 'gauge', @@ -109,7 +111,6 @@ export const createGaugeVisTypeDefinition = (deps: VisTypeVislibDependencies) => }, }, }, - visualization: createVislibVisController(deps), editorConfig: { collections: getGaugeCollections(), optionsTemplate: GaugeOptions, @@ -145,4 +146,4 @@ export const createGaugeVisTypeDefinition = (deps: VisTypeVislibDependencies) => ]), }, useCustomNoDataScreen: true, -}); +}; diff --git a/src/plugins/vis_type_vislib/public/goal.ts b/src/plugins/vis_type_vislib/public/goal.ts index 5f74698938a0b..32574fb5b0a9c 100644 --- a/src/plugins/vis_type_vislib/public/goal.ts +++ b/src/plugins/vis_type_vislib/public/goal.ts @@ -21,20 +21,21 @@ import { i18n } from '@kbn/i18n'; import { GaugeOptions } from './components/options'; import { getGaugeCollections, GaugeTypes } from './utils/collections'; -import { createVislibVisController } from './vis_controller'; -import { VisTypeVislibDependencies } from './plugin'; import { ColorModes, ColorSchemas } from '../../charts/public'; import { AggGroupNames } from '../../data/public'; import { Schemas } from '../../vis_default_editor/public'; +import { toExpressionAst } from './to_ast'; +import { BaseVisTypeOptions } from '../../visualizations/public'; +import { BasicVislibParams } from './types'; -export const createGoalVisTypeDefinition = (deps: VisTypeVislibDependencies) => ({ +export const goalVisTypeDefinition: BaseVisTypeOptions = { name: 'goal', title: i18n.translate('visTypeVislib.goal.goalTitle', { defaultMessage: 'Goal' }), icon: 'visGoal', description: i18n.translate('visTypeVislib.goal.goalDescription', { defaultMessage: 'A goal chart indicates how close you are to your final goal.', }), - visualization: createVislibVisController(deps), + toExpressionAst, visConfig: { defaults: { addTooltip: true, @@ -110,4 +111,4 @@ export const createGoalVisTypeDefinition = (deps: VisTypeVislibDependencies) => ]), }, useCustomNoDataScreen: true, -}); +}; diff --git a/src/plugins/vis_type_vislib/public/heatmap.ts b/src/plugins/vis_type_vislib/public/heatmap.ts index bd3d02029cb23..f970eddd645f5 100644 --- a/src/plugins/vis_type_vislib/public/heatmap.ts +++ b/src/plugins/vis_type_vislib/public/heatmap.ts @@ -23,12 +23,11 @@ import { RangeValues, Schemas } from '../../vis_default_editor/public'; import { AggGroupNames } from '../../data/public'; import { AxisTypes, getHeatmapCollections, Positions, ScaleTypes } from './utils/collections'; import { HeatmapOptions } from './components/options'; -import { createVislibVisController } from './vis_controller'; import { TimeMarker } from './vislib/visualizations/time_marker'; -import { CommonVislibParams, ValueAxis } from './types'; -import { VisTypeVislibDependencies } from './plugin'; +import { BasicVislibParams, CommonVislibParams, ValueAxis } from './types'; import { ColorSchemas, ColorSchemaParams } from '../../charts/public'; -import { VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { BaseVisTypeOptions, VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { toExpressionAst } from './to_ast'; export interface HeatmapVisParams extends CommonVislibParams, ColorSchemaParams { type: 'heatmap'; @@ -42,17 +41,15 @@ export interface HeatmapVisParams extends CommonVislibParams, ColorSchemaParams times: TimeMarker[]; } -export const createHeatmapVisTypeDefinition = (deps: VisTypeVislibDependencies) => ({ +export const heatmapVisTypeDefinition: BaseVisTypeOptions = { name: 'heatmap', title: i18n.translate('visTypeVislib.heatmap.heatmapTitle', { defaultMessage: 'Heat Map' }), icon: 'heatmap', description: i18n.translate('visTypeVislib.heatmap.heatmapDescription', { defaultMessage: 'Shade cells within a matrix', }), - getSupportedTriggers: () => { - return [VIS_EVENT_TO_TRIGGER.filter]; - }, - visualization: createVislibVisController(deps), + getSupportedTriggers: () => [VIS_EVENT_TO_TRIGGER.filter], + toExpressionAst, visConfig: { defaults: { type: 'heatmap', @@ -86,9 +83,6 @@ export const createHeatmapVisTypeDefinition = (deps: VisTypeVislibDependencies) ], }, }, - events: { - brush: { disabled: false }, - }, editorConfig: { collections: getHeatmapCollections(), optionsTemplate: HeatmapOptions, @@ -142,4 +136,4 @@ export const createHeatmapVisTypeDefinition = (deps: VisTypeVislibDependencies) }, ]), }, -}); +}; diff --git a/src/plugins/vis_type_vislib/public/histogram.ts b/src/plugins/vis_type_vislib/public/histogram.ts index 8aeeb4ec533ab..d5fb92f5c6a0c 100644 --- a/src/plugins/vis_type_vislib/public/histogram.ts +++ b/src/plugins/vis_type_vislib/public/histogram.ts @@ -36,12 +36,12 @@ import { getConfigCollections, } from './utils/collections'; import { getAreaOptionTabs, countLabel } from './utils/common_config'; -import { createVislibVisController } from './vis_controller'; -import { VisTypeVislibDependencies } from './plugin'; import { Rotates } from '../../charts/public'; -import { VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { BaseVisTypeOptions, VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { BasicVislibParams } from './types'; +import { toExpressionAst } from './to_ast'; -export const createHistogramVisTypeDefinition = (deps: VisTypeVislibDependencies) => ({ +export const histogramVisTypeDefinition: BaseVisTypeOptions = { name: 'histogram', title: i18n.translate('visTypeVislib.histogram.histogramTitle', { defaultMessage: 'Vertical Bar', @@ -50,10 +50,8 @@ export const createHistogramVisTypeDefinition = (deps: VisTypeVislibDependencies description: i18n.translate('visTypeVislib.histogram.histogramDescription', { defaultMessage: 'Assign a continuous variable to each axis', }), - visualization: createVislibVisController(deps), - getSupportedTriggers: () => { - return [VIS_EVENT_TO_TRIGGER.filter, VIS_EVENT_TO_TRIGGER.brush]; - }, + getSupportedTriggers: () => [VIS_EVENT_TO_TRIGGER.filter, VIS_EVENT_TO_TRIGGER.brush], + toExpressionAst, visConfig: { defaults: { type: 'histogram', @@ -133,9 +131,6 @@ export const createHistogramVisTypeDefinition = (deps: VisTypeVislibDependencies }, }, }, - events: { - brush: { disabled: false }, - }, editorConfig: { collections: getConfigCollections(), optionTabs: getAreaOptionTabs(), @@ -192,4 +187,4 @@ export const createHistogramVisTypeDefinition = (deps: VisTypeVislibDependencies }, ]), }, -}); +}; diff --git a/src/plugins/vis_type_vislib/public/horizontal_bar.ts b/src/plugins/vis_type_vislib/public/horizontal_bar.ts index 702581828e60d..f1a5365e5ae74 100644 --- a/src/plugins/vis_type_vislib/public/horizontal_bar.ts +++ b/src/plugins/vis_type_vislib/public/horizontal_bar.ts @@ -34,12 +34,12 @@ import { getConfigCollections, } from './utils/collections'; import { getAreaOptionTabs, countLabel } from './utils/common_config'; -import { createVislibVisController } from './vis_controller'; -import { VisTypeVislibDependencies } from './plugin'; import { Rotates } from '../../charts/public'; -import { VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { BaseVisTypeOptions, VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { BasicVislibParams } from './types'; +import { toExpressionAst } from './to_ast'; -export const createHorizontalBarVisTypeDefinition = (deps: VisTypeVislibDependencies) => ({ +export const horizontalBarVisTypeDefinition: BaseVisTypeOptions = { name: 'horizontal_bar', title: i18n.translate('visTypeVislib.horizontalBar.horizontalBarTitle', { defaultMessage: 'Horizontal Bar', @@ -48,10 +48,8 @@ export const createHorizontalBarVisTypeDefinition = (deps: VisTypeVislibDependen description: i18n.translate('visTypeVislib.horizontalBar.horizontalBarDescription', { defaultMessage: 'Assign a continuous variable to each axis', }), - visualization: createVislibVisController(deps), - getSupportedTriggers: () => { - return [VIS_EVENT_TO_TRIGGER.filter, VIS_EVENT_TO_TRIGGER.brush]; - }, + getSupportedTriggers: () => [VIS_EVENT_TO_TRIGGER.filter, VIS_EVENT_TO_TRIGGER.brush], + toExpressionAst, visConfig: { defaults: { type: 'histogram', @@ -130,9 +128,6 @@ export const createHorizontalBarVisTypeDefinition = (deps: VisTypeVislibDependen }, }, }, - events: { - brush: { disabled: false }, - }, editorConfig: { collections: getConfigCollections(), optionTabs: getAreaOptionTabs(), @@ -189,4 +184,4 @@ export const createHorizontalBarVisTypeDefinition = (deps: VisTypeVislibDependen }, ]), }, -}); +}; diff --git a/src/plugins/vis_type_vislib/public/index.scss b/src/plugins/vis_type_vislib/public/index.scss index 64445648ba84a..3c347aebde225 100644 --- a/src/plugins/vis_type_vislib/public/index.scss +++ b/src/plugins/vis_type_vislib/public/index.scss @@ -1 +1 @@ -@import './vislib/index' +@import './vislib/index'; diff --git a/src/plugins/vis_type_vislib/public/line.ts b/src/plugins/vis_type_vislib/public/line.ts index 6e9190229114b..a65b0bcf7e2bb 100644 --- a/src/plugins/vis_type_vislib/public/line.ts +++ b/src/plugins/vis_type_vislib/public/line.ts @@ -35,22 +35,20 @@ import { getConfigCollections, } from './utils/collections'; import { getAreaOptionTabs, countLabel } from './utils/common_config'; -import { createVislibVisController } from './vis_controller'; -import { VisTypeVislibDependencies } from './plugin'; import { Rotates } from '../../charts/public'; -import { VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { BaseVisTypeOptions, VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { toExpressionAst } from './to_ast'; +import { BasicVislibParams } from './types'; -export const createLineVisTypeDefinition = (deps: VisTypeVislibDependencies) => ({ +export const lineVisTypeDefinition: BaseVisTypeOptions = { name: 'line', title: i18n.translate('visTypeVislib.line.lineTitle', { defaultMessage: 'Line' }), icon: 'visLine', description: i18n.translate('visTypeVislib.line.lineDescription', { defaultMessage: 'Emphasize trends', }), - visualization: createVislibVisController(deps), - getSupportedTriggers: () => { - return [VIS_EVENT_TO_TRIGGER.filter, VIS_EVENT_TO_TRIGGER.brush]; - }, + getSupportedTriggers: () => [VIS_EVENT_TO_TRIGGER.filter, VIS_EVENT_TO_TRIGGER.brush], + toExpressionAst, visConfig: { defaults: { type: 'line', @@ -129,9 +127,6 @@ export const createLineVisTypeDefinition = (deps: VisTypeVislibDependencies) => }, }, }, - events: { - brush: { disabled: false }, - }, editorConfig: { collections: getConfigCollections(), optionTabs: getAreaOptionTabs(), @@ -182,4 +177,4 @@ export const createLineVisTypeDefinition = (deps: VisTypeVislibDependencies) => }, ]), }, -}); +}; diff --git a/src/plugins/vis_type_vislib/public/pie.ts b/src/plugins/vis_type_vislib/public/pie.ts index 1e81dbdde3f68..58f7dd0df89e8 100644 --- a/src/plugins/vis_type_vislib/public/pie.ts +++ b/src/plugins/vis_type_vislib/public/pie.ts @@ -23,14 +23,12 @@ import { AggGroupNames } from '../../data/public'; import { Schemas } from '../../vis_default_editor/public'; import { PieOptions } from './components/options'; import { getPositions, Positions } from './utils/collections'; -import { createVislibVisController } from './vis_controller'; import { CommonVislibParams } from './types'; -import { VisTypeVislibDependencies } from './plugin'; -import { VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { BaseVisTypeOptions, VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { toExpressionAst } from './to_ast_pie'; export interface PieVisParams extends CommonVislibParams { type: 'pie'; - addLegend: boolean; isDonut: boolean; labels: { show: boolean; @@ -40,17 +38,15 @@ export interface PieVisParams extends CommonVislibParams { }; } -export const createPieVisTypeDefinition = (deps: VisTypeVislibDependencies) => ({ +export const pieVisTypeDefinition: BaseVisTypeOptions = { name: 'pie', title: i18n.translate('visTypeVislib.pie.pieTitle', { defaultMessage: 'Pie' }), icon: 'visPie', description: i18n.translate('visTypeVislib.pie.pieDescription', { defaultMessage: 'Compare parts of a whole', }), - visualization: createVislibVisController(deps), - getSupportedTriggers: () => { - return [VIS_EVENT_TO_TRIGGER.filter]; - }, + getSupportedTriggers: () => [VIS_EVENT_TO_TRIGGER.filter], + toExpressionAst, visConfig: { defaults: { type: 'pie', @@ -108,4 +104,4 @@ export const createPieVisTypeDefinition = (deps: VisTypeVislibDependencies) => ( }, hierarchicalData: true, responseHandler: 'vislib_slices', -}); +}; diff --git a/src/plugins/vis_type_vislib/public/pie_fn.ts b/src/plugins/vis_type_vislib/public/pie_fn.ts index bee200cbe30ee..c9da9e9bd9fab 100644 --- a/src/plugins/vis_type_vislib/public/pie_fn.ts +++ b/src/plugins/vis_type_vislib/public/pie_fn.ts @@ -18,27 +18,35 @@ */ import { i18n } from '@kbn/i18n'; + import { ExpressionFunctionDefinition, Datatable, Render } from '../../expressions/public'; + // @ts-ignore import { vislibSlicesResponseHandler } from './vislib/response_handler'; +import { PieVisParams } from './pie'; +import { vislibVisName } from './vis_type_vislib_vis_fn'; + +export const vislibPieName = 'vislib_pie_vis'; interface Arguments { visConfig: string; } -type VisParams = Required; - interface RenderValue { - visConfig: VisParams; + visData: unknown; + visType: string; + visConfig: PieVisParams; } -export const createPieVisFn = (): ExpressionFunctionDefinition< - 'kibana_pie', +export type VisTypeVislibPieExpressionFunctionDefinition = ExpressionFunctionDefinition< + typeof vislibPieName, Datatable, Arguments, Render -> => ({ - name: 'kibana_pie', +>; + +export const createPieVisFn = (): VisTypeVislibPieExpressionFunctionDefinition => ({ + name: vislibPieName, type: 'render', inputTypes: ['datatable'], help: i18n.translate('visTypeVislib.functions.pie.help', { @@ -48,23 +56,20 @@ export const createPieVisFn = (): ExpressionFunctionDefinition< visConfig: { types: ['string'], default: '"{}"', - help: '', + help: 'vislib pie vis config', }, }, fn(input, args) { - const visConfig = JSON.parse(args.visConfig); - const convertedData = vislibSlicesResponseHandler(input, visConfig.dimensions); + const visConfig = JSON.parse(args.visConfig) as PieVisParams; + const visData = vislibSlicesResponseHandler(input, visConfig.dimensions); return { type: 'render', - as: 'visualization', + as: vislibVisName, value: { - visData: convertedData, - visType: 'pie', + visData, visConfig, - params: { - listenOnChange: true, - }, + visType: 'pie', }, }; }, diff --git a/src/plugins/vis_type_vislib/public/plugin.ts b/src/plugins/vis_type_vislib/public/plugin.ts index c6a6b6f82592b..f183042fd5201 100644 --- a/src/plugins/vis_type_vislib/public/plugin.ts +++ b/src/plugins/vis_type_vislib/public/plugin.ts @@ -17,40 +17,20 @@ * under the License. */ -import './index.scss'; - -import { - CoreSetup, - CoreStart, - Plugin, - IUiSettingsClient, - PluginInitializerContext, -} from 'kibana/public'; +import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'kibana/public'; import { VisTypeXyPluginSetup } from 'src/plugins/vis_type_xy/public'; import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; -import { VisualizationsSetup } from '../../visualizations/public'; +import { BaseVisTypeOptions, VisualizationsSetup } from '../../visualizations/public'; import { createVisTypeVislibVisFn } from './vis_type_vislib_vis_fn'; import { createPieVisFn } from './pie_fn'; -import { - createHistogramVisTypeDefinition, - createLineVisTypeDefinition, - createPieVisTypeDefinition, - createAreaVisTypeDefinition, - createHeatmapVisTypeDefinition, - createHorizontalBarVisTypeDefinition, - createGaugeVisTypeDefinition, - createGoalVisTypeDefinition, -} from './vis_type_vislib_vis_types'; +import { visLibVisTypeDefinitions, pieVisTypeDefinition } from './vis_type_vislib_vis_types'; import { ChartsPluginSetup } from '../../charts/public'; import { DataPublicPluginStart } from '../../data/public'; -import { setFormatService, setDataActions, setKibanaLegacy } from './services'; import { KibanaLegacyStart } from '../../kibana_legacy/public'; - -export interface VisTypeVislibDependencies { - uiSettings: IUiSettingsClient; - charts: ChartsPluginSetup; -} +import { setFormatService, setDataActions } from './services'; +import { getVislibVisRenderer } from './vis_renderer'; +import { BasicVislibParams } from './types'; /** @internal */ export interface VisTypeVislibPluginSetupDependencies { @@ -66,54 +46,37 @@ export interface VisTypeVislibPluginStartDependencies { kibanaLegacy: KibanaLegacyStart; } -type VisTypeVislibCoreSetup = CoreSetup; +export type VisTypeVislibCoreSetup = CoreSetup; /** @internal */ -export class VisTypeVislibPlugin implements Plugin { +export class VisTypeVislibPlugin + implements + Plugin { constructor(public initializerContext: PluginInitializerContext) {} public async setup( core: VisTypeVislibCoreSetup, { expressions, visualizations, charts, visTypeXy }: VisTypeVislibPluginSetupDependencies ) { - const visualizationDependencies: Readonly = { - uiSettings: core.uiSettings, - charts, - }; - const vislibTypes = [ - createHistogramVisTypeDefinition, - createLineVisTypeDefinition, - createPieVisTypeDefinition, - createAreaVisTypeDefinition, - createHeatmapVisTypeDefinition, - createHorizontalBarVisTypeDefinition, - createGaugeVisTypeDefinition, - createGoalVisTypeDefinition, - ]; - const vislibFns = [createVisTypeVislibVisFn(), createPieVisFn()]; - // if visTypeXy plugin is disabled it's config will be undefined if (!visTypeXy) { - const convertedTypes: any[] = []; + const convertedTypes: Array> = []; const convertedFns: any[] = []; // Register legacy vislib types that have been converted convertedFns.forEach(expressions.registerFunction); - convertedTypes.forEach((vis) => - visualizations.createBaseVisualization(vis(visualizationDependencies)) - ); + convertedTypes.forEach(visualizations.createBaseVisualization); + expressions.registerRenderer(getVislibVisRenderer(core, charts)); } - // Register non-converted types - vislibFns.forEach(expressions.registerFunction); - vislibTypes.forEach((vis) => - visualizations.createBaseVisualization(vis(visualizationDependencies)) - ); + visLibVisTypeDefinitions.forEach(visualizations.createBaseVisualization); + visualizations.createBaseVisualization(pieVisTypeDefinition); + expressions.registerRenderer(getVislibVisRenderer(core, charts)); + [createVisTypeVislibVisFn(), createPieVisFn()].forEach(expressions.registerFunction); } - public start(core: CoreStart, { data, kibanaLegacy }: VisTypeVislibPluginStartDependencies) { + public start(core: CoreStart, { data }: VisTypeVislibPluginStartDependencies) { setFormatService(data.fieldFormats); setDataActions(data.actions); - setKibanaLegacy(kibanaLegacy); } } diff --git a/src/plugins/vis_type_vislib/public/sample_vis.test.mocks.ts b/src/plugins/vis_type_vislib/public/sample_vis.test.mocks.ts new file mode 100644 index 0000000000000..324e8e00f37fc --- /dev/null +++ b/src/plugins/vis_type_vislib/public/sample_vis.test.mocks.ts @@ -0,0 +1,3307 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const samplePieVis = { + type: { + name: 'pie', + title: 'Pie', + description: 'Compare parts of a whole', + icon: 'visPie', + stage: 'production', + options: { + showTimePicker: true, + showQueryBar: true, + showFilterBar: true, + showIndexSelection: true, + hierarchicalData: false, + }, + visConfig: { + defaults: { + type: 'pie', + addTooltip: true, + addLegend: true, + legendPosition: 'right', + isDonut: true, + labels: { + show: false, + values: true, + last_level: true, + truncate: 100, + }, + }, + }, + editorConfig: { + collections: { + legendPositions: [ + { + text: 'Top', + value: 'top', + }, + { + text: 'Left', + value: 'left', + }, + { + text: 'Right', + value: 'right', + }, + { + text: 'Bottom', + value: 'bottom', + }, + ], + }, + schemas: { + all: [ + { + group: 'metrics', + name: 'metric', + title: 'Slice size', + min: 1, + max: 1, + aggFilter: ['sum', 'count', 'cardinality', 'top_hits'], + defaults: [ + { + schema: 'metric', + type: 'count', + }, + ], + editor: false, + params: [], + }, + { + group: 'buckets', + name: 'segment', + title: 'Split slices', + min: 0, + max: null, + aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], + editor: false, + params: [], + }, + { + group: 'buckets', + name: 'split', + title: 'Split chart', + mustBeFirst: true, + min: 0, + max: 1, + aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], + params: [ + { + name: 'row', + default: true, + }, + ], + editor: false, + }, + ], + buckets: [null, null], + metrics: [null], + }, + }, + hidden: false, + requestHandler: 'courier', + responseHandler: 'vislib_slices', + hierarchicalData: true, + useCustomNoDataScreen: false, + }, + title: '[Flights] Airline Carrier', + description: '', + params: { + type: 'pie', + addTooltip: true, + addLegend: true, + legendPosition: 'right', + isDonut: true, + labels: { + show: true, + values: true, + last_level: true, + truncate: 100, + }, + }, + sessionState: {}, + data: { + searchSource: { + id: 'data_source1', + requestStartHandlers: [], + inheritOptions: {}, + history: [], + fields: { + filter: [], + query: { + query: '', + language: 'kuery', + }, + index: { + id: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + title: 'kibana_sample_data_flights', + fieldFormatMap: { + AvgTicketPrice: { + id: 'number', + params: { + parsedUrl: { + origin: 'http://localhost:5801', + pathname: '/app/visualize', + basePath: '', + }, + pattern: '$0,0.[00]', + }, + }, + hour_of_day: { + id: 'number', + params: { + pattern: '00', + }, + }, + }, + fields: [ + { + count: 0, + name: 'AvgTicketPrice', + type: 'number', + esTypes: ['float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'Cancelled', + type: 'boolean', + esTypes: ['boolean'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'Carrier', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'Dest', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DestAirportID', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DestCityName', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DestCountry', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DestLocation', + type: 'geo_point', + esTypes: ['geo_point'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DestRegion', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DestWeather', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DistanceKilometers', + type: 'number', + esTypes: ['float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'DistanceMiles', + type: 'number', + esTypes: ['float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'FlightDelay', + type: 'boolean', + esTypes: ['boolean'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'FlightDelayMin', + type: 'number', + esTypes: ['integer'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'FlightDelayType', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'FlightNum', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'FlightTimeHour', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'FlightTimeMin', + type: 'number', + esTypes: ['float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'Origin', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'OriginAirportID', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'OriginCityName', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'OriginCountry', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'OriginLocation', + type: 'geo_point', + esTypes: ['geo_point'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'OriginRegion', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'OriginWeather', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: '_id', + type: 'string', + esTypes: ['_id'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: false, + }, + { + count: 0, + name: '_index', + type: 'string', + esTypes: ['_index'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: false, + }, + { + count: 0, + name: '_score', + type: 'number', + scripted: false, + searchable: false, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: '_source', + type: '_source', + esTypes: ['_source'], + scripted: false, + searchable: false, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: '_type', + type: 'string', + esTypes: ['_type'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: false, + }, + { + count: 0, + name: 'dayOfWeek', + type: 'number', + esTypes: ['integer'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'timestamp', + type: 'date', + esTypes: ['date'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + script: "doc['timestamp'].value.hourOfDay", + lang: 'painless', + name: 'hour_of_day', + type: 'number', + scripted: true, + searchable: true, + aggregatable: true, + readFromDocValues: false, + }, + ], + timeFieldName: 'timestamp', + metaFields: ['_source', '_id', '_type', '_index', '_score'], + version: 'WzM1LDFd', + originalSavedObjectBody: { + title: 'kibana_sample_data_flights', + timeFieldName: 'timestamp', + fields: + '[{"count":0,"name":"AvgTicketPrice","type":"number","esTypes":["float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"Cancelled","type":"boolean","esTypes":["boolean"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"Carrier","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"Dest","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestAirportID","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestCityName","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestCountry","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestLocation","type":"geo_point","esTypes":["geo_point"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestRegion","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DestWeather","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DistanceKilometers","type":"number","esTypes":["float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"DistanceMiles","type":"number","esTypes":["float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightDelay","type":"boolean","esTypes":["boolean"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightDelayMin","type":"number","esTypes":["integer"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightDelayType","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightNum","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightTimeHour","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"FlightTimeMin","type":"number","esTypes":["float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"Origin","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginAirportID","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginCityName","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginCountry","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginLocation","type":"geo_point","esTypes":["geo_point"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginRegion","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"OriginWeather","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"_id","type":"string","esTypes":["_id"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"count":0,"name":"_index","type":"string","esTypes":["_index"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"count":0,"name":"_score","type":"number","scripted":false,"searchable":false,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"_source","type":"_source","esTypes":["_source"],"scripted":false,"searchable":false,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"_type","type":"string","esTypes":["_type"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"count":0,"name":"dayOfWeek","type":"number","esTypes":["integer"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"timestamp","type":"date","esTypes":["date"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"script":"doc[\'timestamp\'].value.hourOfDay","lang":"painless","name":"hour_of_day","type":"number","scripted":true,"searchable":true,"aggregatable":true,"readFromDocValues":false}]', + fieldFormatMap: + '{"AvgTicketPrice":{"id":"number","params":{"parsedUrl":{"origin":"http://localhost:5801","pathname":"/app/visualize","basePath":""},"pattern":"$0,0.[00]"}},"hour_of_day":{"id":"number","params":{"parsedUrl":{"origin":"http://localhost:5801","pathname":"/app/visualize","basePath":""},"pattern":"00"}}}', + }, + shortDotsEnable: false, + fieldFormats: { + fieldFormats: {}, + defaultMap: { + ip: { + id: 'ip', + params: {}, + }, + date: { + id: 'date', + params: {}, + }, + date_nanos: { + id: 'date_nanos', + params: {}, + es: true, + }, + number: { + id: 'number', + params: {}, + }, + boolean: { + id: 'boolean', + params: {}, + }, + _source: { + id: '_source', + params: {}, + }, + _default_: { + id: 'string', + params: {}, + }, + }, + metaParamsOptions: {}, + }, + }, + }, + dependencies: { + legacy: { + loadingCount$: { + _isScalar: false, + observers: [ + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + destination: { + closed: true, + }, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 1, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [ + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 13, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + null, + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [null], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 1, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + null, + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [null], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 1, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + null, + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [null], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 3, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + null, + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [null], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + null, + ], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + null, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + }, + }, + aggs: { + typesRegistry: {}, + getResponseAggs: () => [ + { + id: '1', + enabled: true, + type: 'count', + params: {}, + schema: 'metric', + toSerializedFieldFormat: () => ({ + id: 'number', + }), + }, + { + id: '2', + enabled: true, + type: 'terms', + params: { + field: 'Carrier', + orderBy: '1', + order: 'desc', + size: 5, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + schema: 'segment', + toSerializedFieldFormat: () => ({ + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + parsedUrl: { + origin: 'http://localhost:5801', + pathname: '/app/visualize', + basePath: '', + }, + }, + }), + }, + ], + }, + }, + isHierarchical: () => true, + uiState: { + vis: { + legendOpen: false, + }, + }, +}; + +export const sampleAreaVis = { + type: { + name: 'area', + title: 'Area', + description: 'Emphasize the quantity beneath a line chart', + icon: 'visArea', + stage: 'production', + options: { + showTimePicker: true, + showQueryBar: true, + showFilterBar: true, + showIndexSelection: true, + hierarchicalData: false, + }, + visConfig: { + defaults: { + type: 'area', + grid: { + categoryLines: false, + }, + categoryAxes: [ + { + id: 'CategoryAxis-1', + type: 'category', + position: 'bottom', + show: true, + style: {}, + scale: { + type: 'linear', + }, + labels: { + show: true, + filter: true, + truncate: 100, + }, + title: {}, + }, + ], + valueAxes: [ + { + id: 'ValueAxis-1', + name: 'LeftAxis-1', + type: 'value', + position: 'left', + show: true, + style: {}, + scale: { + type: 'linear', + mode: 'normal', + }, + labels: { + show: true, + rotate: 0, + filter: false, + truncate: 100, + }, + title: { + text: 'Count', + }, + }, + ], + seriesParams: [ + { + show: true, + type: 'area', + mode: 'stacked', + data: { + label: 'Count', + id: '1', + }, + drawLinesBetweenPoints: true, + lineWidth: 2, + showCircles: true, + interpolate: 'linear', + valueAxis: 'ValueAxis-1', + }, + ], + addTooltip: true, + addLegend: true, + legendPosition: 'right', + times: [], + addTimeMarker: false, + thresholdLine: { + show: false, + value: 10, + width: 1, + style: 'full', + color: '#E7664C', + }, + labels: {}, + }, + }, + editorConfig: { + collections: { + legendPositions: [ + { + text: 'Top', + value: 'top', + }, + { + text: 'Left', + value: 'left', + }, + { + text: 'Right', + value: 'right', + }, + { + text: 'Bottom', + value: 'bottom', + }, + ], + positions: [ + { + text: 'Top', + value: 'top', + }, + { + text: 'Left', + value: 'left', + }, + { + text: 'Right', + value: 'right', + }, + { + text: 'Bottom', + value: 'bottom', + }, + ], + chartTypes: [ + { + text: 'Line', + value: 'line', + }, + { + text: 'Area', + value: 'area', + }, + { + text: 'Bar', + value: 'histogram', + }, + ], + axisModes: [ + { + text: 'Normal', + value: 'normal', + }, + { + text: 'Percentage', + value: 'percentage', + }, + { + text: 'Wiggle', + value: 'wiggle', + }, + { + text: 'Silhouette', + value: 'silhouette', + }, + ], + scaleTypes: [ + { + text: 'Linear', + value: 'linear', + }, + { + text: 'Log', + value: 'log', + }, + { + text: 'Square root', + value: 'square root', + }, + ], + chartModes: [ + { + text: 'Normal', + value: 'normal', + }, + { + text: 'Stacked', + value: 'stacked', + }, + ], + interpolationModes: [ + { + text: 'Straight', + value: 'linear', + }, + { + text: 'Smoothed', + value: 'cardinal', + }, + { + text: 'Stepped', + value: 'step-after', + }, + ], + thresholdLineStyles: [ + { + value: 'full', + text: 'Full', + }, + { + value: 'dashed', + text: 'Dashed', + }, + { + value: 'dot-dashed', + text: 'Dot-dashed', + }, + ], + }, + optionTabs: [ + { + name: 'advanced', + title: 'Metrics & axes', + }, + { + name: 'options', + title: 'Panel settings', + }, + ], + schemas: { + all: [ + { + group: 'metrics', + name: 'metric', + title: 'Y-axis', + aggFilter: ['!geo_centroid', '!geo_bounds'], + min: 1, + defaults: [ + { + schema: 'metric', + type: 'count', + }, + ], + max: null, + editor: false, + params: [], + }, + { + group: 'metrics', + name: 'radius', + title: 'Dot size', + min: 0, + max: 1, + aggFilter: ['count', 'avg', 'sum', 'min', 'max', 'cardinality'], + editor: false, + params: [], + }, + { + group: 'buckets', + name: 'segment', + title: 'X-axis', + min: 0, + max: 1, + aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], + editor: false, + params: [], + }, + { + group: 'buckets', + name: 'group', + title: 'Split series', + min: 0, + max: 3, + aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], + editor: false, + params: [], + }, + { + group: 'buckets', + name: 'split', + title: 'Split chart', + min: 0, + max: 1, + aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'], + params: [ + { + name: 'row', + default: true, + }, + ], + editor: false, + }, + ], + buckets: [null, null, null], + metrics: [null, null], + }, + }, + hidden: false, + requestHandler: 'courier', + responseHandler: 'none', + hierarchicalData: false, + useCustomNoDataScreen: false, + }, + title: '[eCommerce] Sales by Category', + description: '', + params: { + type: 'area', + grid: { + categoryLines: false, + style: { + color: '#eee', + }, + }, + categoryAxes: [ + { + id: 'CategoryAxis-1', + type: 'category', + position: 'bottom', + show: true, + style: {}, + scale: { + type: 'linear', + }, + labels: { + show: true, + truncate: 100, + }, + title: {}, + }, + ], + valueAxes: [ + { + id: 'ValueAxis-1', + name: 'LeftAxis-1', + type: 'value', + position: 'left', + show: true, + style: {}, + scale: { + type: 'linear', + mode: 'normal', + }, + labels: { + show: true, + rotate: 0, + filter: false, + truncate: 100, + }, + title: { + text: 'Sum of total_quantity', + }, + }, + ], + seriesParams: [ + { + show: 'true', + type: 'area', + mode: 'stacked', + data: { + label: 'Sum of total_quantity', + id: '1', + }, + drawLinesBetweenPoints: true, + showCircles: true, + interpolate: 'linear', + valueAxis: 'ValueAxis-1', + }, + ], + addTooltip: true, + addLegend: true, + legendPosition: 'top', + times: [], + addTimeMarker: false, + thresholdLine: { + show: false, + value: 10, + width: 1, + style: 'full', + color: '#E7664C', + }, + labels: {}, + dimensions: { + x: { + accessor: 0, + format: { + id: 'date', + params: { + pattern: 'YYYY-MM-DD HH:mm', + }, + }, + params: { + date: true, + interval: 43200000, + format: 'YYYY-MM-DD HH:mm', + bounds: { + min: '2020-09-30T12:41:13.795Z', + max: '2020-10-15T17:00:00.000Z', + }, + }, + label: 'order_date per 12 hours', + aggType: 'date_histogram', + }, + y: [ + { + accessor: 2, + format: { + id: 'number', + params: { + parsedUrl: { + origin: 'http://localhost:5801', + pathname: '/app/visualize', + basePath: '', + }, + }, + }, + params: {}, + label: 'Sum of total_quantity', + aggType: 'sum', + }, + ], + series: [ + { + accessor: 1, + format: { + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + }, + }, + params: {}, + label: 'category.keyword: Descending', + aggType: 'terms', + }, + ], + }, + }, + sessionState: {}, + data: { + searchSource: { + id: 'data_source1', + requestStartHandlers: [], + inheritOptions: {}, + history: [], + fields: { + query: { + query: '', + language: 'kuery', + }, + filter: [], + index: { + id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', + title: 'kibana_sample_data_ecommerce', + fieldFormatMap: { + taxful_total_price: { + id: 'number', + params: { + pattern: '$0,0.[00]', + }, + }, + }, + fields: [ + { + count: 0, + name: '_id', + type: 'string', + esTypes: ['_id'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: false, + }, + { + count: 0, + name: '_index', + type: 'string', + esTypes: ['_index'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: false, + }, + { + count: 0, + name: '_score', + type: 'number', + scripted: false, + searchable: false, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: '_source', + type: '_source', + esTypes: ['_source'], + scripted: false, + searchable: false, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: '_type', + type: 'string', + esTypes: ['_type'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: false, + }, + { + count: 0, + name: 'category', + type: 'string', + esTypes: ['text'], + scripted: false, + searchable: true, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: 'category.keyword', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + subType: { + multi: { + parent: 'category', + }, + }, + }, + { + count: 0, + name: 'currency', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'customer_birth_date', + type: 'date', + esTypes: ['date'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'customer_first_name', + type: 'string', + esTypes: ['text'], + scripted: false, + searchable: true, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: 'customer_first_name.keyword', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + subType: { + multi: { + parent: 'customer_first_name', + }, + }, + }, + { + count: 0, + name: 'customer_full_name', + type: 'string', + esTypes: ['text'], + scripted: false, + searchable: true, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: 'customer_full_name.keyword', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + subType: { + multi: { + parent: 'customer_full_name', + }, + }, + }, + { + count: 0, + name: 'customer_gender', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'customer_id', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'customer_last_name', + type: 'string', + esTypes: ['text'], + scripted: false, + searchable: true, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: 'customer_last_name.keyword', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + subType: { + multi: { + parent: 'customer_last_name', + }, + }, + }, + { + count: 0, + name: 'customer_phone', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'day_of_week', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'day_of_week_i', + type: 'number', + esTypes: ['integer'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'email', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'event.dataset', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'geoip.city_name', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'geoip.continent_name', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'geoip.country_iso_code', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'geoip.location', + type: 'geo_point', + esTypes: ['geo_point'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'geoip.region_name', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'manufacturer', + type: 'string', + esTypes: ['text'], + scripted: false, + searchable: true, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: 'manufacturer.keyword', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + subType: { + multi: { + parent: 'manufacturer', + }, + }, + }, + { + count: 0, + name: 'order_date', + type: 'date', + esTypes: ['date'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'order_id', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products._id', + type: 'string', + esTypes: ['text'], + scripted: false, + searchable: true, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: 'products._id.keyword', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + subType: { + multi: { + parent: 'products._id', + }, + }, + }, + { + count: 0, + name: 'products.base_price', + type: 'number', + esTypes: ['half_float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products.base_unit_price', + type: 'number', + esTypes: ['half_float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products.category', + type: 'string', + esTypes: ['text'], + scripted: false, + searchable: true, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: 'products.category.keyword', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + subType: { + multi: { + parent: 'products.category', + }, + }, + }, + { + count: 0, + name: 'products.created_on', + type: 'date', + esTypes: ['date'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products.discount_amount', + type: 'number', + esTypes: ['half_float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products.discount_percentage', + type: 'number', + esTypes: ['half_float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products.manufacturer', + type: 'string', + esTypes: ['text'], + scripted: false, + searchable: true, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: 'products.manufacturer.keyword', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + subType: { + multi: { + parent: 'products.manufacturer', + }, + }, + }, + { + count: 0, + name: 'products.min_price', + type: 'number', + esTypes: ['half_float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products.price', + type: 'number', + esTypes: ['half_float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products.product_id', + type: 'number', + esTypes: ['long'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products.product_name', + type: 'string', + esTypes: ['text'], + scripted: false, + searchable: true, + aggregatable: false, + readFromDocValues: false, + }, + { + count: 0, + name: 'products.product_name.keyword', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + subType: { + multi: { + parent: 'products.product_name', + }, + }, + }, + { + count: 0, + name: 'products.quantity', + type: 'number', + esTypes: ['integer'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products.sku', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products.tax_amount', + type: 'number', + esTypes: ['half_float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products.taxful_price', + type: 'number', + esTypes: ['half_float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products.taxless_price', + type: 'number', + esTypes: ['half_float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'products.unit_discount_amount', + type: 'number', + esTypes: ['half_float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'sku', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'taxful_total_price', + type: 'number', + esTypes: ['half_float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'taxless_total_price', + type: 'number', + esTypes: ['half_float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'total_quantity', + type: 'number', + esTypes: ['integer'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'total_unique_products', + type: 'number', + esTypes: ['integer'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'type', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + { + count: 0, + name: 'user', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + ], + timeFieldName: 'order_date', + metaFields: ['_source', '_id', '_type', '_index', '_score'], + version: 'WzEzLDFd', + originalSavedObjectBody: { + title: 'kibana_sample_data_ecommerce', + timeFieldName: 'order_date', + fields: + '[{"count":0,"name":"_id","type":"string","esTypes":["_id"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"count":0,"name":"_index","type":"string","esTypes":["_index"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"count":0,"name":"_score","type":"number","scripted":false,"searchable":false,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"_source","type":"_source","esTypes":["_source"],"scripted":false,"searchable":false,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"_type","type":"string","esTypes":["_type"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"count":0,"name":"category","type":"string","esTypes":["text"],"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"category.keyword","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"category"}}},{"count":0,"name":"currency","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"customer_birth_date","type":"date","esTypes":["date"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"customer_first_name","type":"string","esTypes":["text"],"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"customer_first_name.keyword","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"customer_first_name"}}},{"count":0,"name":"customer_full_name","type":"string","esTypes":["text"],"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"customer_full_name.keyword","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"customer_full_name"}}},{"count":0,"name":"customer_gender","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"customer_id","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"customer_last_name","type":"string","esTypes":["text"],"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"customer_last_name.keyword","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"customer_last_name"}}},{"count":0,"name":"customer_phone","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"day_of_week","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"day_of_week_i","type":"number","esTypes":["integer"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"email","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"event.dataset","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"geoip.city_name","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"geoip.continent_name","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"geoip.country_iso_code","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"geoip.location","type":"geo_point","esTypes":["geo_point"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"geoip.region_name","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"manufacturer","type":"string","esTypes":["text"],"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"manufacturer.keyword","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"manufacturer"}}},{"count":0,"name":"order_date","type":"date","esTypes":["date"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"order_id","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products._id","type":"string","esTypes":["text"],"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"products._id.keyword","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"products._id"}}},{"count":0,"name":"products.base_price","type":"number","esTypes":["half_float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products.base_unit_price","type":"number","esTypes":["half_float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products.category","type":"string","esTypes":["text"],"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"products.category.keyword","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"products.category"}}},{"count":0,"name":"products.created_on","type":"date","esTypes":["date"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products.discount_amount","type":"number","esTypes":["half_float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products.discount_percentage","type":"number","esTypes":["half_float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products.manufacturer","type":"string","esTypes":["text"],"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"products.manufacturer.keyword","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"products.manufacturer"}}},{"count":0,"name":"products.min_price","type":"number","esTypes":["half_float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products.price","type":"number","esTypes":["half_float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products.product_id","type":"number","esTypes":["long"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products.product_name","type":"string","esTypes":["text"],"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"count":0,"name":"products.product_name.keyword","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"products.product_name"}}},{"count":0,"name":"products.quantity","type":"number","esTypes":["integer"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products.sku","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products.tax_amount","type":"number","esTypes":["half_float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products.taxful_price","type":"number","esTypes":["half_float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products.taxless_price","type":"number","esTypes":["half_float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"products.unit_discount_amount","type":"number","esTypes":["half_float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"sku","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"taxful_total_price","type":"number","esTypes":["half_float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"taxless_total_price","type":"number","esTypes":["half_float"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"total_quantity","type":"number","esTypes":["integer"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"total_unique_products","type":"number","esTypes":["integer"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"type","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"count":0,"name":"user","type":"string","esTypes":["keyword"],"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true}]', + fieldFormatMap: + '{"taxful_total_price":{"id":"number","params":{"parsedUrl":{"origin":"http://localhost:5801","pathname":"/app/visualize","basePath":""},"pattern":"$0,0.[00]"}}}', + }, + shortDotsEnable: false, + fieldFormats: { + fieldFormats: {}, + defaultMap: { + ip: { + id: 'ip', + params: {}, + }, + date: { + id: 'date', + params: {}, + }, + date_nanos: { + id: 'date_nanos', + params: {}, + es: true, + }, + number: { + id: 'number', + params: {}, + }, + boolean: { + id: 'boolean', + params: {}, + }, + _source: { + id: '_source', + params: {}, + }, + _default_: { + id: 'string', + params: {}, + }, + }, + metaParamsOptions: {}, + }, + }, + }, + dependencies: { + legacy: { + loadingCount$: { + _isScalar: false, + observers: [ + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + destination: { + closed: true, + }, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 1, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [ + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 13, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + null, + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [null], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 1, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + null, + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [null], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 1, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + null, + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [null], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: { + closed: false, + _parentOrParents: null, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + destination: { + closed: false, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + _context: {}, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + count: 3, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: false, + hasPrev: true, + prev: 0, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: true, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [], + active: 1, + index: 2, + }, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + parent: { + closed: true, + _parentOrParents: null, + _subscriptions: null, + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: true, + concurrent: 1, + hasCompleted: true, + buffer: [ + { + _isScalar: false, + }, + ], + active: 1, + index: 1, + }, + }, + _subscriptions: [ + null, + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + subject: { + _isScalar: false, + observers: [null], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + null, + ], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + }, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + null, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + seenValue: false, + }, + _subscriptions: [null], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + }, + _subscriptions: [ + { + closed: false, + _subscriptions: null, + }, + ], + syncErrorValue: null, + syncErrorThrown: false, + syncErrorThrowable: false, + isStopped: false, + hasKey: true, + key: 0, + }, + ], + closed: false, + isStopped: false, + hasError: false, + thrownError: null, + _value: 0, + }, + }, + }, + }, + aggs: { + typesRegistry: {}, + getResponseAggs: () => [ + { + id: '1', + enabled: true, + type: 'sum', + params: { + field: 'total_quantity', + }, + schema: 'metric', + toSerializedFieldFormat: () => ({ + id: 'number', + params: { + parsedUrl: { + origin: 'http://localhost:5801', + pathname: '/app/visualize', + basePath: '', + }, + }, + }), + }, + { + id: '2', + enabled: true, + type: 'date_histogram', + params: { + field: 'order_date', + timeRange: { + from: '2020-09-30T12:41:13.795Z', + to: '2020-10-15T17:00:00.000Z', + }, + useNormalizedEsInterval: true, + scaleMetricValues: false, + interval: 'auto', + drop_partials: false, + min_doc_count: 1, + extended_bounds: {}, + }, + schema: 'segment', + toSerializedFieldFormat: () => ({ + id: 'date', + params: { pattern: 'HH:mm:ss.SSS' }, + }), + }, + { + id: '3', + enabled: true, + type: 'terms', + params: { + field: 'category.keyword', + orderBy: '1', + order: 'desc', + size: 5, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + schema: 'group', + toSerializedFieldFormat: () => ({ + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + parsedUrl: { + origin: 'http://localhost:5801', + pathname: '/app/visualize', + basePath: '', + }, + }, + }), + }, + ], + }, + }, + isHierarchical: () => false, + uiState: {}, +}; diff --git a/src/plugins/vis_type_vislib/public/services.ts b/src/plugins/vis_type_vislib/public/services.ts index 7257b98f2e9f5..633fae9c7f2a6 100644 --- a/src/plugins/vis_type_vislib/public/services.ts +++ b/src/plugins/vis_type_vislib/public/services.ts @@ -19,7 +19,6 @@ import { createGetterSetter } from '../../kibana_utils/public'; import { DataPublicPluginStart } from '../../data/public'; -import { KibanaLegacyStart } from '../../kibana_legacy/public'; export const [getDataActions, setDataActions] = createGetterSetter< DataPublicPluginStart['actions'] @@ -28,7 +27,3 @@ export const [getDataActions, setDataActions] = createGetterSetter< export const [getFormatService, setFormatService] = createGetterSetter< DataPublicPluginStart['fieldFormats'] >('vislib data.fieldFormats'); - -export const [getKibanaLegacy, setKibanaLegacy] = createGetterSetter( - 'vislib kibanalegacy' -); diff --git a/src/plugins/vis_type_vislib/public/to_ast.test.ts b/src/plugins/vis_type_vislib/public/to_ast.test.ts new file mode 100644 index 0000000000000..48d3dfe254d0b --- /dev/null +++ b/src/plugins/vis_type_vislib/public/to_ast.test.ts @@ -0,0 +1,60 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Vis } from '../../visualizations/public'; +import { buildExpression } from '../../expressions/public'; + +import { BasicVislibParams } from './types'; +import { toExpressionAst } from './to_ast'; +import { sampleAreaVis } from './sample_vis.test.mocks'; + +jest.mock('../../expressions/public', () => ({ + ...(jest.requireActual('../../expressions/public') as any), + buildExpression: jest.fn().mockImplementation(() => ({ + toAst: () => ({ + type: 'expression', + chain: [], + }), + })), +})); + +jest.mock('./to_ast_esaggs', () => ({ + getEsaggsFn: jest.fn(), +})); + +describe('vislib vis toExpressionAst function', () => { + let vis: Vis; + + const params = { + timefilter: {}, + timeRange: {}, + abortSignal: {}, + } as any; + + beforeEach(() => { + vis = sampleAreaVis as any; + }); + + it('should match basic snapshot', () => { + toExpressionAst(vis, params); + const [, builtExpression] = (buildExpression as jest.Mock).mock.calls[0][0]; + + expect(builtExpression).toMatchSnapshot(); + }); +}); diff --git a/src/plugins/vis_type_vislib/public/to_ast.ts b/src/plugins/vis_type_vislib/public/to_ast.ts new file mode 100644 index 0000000000000..7cd55ccd32ebc --- /dev/null +++ b/src/plugins/vis_type_vislib/public/to_ast.ts @@ -0,0 +1,103 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import moment from 'moment'; + +import { VisToExpressionAst, getVisSchemas } from '../../visualizations/public'; +import { buildExpression, buildExpressionFunction } from '../../expressions/public'; + +import { vislibVisName, VisTypeVislibExpressionFunctionDefinition } from './vis_type_vislib_vis_fn'; +import { BasicVislibParams } from './types'; +import { + DateHistogramParams, + Dimensions, + HistogramParams, +} from './vislib/helpers/point_series/point_series'; +import { getEsaggsFn } from './to_ast_esaggs'; + +export const toExpressionAst: VisToExpressionAst = async (vis, params) => { + const schemas = getVisSchemas(vis, params); + const dimensions: Dimensions = { + x: schemas.segment ? schemas.segment[0] : null, + y: schemas.metric, + z: schemas.radius, + width: schemas.width, + series: schemas.group, + splitRow: schemas.split_row, + splitColumn: schemas.split_column, + }; + + const responseAggs = vis.data.aggs?.getResponseAggs() ?? []; + + if (dimensions.x) { + const xAgg = responseAggs[dimensions.x.accessor] as any; + if (xAgg.type.name === 'date_histogram') { + (dimensions.x.params as DateHistogramParams).date = true; + const { esUnit, esValue } = xAgg.buckets.getInterval(); + (dimensions.x.params as DateHistogramParams).intervalESUnit = esUnit; + (dimensions.x.params as DateHistogramParams).intervalESValue = esValue; + (dimensions.x.params as DateHistogramParams).interval = moment + .duration(esValue, esUnit) + .asMilliseconds(); + (dimensions.x.params as DateHistogramParams).format = xAgg.buckets.getScaledDateFormat(); + (dimensions.x.params as DateHistogramParams).bounds = xAgg.buckets.getBounds(); + } else if (xAgg.type.name === 'histogram') { + const intervalParam = xAgg.type.paramByName('interval'); + const output = { params: {} as any }; + await intervalParam.modifyAggConfigOnSearchRequestStart(xAgg, vis.data.searchSource, { + abortSignal: params.abortSignal, + }); + intervalParam.write(xAgg, output); + (dimensions.x.params as HistogramParams).interval = output.params.interval; + } + } + + const visConfig = { ...vis.params }; + + (dimensions.y || []).forEach((yDimension) => { + const yAgg = responseAggs.filter(({ enabled }) => enabled)[yDimension.accessor]; + const seriesParam = (visConfig.seriesParams || []).find((param) => param.data.id === yAgg.id); + if (seriesParam) { + const usedValueAxis = (visConfig.valueAxes || []).find( + (valueAxis) => valueAxis.id === seriesParam.valueAxis + ); + if (usedValueAxis?.scale.mode === 'percentage') { + yDimension.format = { id: 'percent' }; + } + } + if (visConfig?.gauge?.percentageMode === true) { + yDimension.format = { id: 'percent' }; + } + }); + + visConfig.dimensions = dimensions; + + const configStr = JSON.stringify(visConfig).replace(/\\/g, `\\\\`).replace(/'/g, `\\'`); + const visTypeXy = buildExpressionFunction( + vislibVisName, + { + type: vis.type.name, + visConfig: configStr, + } + ); + + const ast = buildExpression([getEsaggsFn(vis), visTypeXy]); + + return ast.toAst(); +}; diff --git a/src/plugins/vis_type_vislib/public/components/options/index.ts b/src/plugins/vis_type_vislib/public/to_ast_esaggs.ts similarity index 51% rename from src/plugins/vis_type_vislib/public/components/options/index.ts rename to src/plugins/vis_type_vislib/public/to_ast_esaggs.ts index 57afbd4818ae4..a7312c9d36cbb 100644 --- a/src/plugins/vis_type_vislib/public/components/options/index.ts +++ b/src/plugins/vis_type_vislib/public/to_ast_esaggs.ts @@ -17,8 +17,24 @@ * under the License. */ -export { GaugeOptions } from './gauge'; -export { PieOptions } from './pie'; -export { PointSeriesOptions } from './point_series'; -export { HeatmapOptions } from './heatmap'; -export { MetricsAxisOptions } from './metrics_axes'; +import { Vis } from '../../visualizations/public'; +import { buildExpressionFunction } from '../../expressions/public'; +import { EsaggsExpressionFunctionDefinition } from '../../data/public'; + +import { PieVisParams } from './pie'; +import { BasicVislibParams } from './types'; + +/** + * Get esaggs expressions function + * TODO: replace this with vis.data.aggs!.toExpressionAst(); + * @param vis + */ +export function getEsaggsFn(vis: Vis | Vis) { + return buildExpressionFunction('esaggs', { + index: vis.data.indexPattern!.id!, + metricsAtAllLevels: vis.isHierarchical(), + partialRows: false, + aggConfigs: JSON.stringify(vis.data.aggs!.aggs), + includeFormatHints: false, + }); +} diff --git a/src/plugins/vis_type_vislib/public/to_ast_pie.test.ts b/src/plugins/vis_type_vislib/public/to_ast_pie.test.ts new file mode 100644 index 0000000000000..36a9a17341bc5 --- /dev/null +++ b/src/plugins/vis_type_vislib/public/to_ast_pie.test.ts @@ -0,0 +1,60 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Vis } from '../../visualizations/public'; +import { buildExpression } from '../../expressions/public'; + +import { PieVisParams } from './pie'; +import { samplePieVis } from './sample_vis.test.mocks'; +import { toExpressionAst } from './to_ast_pie'; + +jest.mock('../../expressions/public', () => ({ + ...(jest.requireActual('../../expressions/public') as any), + buildExpression: jest.fn().mockImplementation(() => ({ + toAst: () => ({ + type: 'expression', + chain: [], + }), + })), +})); + +jest.mock('./to_ast_esaggs', () => ({ + getEsaggsFn: jest.fn(), +})); + +describe('vislib pie vis toExpressionAst function', () => { + let vis: Vis; + + const params = { + timefilter: {}, + timeRange: {}, + abortSignal: {}, + } as any; + + beforeEach(() => { + vis = samplePieVis as any; + }); + + it('should match basic snapshot', () => { + toExpressionAst(vis, params); + const [, builtExpression] = (buildExpression as jest.Mock).mock.calls[0][0]; + + expect(builtExpression).toMatchSnapshot(); + }); +}); diff --git a/src/plugins/vis_type_vislib/public/to_ast_pie.ts b/src/plugins/vis_type_vislib/public/to_ast_pie.ts new file mode 100644 index 0000000000000..95a5f89208ef9 --- /dev/null +++ b/src/plugins/vis_type_vislib/public/to_ast_pie.ts @@ -0,0 +1,50 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { getVisSchemas, VisToExpressionAst } from '../../visualizations/public'; +import { buildExpression, buildExpressionFunction } from '../../expressions/public'; + +import { PieVisParams } from './pie'; +import { vislibPieName, VisTypeVislibPieExpressionFunctionDefinition } from './pie_fn'; +import { getEsaggsFn } from './to_ast_esaggs'; + +export const toExpressionAst: VisToExpressionAst = async (vis, params) => { + const schemas = getVisSchemas(vis, params); + const visConfig = { + ...vis.params, + dimensions: { + metric: schemas.metric[0], + buckets: schemas.segment, + splitRow: schemas.split_row, + splitColumn: schemas.split_column, + }, + }; + + const configStr = JSON.stringify(visConfig).replace(/\\/g, `\\\\`).replace(/'/g, `\\'`); + const visTypePie = buildExpressionFunction( + vislibPieName, + { + visConfig: configStr, + } + ); + + const ast = buildExpression([getEsaggsFn(vis), visTypePie]); + + return ast.toAst(); +}; diff --git a/src/plugins/vis_type_vislib/public/types.ts b/src/plugins/vis_type_vislib/public/types.ts index a29f0bcb5c52a..c0311edf76154 100644 --- a/src/plugins/vis_type_vislib/public/types.ts +++ b/src/plugins/vis_type_vislib/public/types.ts @@ -29,10 +29,13 @@ import { ThresholdLineStyles, } from './utils/collections'; import { Labels, Style } from '../../charts/public'; +import { Dimensions } from './vislib/helpers/point_series/point_series'; export interface CommonVislibParams { addTooltip: boolean; + addLegend: boolean; legendPosition: Positions; + dimensions: Dimensions; } export interface Scale { @@ -87,6 +90,9 @@ export interface BasicVislibParams extends CommonVislibParams { labels: Labels; thresholdLine: ThresholdLine; valueAxes: ValueAxis[]; + gauge?: { + percentageMode: boolean; + }; grid: { categoryLines: boolean; valueAxis?: string; diff --git a/src/plugins/vis_type_vislib/public/vis_controller.tsx b/src/plugins/vis_type_vislib/public/vis_controller.tsx index 3a05030f804ca..1804d0d52ae7a 100644 --- a/src/plugins/vis_type_vislib/public/vis_controller.tsx +++ b/src/plugins/vis_type_vislib/public/vis_controller.tsx @@ -20,127 +20,147 @@ import $ from 'jquery'; import React, { RefObject } from 'react'; -import { Positions } from './utils/collections'; -import { VisTypeVislibDependencies } from './plugin'; import { mountReactNode } from '../../../core/public/utils'; +import { ChartsPluginSetup } from '../../charts/public'; +import { PersistedState } from '../../visualizations/public'; +import { IInterpreterRenderHandlers } from '../../expressions/public'; + +import { VisTypeVislibCoreSetup } from './plugin'; import { VisLegend, CUSTOM_LEGEND_VIS_TYPES } from './vislib/components/legend'; -import { VisParams, ExprVis } from '../../visualizations/public'; -import { getKibanaLegacy } from './services'; +import { BasicVislibParams } from './types'; +import { PieVisParams } from './pie'; const legendClassName = { - top: 'visLib--legend-top', - bottom: 'visLib--legend-bottom', - left: 'visLib--legend-left', - right: 'visLib--legend-right', + top: 'vislib--legend-top', + bottom: 'vislib--legend-bottom', + left: 'vislib--legend-left', + right: 'vislib--legend-right', }; -export const createVislibVisController = (deps: VisTypeVislibDependencies) => { +export type VislibVisController = InstanceType>; + +export const createVislibVisController = ( + core: VisTypeVislibCoreSetup, + charts: ChartsPluginSetup +) => { return class VislibVisController { - unmount: (() => void) | null = null; - visParams?: VisParams; + private removeListeners?: () => void; + private unmountLegend?: () => void; + legendRef: RefObject; container: HTMLDivElement; chartEl: HTMLDivElement; legendEl: HTMLDivElement; - vislibVis: any; + vislibVis?: any; - constructor(public el: Element, public vis: ExprVis) { + constructor(public el: HTMLDivElement) { this.el = el; - this.vis = vis; - this.unmount = null; this.legendRef = React.createRef(); // vis mount point this.container = document.createElement('div'); - this.container.className = 'visLib'; + this.container.className = 'vislib'; this.el.appendChild(this.container); // chart mount point this.chartEl = document.createElement('div'); - this.chartEl.className = 'visLib__chart'; + this.chartEl.className = 'vislib__chart'; this.container.appendChild(this.chartEl); // legend mount point this.legendEl = document.createElement('div'); - this.legendEl.className = 'visLib__legend'; + this.legendEl.className = 'vislib__legend'; this.container.appendChild(this.legendEl); } - render(esResponse: any, visParams: VisParams): Promise { + async render( + esResponse: any, + visParams: BasicVislibParams | PieVisParams, + handlers: IInterpreterRenderHandlers + ): Promise { if (this.vislibVis) { - this.destroy(); + this.destroy(false); + } + + // Used in functional tests to know when chart is loaded by type + this.chartEl.dataset.vislibChartType = visParams.type; + + if (this.el.clientWidth === 0 || this.el.clientHeight === 0) { + handlers.done(); + return; + } + + const [, { kibanaLegacy }] = await core.getStartServices(); + kibanaLegacy.loadFontAwesome(); + + // @ts-expect-error + const { Vis: Vislib } = await import('./vislib/vis'); + const { uiState, event: fireEvent } = handlers; + + this.vislibVis = new Vislib(this.chartEl, visParams, core, charts); + this.vislibVis.on('brush', fireEvent); + this.vislibVis.on('click', fireEvent); + this.vislibVis.on('renderComplete', handlers.done); + this.removeListeners = () => { + this.vislibVis.off('brush', fireEvent); + this.vislibVis.off('click', fireEvent); + }; + + this.vislibVis.initVisConfig(esResponse, uiState); + + if (visParams.addLegend) { + $(this.container) + .attr('class', (i, cls) => { + return cls.replace(/vislib--legend-\S+/g, ''); + }) + .addClass((legendClassName as any)[visParams.legendPosition]); + + this.mountLegend(esResponse, visParams, fireEvent, uiState); } - getKibanaLegacy().loadFontAwesome(); - - return new Promise(async (resolve) => { - if (this.el.clientWidth === 0 || this.el.clientHeight === 0) { - return resolve(); - } - - // @ts-expect-error - const { Vis: Vislib } = await import('./vislib/vis'); - - this.vislibVis = new Vislib(this.chartEl, visParams, deps); - this.vislibVis.on('brush', this.vis.API.events.brush); - this.vislibVis.on('click', this.vis.API.events.filter); - this.vislibVis.on('renderComplete', resolve); - - this.vislibVis.initVisConfig(esResponse, this.vis.getUiState()); - - if (visParams.addLegend) { - $(this.container) - .attr('class', (i, cls) => { - return cls.replace(/visLib--legend-\S+/g, ''); - }) - .addClass((legendClassName as any)[visParams.legendPosition]); - - this.mountLegend(esResponse, visParams.legendPosition); - } - - this.vislibVis.render(esResponse, this.vis.getUiState()); - - // refreshing the legend after the chart is rendered. - // this is necessary because some visualizations - // provide data necessary for the legend only after a render cycle. - if ( - visParams.addLegend && - CUSTOM_LEGEND_VIS_TYPES.includes(this.vislibVis.visConfigArgs.type) - ) { - this.unmountLegend(); - this.mountLegend(esResponse, visParams.legendPosition); - this.vislibVis.render(esResponse, this.vis.getUiState()); - } - }); + this.vislibVis.render(esResponse, uiState); + + // refreshing the legend after the chart is rendered. + // this is necessary because some visualizations + // provide data necessary for the legend only after a render cycle. + if ( + visParams.addLegend && + CUSTOM_LEGEND_VIS_TYPES.includes(this.vislibVis.visConfigArgs.type) + ) { + this.unmountLegend?.(); + this.mountLegend(esResponse, visParams, fireEvent, uiState); + this.vislibVis.render(esResponse, uiState); + } } - mountLegend(visData: any, position: Positions) { - this.unmount = mountReactNode( + mountLegend( + visData: unknown, + { legendPosition, addLegend }: BasicVislibParams | PieVisParams, + fireEvent: IInterpreterRenderHandlers['event'], + uiState?: PersistedState + ) { + this.unmountLegend = mountReactNode( )(this.legendEl); } - unmountLegend() { - if (this.unmount) { - this.unmount(); - } - } + destroy(clearElement = true) { + this.unmountLegend?.(); - destroy() { - if (this.unmount) { - this.unmount(); + if (clearElement) { + this.el.innerHTML = ''; } if (this.vislibVis) { - this.vislibVis.off('brush', this.vis.API.events.brush); - this.vislibVis.off('click', this.vis.API.events.filter); + this.removeListeners?.(); this.vislibVis.destroy(); delete this.vislibVis; } diff --git a/src/plugins/vis_type_vislib/public/vis_renderer.tsx b/src/plugins/vis_type_vislib/public/vis_renderer.tsx new file mode 100644 index 0000000000000..9c697f481e63e --- /dev/null +++ b/src/plugins/vis_type_vislib/public/vis_renderer.tsx @@ -0,0 +1,61 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { lazy } from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; + +import { ExpressionRenderDefinition } from '../../expressions/public'; +import { VisualizationContainer } from '../../visualizations/public'; +import { ChartsPluginSetup } from '../../charts/public'; + +import { VisTypeVislibCoreSetup } from './plugin'; +import { VislibRenderValue, vislibVisName } from './vis_type_vislib_vis_fn'; + +function shouldShowNoResultsMessage(visData: any, visType: string): boolean { + if (['goal', 'gauge'].includes(visType)) { + return false; + } + + const rows: object[] | undefined = visData?.rows; + const isZeroHits = visData?.hits === 0 || (rows && !rows.length); + + return Boolean(isZeroHits); +} + +const VislibWrapper = lazy(() => import('./vis_wrapper')); + +export const getVislibVisRenderer: ( + core: VisTypeVislibCoreSetup, + charts: ChartsPluginSetup +) => ExpressionRenderDefinition = (core, charts) => ({ + name: vislibVisName, + reuseDomNode: true, + render: async (domNode, config, handlers) => { + const showNoResult = shouldShowNoResultsMessage(config.visData, config.visType); + + handlers.onDestroy(() => unmountComponentAtNode(domNode)); + + render( + + + , + domNode + ); + }, +}); diff --git a/src/plugins/vis_type_vislib/public/vis_type_vislib_vis_fn.ts b/src/plugins/vis_type_vislib/public/vis_type_vislib_vis_fn.ts index 557f9930f55b1..c5fa8f36f43e3 100644 --- a/src/plugins/vis_type_vislib/public/vis_type_vislib_vis_fn.ts +++ b/src/plugins/vis_type_vislib/public/vis_type_vislib_vis_fn.ts @@ -18,29 +18,35 @@ */ import { i18n } from '@kbn/i18n'; + import { ExpressionFunctionDefinition, Datatable, Render } from '../../expressions/public'; + // @ts-ignore import { vislibSeriesResponseHandler } from './vislib/response_handler'; +import { BasicVislibParams } from './types'; + +export const vislibVisName = 'vislib_vis'; interface Arguments { type: string; visConfig: string; } -type VisParams = Required; - -interface RenderValue { +export interface VislibRenderValue { + visData: any; visType: string; - visConfig: VisParams; + visConfig: BasicVislibParams; } -export const createVisTypeVislibVisFn = (): ExpressionFunctionDefinition< - 'vislib', +export type VisTypeVislibExpressionFunctionDefinition = ExpressionFunctionDefinition< + typeof vislibVisName, Datatable, Arguments, - Render -> => ({ - name: 'vislib', + Render +>; + +export const createVisTypeVislibVisFn = (): VisTypeVislibExpressionFunctionDefinition => ({ + name: vislibVisName, type: 'render', inputTypes: ['datatable'], help: i18n.translate('visTypeVislib.functions.vislib.help', { @@ -55,23 +61,21 @@ export const createVisTypeVislibVisFn = (): ExpressionFunctionDefinition< visConfig: { types: ['string'], default: '"{}"', - help: '', + help: 'vislib vis config', }, }, fn(context, args) { - const visConfigParams = JSON.parse(args.visConfig); - const convertedData = vislibSeriesResponseHandler(context, visConfigParams.dimensions); + const visType = args.type; + const visConfig = JSON.parse(args.visConfig) as BasicVislibParams; + const visData = vislibSeriesResponseHandler(context, visConfig.dimensions); return { type: 'render', - as: 'visualization', + as: vislibVisName, value: { - visData: convertedData, - visType: args.type, - visConfig: visConfigParams, - params: { - listenOnChange: true, - }, + visData, + visConfig, + visType, }, }; }, diff --git a/src/plugins/vis_type_vislib/public/vis_type_vislib_vis_types.ts b/src/plugins/vis_type_vislib/public/vis_type_vislib_vis_types.ts index f44d503895483..1b43a213c618d 100644 --- a/src/plugins/vis_type_vislib/public/vis_type_vislib_vis_types.ts +++ b/src/plugins/vis_type_vislib/public/vis_type_vislib_vis_types.ts @@ -17,11 +17,22 @@ * under the License. */ -export { createHistogramVisTypeDefinition } from './histogram'; -export { createLineVisTypeDefinition } from './line'; -export { createPieVisTypeDefinition } from './pie'; -export { createAreaVisTypeDefinition } from './area'; -export { createHeatmapVisTypeDefinition } from './heatmap'; -export { createHorizontalBarVisTypeDefinition } from './horizontal_bar'; -export { createGaugeVisTypeDefinition } from './gauge'; -export { createGoalVisTypeDefinition } from './goal'; +import { histogramVisTypeDefinition } from './histogram'; +import { lineVisTypeDefinition } from './line'; +import { areaVisTypeDefinition } from './area'; +import { heatmapVisTypeDefinition } from './heatmap'; +import { horizontalBarVisTypeDefinition } from './horizontal_bar'; +import { gaugeVisTypeDefinition } from './gauge'; +import { goalVisTypeDefinition } from './goal'; + +export { pieVisTypeDefinition } from './pie'; + +export const visLibVisTypeDefinitions = [ + histogramVisTypeDefinition, + lineVisTypeDefinition, + areaVisTypeDefinition, + heatmapVisTypeDefinition, + horizontalBarVisTypeDefinition, + gaugeVisTypeDefinition, + goalVisTypeDefinition, +]; diff --git a/src/plugins/vis_type_vislib/public/vis_wrapper.tsx b/src/plugins/vis_type_vislib/public/vis_wrapper.tsx new file mode 100644 index 0000000000000..980ba1c175885 --- /dev/null +++ b/src/plugins/vis_type_vislib/public/vis_wrapper.tsx @@ -0,0 +1,89 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { useEffect, useMemo, useRef } from 'react'; +import { EuiResizeObserver } from '@elastic/eui'; +import { debounce } from 'lodash'; + +import { IInterpreterRenderHandlers } from '../../expressions/public'; +import { ChartsPluginSetup } from '../../charts/public'; + +import { VislibRenderValue } from './vis_type_vislib_vis_fn'; +import { createVislibVisController, VislibVisController } from './vis_controller'; +import { VisTypeVislibCoreSetup } from './plugin'; + +import './index.scss'; + +type VislibWrapperProps = VislibRenderValue & { + core: VisTypeVislibCoreSetup; + charts: ChartsPluginSetup; + handlers: IInterpreterRenderHandlers; +}; + +const VislibWrapper = ({ core, charts, visData, visConfig, handlers }: VislibWrapperProps) => { + const chartDiv = useRef(null); + const visController = useRef(null); + + const updateChart = useMemo( + () => + debounce(() => { + if (visController.current) { + visController.current.render(visData, visConfig, handlers); + } + }, 100), + [visConfig, visData, handlers] + ); + + useEffect(() => { + if (chartDiv.current) { + const Controller = createVislibVisController(core, charts); + visController.current = new Controller(chartDiv.current); + } + return () => { + visController.current?.destroy(); + visController.current = null; + }; + }, [core, charts, handlers]); + + useEffect(updateChart, [updateChart]); + + useEffect(() => { + if (handlers.uiState) { + handlers.uiState.on('change', updateChart); + + return () => { + handlers.uiState?.off('change', updateChart); + }; + } + }, [handlers.uiState, updateChart]); + + return ( + + {(resizeRef) => ( +
+
+
+ )} + + ); +}; + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { VislibWrapper as default }; diff --git a/src/plugins/vis_type_vislib/public/vislib/_vislib_vis_type.scss b/src/plugins/vis_type_vislib/public/vislib/_vislib_vis_type.scss index c03aa19140de0..843bb9d3f03eb 100644 --- a/src/plugins/vis_type_vislib/public/vislib/_vislib_vis_type.scss +++ b/src/plugins/vis_type_vislib/public/vislib/_vislib_vis_type.scss @@ -1,27 +1,29 @@ -.visLib { +.vislib { flex: 1 1 0; display: flex; flex-direction: row; overflow: auto; - &.visLib--legend-left { + &.vislib--legend-left { flex-direction: row-reverse; } - &.visLib--legend-right { + &.vislib--legend-right { flex-direction: row; } - &.visLib--legend-top { + &.vislib--legend-top { flex-direction: column-reverse; } - &.visLib--legend-bottom { + &.vislib--legend-bottom { flex-direction: column; } } -.visLib__chart { +.vislib__chart, +.vislib__wrapper, +.vislib__container { display: flex; flex: 1 1 auto; min-height: 0; diff --git a/src/plugins/vis_type_vislib/public/vislib/components/legend/_legend.scss b/src/plugins/vis_type_vislib/public/vislib/components/legend/_legend.scss index b1a59f88a348a..a06f0cb00787b 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/legend/_legend.scss +++ b/src/plugins/vis_type_vislib/public/vislib/components/legend/_legend.scss @@ -13,6 +13,7 @@ $visLegendLineHeight: $euiSize; left: 0; display: flex; padding: $euiSizeXS; + margin: $euiSizeS; background-color: $euiColorEmptyShade; transition: opacity $euiAnimSpeedFast $euiAnimSlightResistance, background-color $euiAnimSpeedFast $euiAnimSlightResistance $euiAnimSpeedExtraSlow; @@ -33,13 +34,13 @@ $visLegendLineHeight: $euiSize; height: 100%; } -.visLib--legend-left { +.vislib--legend-left { .visLegend__list { margin-bottom: $euiSizeL; } } -.visLib--legend-bottom { +.vislib--legend-bottom { .visLegend__list { margin-left: $euiSizeL; } @@ -64,8 +65,8 @@ $visLegendLineHeight: $euiSize; } } - .visLib--legend-top &, - .visLib--legend-bottom & { + .vislib--legend-top &, + .vislib--legend-bottom & { width: auto; flex-direction: row; flex-wrap: wrap; diff --git a/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.test.tsx b/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.test.tsx index 65d148cfc5ef4..a3fb536d0aec5 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.test.tsx +++ b/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.test.tsx @@ -41,16 +41,8 @@ jest.mock('../../../services', () => ({ }), })); -const vis = { - params: { - addLegend: true, - }, - API: { - events: { - filter: jest.fn(), - }, - }, -}; +const fireEvent = jest.fn(); + const vislibVis = { handler: { highlight: jest.fn(), @@ -96,14 +88,15 @@ const uiState = { set: jest.fn().mockImplementation((key, value) => mockState.set(key, value)), emit: jest.fn(), setSilent: jest.fn(), -}; +} as any; const getWrapper = async (props?: Partial) => { const wrapper = mount( { }); it('should work with no handlers set', () => { - const newVis = { - ...vis, + const newProps = { vislibVis: { ...vislibVis, handler: null, @@ -197,7 +189,7 @@ describe('VisLegend Component', () => { }; expect(async () => { - wrapper = await getWrapper({ vis: newVis }); + wrapper = await getWrapper(newProps); const first = getLegendItems(wrapper).first(); first.simulate('focus'); first.simulate('blur'); @@ -216,8 +208,11 @@ describe('VisLegend Component', () => { const filterGroup = wrapper.find(EuiButtonGroup).first(); filterGroup.getElement().props.onChange('filterIn'); - expect(vis.API.events.filter).toHaveBeenCalledWith({ data: ['valuesA'], negate: false }); - expect(vis.API.events.filter).toHaveBeenCalledTimes(1); + expect(fireEvent).toHaveBeenCalledWith({ + name: 'filterBucket', + data: { data: ['valuesA'], negate: false }, + }); + expect(fireEvent).toHaveBeenCalledTimes(1); }); it('should filter in when clicked', () => { @@ -226,8 +221,11 @@ describe('VisLegend Component', () => { const filterGroup = wrapper.find(EuiButtonGroup).first(); filterGroup.getElement().props.onChange('filterOut'); - expect(vis.API.events.filter).toHaveBeenCalledWith({ data: ['valuesA'], negate: true }); - expect(vis.API.events.filter).toHaveBeenCalledTimes(1); + expect(fireEvent).toHaveBeenCalledWith({ + name: 'filterBucket', + data: { data: ['valuesA'], negate: true }, + }); + expect(fireEvent).toHaveBeenCalledTimes(1); }); }); diff --git a/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx b/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx index 5a2db2d21c6fe..cec97f0cadf11 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx +++ b/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx @@ -23,16 +23,21 @@ import { compact, uniqBy, map, every, isUndefined } from 'lodash'; import { i18n } from '@kbn/i18n'; import { EuiPopoverProps, EuiIcon, keys, htmlIdGenerator } from '@elastic/eui'; +import { PersistedState } from '../../../../../visualizations/public'; +import { IInterpreterRenderHandlers } from '../../../../../expressions/public'; + import { getDataActions } from '../../../services'; import { CUSTOM_LEGEND_VIS_TYPES, LegendItem } from './models'; import { VisLegendItem } from './legend_item'; import { getPieNames } from './pie_utils'; +import { BasicVislibParams } from '../../../types'; export interface VisLegendProps { - vis: any; vislibVis: any; - visData: any; - uiState: any; + visData: unknown; + uiState?: PersistedState; + fireEvent: IInterpreterRenderHandlers['event']; + addLegend: BasicVislibParams['addLegend']; position: 'top' | 'bottom' | 'left' | 'right'; } @@ -49,7 +54,10 @@ export class VisLegend extends PureComponent { constructor(props: VisLegendProps) { super(props); - const open = props.uiState.get('vis.legendOpen', true); + + // TODO: Check when this bwc can safely be removed + const bwcLegendStateDefault = props.addLegend ?? true; + const open = props.uiState?.get('vis.legendOpen', bwcLegendStateDefault) as boolean; this.state = { open, @@ -64,13 +72,9 @@ export class VisLegend extends PureComponent { } toggleLegend = () => { - const bwcAddLegend = this.props.vis.params.addLegend; - const bwcLegendStateDefault = bwcAddLegend == null ? true : bwcAddLegend; - const newOpen = !this.props.uiState.get('vis.legendOpen', bwcLegendStateDefault); - this.setState({ open: newOpen }); - // open should be applied on template before we update uiState - setTimeout(() => { - this.props.uiState.set('vis.legendOpen', newOpen); + const newOpen = !this.state.open; + this.setState({ open: newOpen }, () => { + this.props.uiState?.set('vis.legendOpen', newOpen); }); }; @@ -79,17 +83,23 @@ export class VisLegend extends PureComponent { return; } - const colors = this.props.uiState.get('vis.colors') || {}; + const colors = this.props.uiState?.get('vis.colors') || {}; if (colors[label] === color) delete colors[label]; else colors[label] = color; - this.props.uiState.setSilent('vis.colors', null); - this.props.uiState.set('vis.colors', colors); - this.props.uiState.emit('colorChanged'); + this.props.uiState?.setSilent('vis.colors', null); + this.props.uiState?.set('vis.colors', colors); + this.props.uiState?.emit('colorChanged'); this.refresh(); }; filter = ({ values: data }: LegendItem, negate: boolean) => { - this.props.vis.API.events.filter({ data, negate }); + this.props.fireEvent({ + name: 'filterBucket', + data: { + data, + negate, + }, + }); }; canFilter = async (item: LegendItem): Promise => { @@ -172,11 +182,8 @@ export class VisLegend extends PureComponent { return; } // make sure vislib is defined at this point - if ( - this.props.uiState.get('vis.legendOpen') == null && - this.props.vis.params.addLegend != null - ) { - this.setState({ open: this.props.vis.params.addLegend }); + if (this.props.uiState?.get('vis.legendOpen') == null && this.props.addLegend != null) { + this.setState({ open: this.props.addLegend }); } if (vislibVis.visConfig) { diff --git a/src/plugins/vis_type_vislib/public/vislib/helpers/point_series/_init_x_axis.ts b/src/plugins/vis_type_vislib/public/vislib/helpers/point_series/_init_x_axis.ts index 32536960c59cd..147bae7e3b985 100644 --- a/src/plugins/vis_type_vislib/public/vislib/helpers/point_series/_init_x_axis.ts +++ b/src/plugins/vis_type_vislib/public/vislib/helpers/point_series/_init_x_axis.ts @@ -33,11 +33,11 @@ export function initXAxis(chart: Chart, table: Table) { chart.xAxisLabel = title; if ('interval' in params) { - const { interval } = params; if ('date' in params) { const { intervalESUnit, intervalESValue } = params; + chart.ordered = { - interval: moment.duration(interval), + interval: moment.duration(intervalESValue, intervalESUnit as any), intervalESUnit, intervalESValue, }; diff --git a/src/plugins/vis_type_vislib/public/vislib/helpers/point_series/point_series.ts b/src/plugins/vis_type_vislib/public/vislib/helpers/point_series/point_series.ts index 4ba3101d34898..f40d01e6a8123 100644 --- a/src/plugins/vis_type_vislib/public/vislib/helpers/point_series/point_series.ts +++ b/src/plugins/vis_type_vislib/public/vislib/helpers/point_series/point_series.ts @@ -28,7 +28,7 @@ import { Column, Table } from '../../types'; export interface DateHistogramParams { date: boolean; - interval: string; + interval: number | string; intervalESValue: number; intervalESUnit: string; format: string; @@ -57,6 +57,9 @@ export interface Dimensions { y: Dimension[]; z?: Dimension[]; series?: Dimension | Dimension[]; + width?: Dimension[]; + splitRow?: Dimension[]; + splitColumn?: Dimension[]; } export interface Aspect { accessor: Column['id']; diff --git a/src/plugins/vis_type_vislib/public/vislib/lib/_handler.scss b/src/plugins/vis_type_vislib/public/vislib/lib/_handler.scss deleted file mode 100644 index d1c7fc7c6278c..0000000000000 --- a/src/plugins/vis_type_vislib/public/vislib/lib/_handler.scss +++ /dev/null @@ -1,17 +0,0 @@ -.visError { - flex: 1 1 0; - display: flex; - align-items: center; - justify-content: center; - text-align: center; - - // From ML - .top { align-self: flex-start; } - .bottom { align-self: flex-end; } -} - -// Prevent large request errors from overflowing the container -.visError--request { - max-width: 100%; - max-height: 100%; -} diff --git a/src/plugins/vis_type_vislib/public/vislib/lib/_index.scss b/src/plugins/vis_type_vislib/public/vislib/lib/_index.scss index b19c2dfb153b9..6751e9f28a8ee 100644 --- a/src/plugins/vis_type_vislib/public/vislib/lib/_index.scss +++ b/src/plugins/vis_type_vislib/public/vislib/lib/_index.scss @@ -1,4 +1,3 @@ @import './alerts'; -@import './handler'; @import './layout/index'; diff --git a/src/plugins/vis_type_vislib/public/vislib/lib/dispatch.js b/src/plugins/vis_type_vislib/public/vislib/lib/dispatch.js index 4c50472b9d11a..16283c6bddf26 100644 --- a/src/plugins/vis_type_vislib/public/vislib/lib/dispatch.js +++ b/src/plugins/vis_type_vislib/public/vislib/lib/dispatch.js @@ -182,7 +182,6 @@ export class Dispatch { const data = d.input || d; return { - e: d3.event, data: isSlices ? this._pieClickResponse(data) : this._seriesClickResponse(data), }; } @@ -423,7 +422,6 @@ export class Dispatch { */ createBrush(xScale, svg) { const self = this; - const visConfig = self.handler.visConfig; const { width, height } = svg.node().getBBox(); const isHorizontal = self.handler.categoryAxes[0].axisConfig.isHorizontal(); @@ -449,8 +447,6 @@ export class Dispatch { return self.emit('brush', { range, - config: visConfig, - e: d3.event, data, }); }); diff --git a/src/plugins/vis_type_vislib/public/vislib/lib/handler.js b/src/plugins/vis_type_vislib/public/vislib/lib/handler.js index 3c1aeaa0d1d0d..938ea3adcb9b5 100644 --- a/src/plugins/vis_type_vislib/public/vislib/lib/handler.js +++ b/src/plugins/vis_type_vislib/public/vislib/lib/handler.js @@ -46,10 +46,10 @@ const markdownIt = new MarkdownIt({ * create the visualization */ export class Handler { - constructor(vis, visConfig, deps) { + constructor(vis, visConfig, uiSettings) { this.el = visConfig.get('el'); this.ChartClass = chartTypes[visConfig.get('type')]; - this.deps = deps; + this.uiSettings = uiSettings; this.charts = []; this.vis = vis; @@ -91,12 +91,18 @@ export class Handler { const xRaw = _.get(eventPayload.data, 'series[0].values[0].xRaw'); if (!xRaw) return; // not sure if this is possible? return self.vis.emit(eventType, { - table: xRaw.table, - range: eventPayload.range, - column: xRaw.column, + name: 'brush', + data: { + table: xRaw.table, + range: eventPayload.range, + column: xRaw.column, + }, }); case 'click': - return self.vis.emit(eventType, eventPayload); + return self.vis.emit(eventType, { + name: 'filterBucket', + data: eventPayload, + }); } }; }); @@ -164,7 +170,7 @@ export class Handler { let loadedCount = 0; const chartSelection = selection.selectAll('.chart'); chartSelection.each(function (chartData) { - const chart = new self.ChartClass(self, this, chartData, self.deps); + const chart = new self.ChartClass(self, this, chartData, self.uiSettings); self.vis.eventNames().forEach(function (event) { self.enable(event, chart); @@ -222,7 +228,7 @@ export class Handler { // class name needs `chart` in it for the polling checkSize function // to continuously call render on resize .attr('class', 'visError chart error') - .attr('data-test-subj', 'visLibVisualizeError'); + .attr('data-test-subj', 'vislibVisualizeError'); div.append('h4').text(markdownIt.renderInline(message)); diff --git a/src/plugins/vis_type_vislib/public/vislib/lib/handler.test.js b/src/plugins/vis_type_vislib/public/vislib/lib/handler.test.js index d50c70de1bb48..119a24d2f25d1 100644 --- a/src/plugins/vis_type_vislib/public/vislib/lib/handler.test.js +++ b/src/plugins/vis_type_vislib/public/vislib/lib/handler.test.js @@ -157,7 +157,7 @@ dateHistogramArray.forEach(function (data, i) { const args = Array.from(arguments); expect(args.length).toBe(2); expect(args[0]).toBe('click'); - expect(args[1]).toBe(event); + expect(args[1].data).toBe(event); done(); }; diff --git a/src/plugins/vis_type_vislib/public/vislib/lib/vis_config.js b/src/plugins/vis_type_vislib/public/vislib/lib/vis_config.js index dda9d85ec43c5..2086f744be584 100644 --- a/src/plugins/vis_type_vislib/public/vislib/lib/vis_config.js +++ b/src/plugins/vis_type_vislib/public/vislib/lib/vis_config.js @@ -50,7 +50,6 @@ export class VisConfig { return _.get(this._values, property, defaults); } else { throw new Error(`Accessing invalid config property: ${property}`); - return defaults; } } diff --git a/src/plugins/vis_type_vislib/public/vislib/vis.js b/src/plugins/vis_type_vislib/public/vislib/vis.js index f258cb55ba281..628b876fc50c5 100644 --- a/src/plugins/vis_type_vislib/public/vislib/vis.js +++ b/src/plugins/vis_type_vislib/public/vislib/vis.js @@ -35,13 +35,14 @@ import { DIMMING_OPACITY_SETTING, HEATMAP_MAX_BUCKETS_SETTING } from '../../comm * @param config {Object} Parameters that define the chart type and chart options */ export class Vis extends EventEmitter { - constructor(element, visConfigArgs, deps) { + constructor(element, visConfigArgs, core, charts) { super(); this.element = element.get ? element.get(0) : element; this.visConfigArgs = _.cloneDeep(visConfigArgs); - this.visConfigArgs.dimmingOpacity = deps.uiSettings.get(DIMMING_OPACITY_SETTING); - this.visConfigArgs.heatmapMaxBuckets = deps.uiSettings.get(HEATMAP_MAX_BUCKETS_SETTING); - this.deps = deps; + this.visConfigArgs.dimmingOpacity = core.uiSettings.get(DIMMING_OPACITY_SETTING); + this.visConfigArgs.heatmapMaxBuckets = core.uiSettings.get(HEATMAP_MAX_BUCKETS_SETTING); + this.charts = charts; + this.uiSettings = core.uiSettings; } hasLegend() { @@ -56,7 +57,7 @@ export class Vis extends EventEmitter { this.data, this.uiState, this.element, - this.deps.charts.colors.createColorLookupFunction.bind(this.deps.charts.colors) + this.charts.colors.createColorLookupFunction.bind(this.charts.colors) ); } @@ -78,7 +79,7 @@ export class Vis extends EventEmitter { this.initVisConfig(data, uiState); - this.handler = new Handler(this, this.visConfig, this.deps); + this.handler = new Handler(this, this.visConfig, this.uiSettings); this._runOnHandler('render'); } diff --git a/src/plugins/vis_type_vislib/public/vislib/visualizations/_chart.js b/src/plugins/vis_type_vislib/public/vislib/visualizations/_chart.js index 5ed6d3eb79f4b..e5cb0235b6510 100644 --- a/src/plugins/vis_type_vislib/public/vislib/visualizations/_chart.js +++ b/src/plugins/vis_type_vislib/public/vislib/visualizations/_chart.js @@ -39,13 +39,13 @@ import { * @param chartData {Object} Elasticsearch query results for this specific chart */ export class Chart { - constructor(handler, element, chartData, deps) { + constructor(handler, element, chartData, uiSettings) { this.handler = handler; this.chartEl = element; this.chartData = chartData; this.tooltips = []; - const events = (this.events = new Dispatch(handler, deps.uiSettings)); + const events = (this.events = new Dispatch(handler, uiSettings)); const fieldFormatter = getFormatService().deserialize( this.handler.data.get('tooltipFormatter') diff --git a/src/plugins/vis_type_vislib/public/vislib/visualizations/_vis_fixture.js b/src/plugins/vis_type_vislib/public/vislib/visualizations/_vis_fixture.js index 0ffa53fc7ca9c..11b5964eebdf3 100644 --- a/src/plugins/vis_type_vislib/public/vislib/visualizations/_vis_fixture.js +++ b/src/plugins/vis_type_vislib/public/vislib/visualizations/_vis_fixture.js @@ -53,20 +53,10 @@ afterEach(function () { count = 0; }); -const getDeps = () => { - const mockUiSettings = coreMock.createSetup().uiSettings; - const charts = chartPluginMock.createStartContract(); - - return { - uiSettings: mockUiSettings, - charts: charts, - }; -}; - -export function getVis(visLibParams, element) { +export function getVis(vislibParams, element) { return new Vis( element || $visCanvas.new(), - _.defaults({}, visLibParams || {}, { + _.defaults({}, vislibParams || {}, { addTooltip: true, addLegend: true, defaultYExtents: false, @@ -74,6 +64,7 @@ export function getVis(visLibParams, element) { yAxis: {}, type: 'histogram', }), - getDeps() + coreMock.createSetup(), + chartPluginMock.createStartContract() ); } diff --git a/src/plugins/vis_type_vislib/public/vislib/visualizations/gauge_chart.test.js b/src/plugins/vis_type_vislib/public/vislib/visualizations/gauge_chart.test.js index 6fdc2a134b820..913b237a10e58 100644 --- a/src/plugins/vis_type_vislib/public/vislib/visualizations/gauge_chart.test.js +++ b/src/plugins/vis_type_vislib/public/vislib/visualizations/gauge_chart.test.js @@ -28,7 +28,7 @@ import { getVis } from './_vis_fixture'; describe('Vislib Gauge Chart Test Suite', function () { let vis; let chartEl; - const visLibParams = { + const vislibParams = { type: 'gauge', addTooltip: true, addLegend: false, @@ -71,7 +71,7 @@ describe('Vislib Gauge Chart Test Suite', function () { }; function generateVis(opts = {}) { - const config = _.defaultsDeep({}, opts, visLibParams); + const config = _.defaultsDeep({}, opts, vislibParams); if (vis) { vis.destroy(); $('.visChart').remove(); diff --git a/src/plugins/vis_type_vislib/public/vislib/visualizations/pie_chart.js b/src/plugins/vis_type_vislib/public/vislib/visualizations/pie_chart.js index 938d3d0ec6d74..b1acea34aabf6 100644 --- a/src/plugins/vis_type_vislib/public/vislib/visualizations/pie_chart.js +++ b/src/plugins/vis_type_vislib/public/vislib/visualizations/pie_chart.js @@ -42,8 +42,8 @@ const defaults = { * @param chartData {Object} Elasticsearch query results for this specific chart */ export class PieChart extends Chart { - constructor(handler, chartEl, chartData, deps) { - super(handler, chartEl, chartData, deps); + constructor(handler, chartEl, chartData, uiSettings) { + super(handler, chartEl, chartData, uiSettings); const charts = this.handler.data.getVisData(); this._validatePieData(charts); this._attr = _.defaults(handler.visConfig.get('chart', {}), defaults); diff --git a/src/plugins/vis_type_vislib/public/vislib/visualizations/pie_chart.test.js b/src/plugins/vis_type_vislib/public/vislib/visualizations/pie_chart.test.js index e2da33d0808ba..1207db2e54bb8 100644 --- a/src/plugins/vis_type_vislib/public/vislib/visualizations/pie_chart.test.js +++ b/src/plugins/vis_type_vislib/public/vislib/visualizations/pie_chart.test.js @@ -40,7 +40,7 @@ let mockedSVGElementGetBBox; let mockedSVGElementGetComputedTextLength; describe('No global chart settings', function () { - const visLibParams1 = { + const vislibParams1 = { el: '
', type: 'pie', addLegend: true, @@ -58,7 +58,7 @@ describe('No global chart settings', function () { }); beforeEach(() => { - chart1 = getVis(visLibParams1); + chart1 = getVis(vislibParams1); mockUiState = getMockUiState(); }); @@ -153,7 +153,7 @@ describe('Vislib PieChart Class Test Suite', function () { describe('Vislib PieChart Class Test Suite for ' + names[i] + ' data', function () { const mockPieData = pieChartMockData[aggItem]; - const visLibParams = { + const vislibParams = { type: 'pie', addLegend: true, addTooltip: true, @@ -161,7 +161,7 @@ describe('Vislib PieChart Class Test Suite', function () { let vis; beforeEach(async () => { - vis = getVis(visLibParams); + vis = getVis(vislibParams); const mockUiState = getMockUiState(); vis.render(mockPieData, mockUiState); }); diff --git a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series.js b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series.js index 9a25d041f6567..a40d46737f05e 100644 --- a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series.js +++ b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series.js @@ -40,10 +40,10 @@ const touchdownTmpl = _.template(touchdownTmplHtml); * @param chartData {Object} Elasticsearch query results for this specific chart */ export class PointSeries extends Chart { - constructor(handler, chartEl, chartData, deps) { - super(handler, chartEl, chartData, deps); + constructor(handler, chartEl, chartData, uiSettings) { + super(handler, chartEl, chartData, uiSettings); - this.deps = deps; + this.uiSettings = uiSettings; this.handler = handler; this.chartData = chartData; this.chartEl = chartEl; @@ -246,7 +246,13 @@ export class PointSeries extends Chart { if (!seriArgs.show) return; const SeriClass = seriTypes[seriArgs.type || self.handler.visConfig.get('chart.type')] || seriTypes.line; - const series = new SeriClass(self.handler, svg, data.series[i], seriArgs, self.deps); + const series = new SeriClass( + self.handler, + svg, + data.series[i], + seriArgs, + self.uiSettings + ); series.events = self.events; svg.call(series.draw()); self.series.push(series); diff --git a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/area_chart.js b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/area_chart.js index e3e2d31ecd4f4..b65c5be330fef 100644 --- a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/area_chart.js +++ b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/area_chart.js @@ -43,8 +43,8 @@ const defaults = { * chart */ export class AreaChart extends PointSeries { - constructor(handler, chartEl, chartData, seriesConfigArgs, deps) { - super(handler, chartEl, chartData, seriesConfigArgs, deps); + constructor(handler, chartEl, chartData, seriesConfigArgs, core) { + super(handler, chartEl, chartData, seriesConfigArgs, core); this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults); this.isOverlapping = this.seriesConfig.mode !== 'stacked'; diff --git a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/area_chart.test.js b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/area_chart.test.js index 3cd58060978ee..ae15d95d560ca 100644 --- a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/area_chart.test.js +++ b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/area_chart.test.js @@ -38,7 +38,7 @@ const dataTypesArray = { stackedSeries: import('../../../fixtures/mock_data/date_histogram/_stacked_series'), }; -const visLibParams = { +const vislibParams = { type: 'area', addLegend: true, addTooltip: true, @@ -61,7 +61,7 @@ _.forOwn(dataTypesArray, function (dataType, dataTypeName) { }); beforeEach(async () => { - vis = getVis(visLibParams); + vis = getVis(vislibParams); mockUiState = getMockUiState(); vis.on('brush', _.noop); vis.render(await dataType, mockUiState); diff --git a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/column_chart.js b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/column_chart.js index 1369bf1dff68a..07bebf4eb2f83 100644 --- a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/column_chart.js +++ b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/column_chart.js @@ -57,8 +57,8 @@ function datumWidth(defaultWidth, datum, nextDatum, scale, gutterWidth, groupCou * @param chartData {Object} Elasticsearch query results for this specific chart */ export class ColumnChart extends PointSeries { - constructor(handler, chartEl, chartData, seriesConfigArgs, deps) { - super(handler, chartEl, chartData, seriesConfigArgs, deps); + constructor(handler, chartEl, chartData, seriesConfigArgs, core) { + super(handler, chartEl, chartData, seriesConfigArgs, core); this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults); this.labelOptions = _.defaults(handler.visConfig.get('labels', {}), defaults.showLabel); } diff --git a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/column_chart.test.js b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/column_chart.test.js index f3d8d66df2d85..d7fc177a30009 100644 --- a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/column_chart.test.js +++ b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/column_chart.test.js @@ -62,7 +62,7 @@ dataTypesArray.forEach(function (dataType) { describe('Vislib Column Chart Test Suite for ' + name + ' Data', function () { let vis; let mockUiState; - const visLibParams = { + const vislibParams = { type: 'histogram', addLegend: true, addTooltip: true, @@ -81,7 +81,7 @@ dataTypesArray.forEach(function (dataType) { }); beforeEach(() => { - vis = getVis(visLibParams); + vis = getVis(vislibParams); mockUiState = getMockUiState(); vis.on('brush', _.noop); vis.render(data, mockUiState); @@ -261,7 +261,7 @@ dataTypesArray.forEach(function (dataType) { describe('stackData method - data set with zeros in percentage mode', function () { let vis; let mockUiState; - const visLibParams = { + const vislibParams = { type: 'histogram', addLegend: true, addTooltip: true, @@ -276,7 +276,7 @@ describe('stackData method - data set with zeros in percentage mode', function ( }); beforeEach(() => { - vis = getVis(visLibParams); + vis = getVis(vislibParams); mockUiState = getMockUiState(); vis.on('brush', _.noop); }); @@ -320,7 +320,7 @@ describe('stackData method - data set with zeros in percentage mode', function ( describe('datumWidth - split chart data set with holes', function () { let vis; let mockUiState; - const visLibParams = { + const vislibParams = { type: 'histogram', addLegend: true, addTooltip: true, @@ -335,7 +335,7 @@ describe('datumWidth - split chart data set with holes', function () { }); beforeEach(() => { - vis = getVis(visLibParams); + vis = getVis(vislibParams); mockUiState = getMockUiState(); vis.on('brush', _.noop); vis.render(rowsSeriesWithHoles, mockUiState); @@ -366,7 +366,7 @@ describe('datumWidth - split chart data set with holes', function () { describe('datumWidth - monthly interval', function () { let vis; let mockUiState; - const visLibParams = { + const vislibParams = { type: 'histogram', addLegend: true, addTooltip: true, @@ -384,7 +384,7 @@ describe('datumWidth - monthly interval', function () { }); beforeEach(() => { - vis = getVis(visLibParams); + vis = getVis(vislibParams); mockUiState = getMockUiState(); vis.on('brush', _.noop); vis.render(seriesMonthlyInterval, mockUiState); diff --git a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/heatmap_chart.test.js b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/heatmap_chart.test.js index 8c727d225c6c3..a7534add76e36 100644 --- a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/heatmap_chart.test.js +++ b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/heatmap_chart.test.js @@ -71,7 +71,7 @@ describe('Vislib Heatmap Chart Test Suite', function () { describe('for ' + name + ' Data', function () { let vis; let mockUiState; - const visLibParams = { + const vislibParams = { type: 'heatmap', addLegend: true, addTooltip: true, @@ -84,7 +84,7 @@ describe('Vislib Heatmap Chart Test Suite', function () { }; function generateVis(opts = {}) { - const config = _.defaultsDeep({}, opts, visLibParams); + const config = _.defaultsDeep({}, opts, vislibParams); vis = getVis(config); mockUiState = getMockUiState(); vis.on('brush', _.noop); diff --git a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/line_chart.js b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/line_chart.js index 64fbae7d1ac8c..983c15c004b97 100644 --- a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/line_chart.js +++ b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/line_chart.js @@ -42,8 +42,8 @@ const defaults = { * @param chartData {Object} Elasticsearch query results for this specific chart */ export class LineChart extends PointSeries { - constructor(handler, chartEl, chartData, seriesConfigArgs, deps) { - super(handler, chartEl, chartData, seriesConfigArgs, deps); + constructor(handler, chartEl, chartData, seriesConfigArgs, core) { + super(handler, chartEl, chartData, seriesConfigArgs, core); this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults); } diff --git a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/line_chart.test.js b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/line_chart.test.js index a84c74c095051..8d86df7c27da4 100644 --- a/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/line_chart.test.js +++ b/src/plugins/vis_type_vislib/public/vislib/visualizations/point_series/line_chart.test.js @@ -71,14 +71,14 @@ describe('Vislib Line Chart', function () { let mockUiState; beforeEach(() => { - const visLibParams = { + const vislibParams = { type: 'line', addLegend: true, addTooltip: true, drawLinesBetweenPoints: true, }; - vis = getVis(visLibParams); + vis = getVis(vislibParams); mockUiState = getMockUiState(); vis.render(data, mockUiState); vis.on('brush', _.noop); diff --git a/src/plugins/visualizations/public/components/_visualization.scss b/src/plugins/visualizations/public/components/_visualization.scss index f5e2d4fcf2862..bde9621fd70b8 100644 --- a/src/plugins/visualizations/public/components/_visualization.scss +++ b/src/plugins/visualizations/public/components/_visualization.scss @@ -70,10 +70,10 @@ flex-direction: column; } -.visChart__spinner { +.visChart__spinner, .visError { display: flex; flex: 1 1 auto; justify-content: center; align-items: center; + text-align: center; } - diff --git a/src/plugins/visualizations/public/index.ts b/src/plugins/visualizations/public/index.ts index 081399fd1fbea..7bd4466b23166 100644 --- a/src/plugins/visualizations/public/index.ts +++ b/src/plugins/visualizations/public/index.ts @@ -52,6 +52,7 @@ export { ISavedVis, VisSavedObject, VisResponseValue, + VisToExpressionAst, } from './types'; export { ExprVisAPIEvents } from './expressions/vis'; export { VisualizationListItem } from './vis_types/vis_type_alias_registry'; diff --git a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap index 959d9031853af..2c6cfc6fb7462 100644 --- a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap +++ b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap @@ -6,8 +6,6 @@ exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunct exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles metrics/tsvb function 1`] = `"tsvb params='{\\"foo\\":\\"bar\\"}' uiState='{}' "`; -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles pie function 1`] = `"kibana_pie visConfig='{\\"dimensions\\":{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},\\"buckets\\":[1,2]}}' "`; - exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles region_map function with buckets 1`] = `"regionmap visConfig='{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},\\"bucket\\":1}' "`; exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles region_map function without buckets 1`] = `"regionmap visConfig='{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"}}' "`; diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts index 501a69080d93f..0c210a04d2007 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts @@ -21,14 +21,12 @@ import { prepareJson, prepareString, buildPipelineVisFunction, - buildVislibDimensions, buildPipeline, SchemaConfig, Schemas, } from './build_pipeline'; import { Vis } from '..'; import { dataPluginMock } from '../../../../plugins/data/public/mocks'; -import { IndexPattern, IAggConfigs } from '../../../../plugins/data/public'; import { parseExpression } from '../../../expressions/common'; describe('visualize loader pipeline helpers: build pipeline', () => { @@ -136,15 +134,6 @@ describe('visualize loader pipeline helpers: build pipeline', () => { const actual = buildPipelineVisFunction.tile_map(params, schemas, uiState); expect(actual).toMatchSnapshot(); }); - - it('handles pie function', () => { - const schemas = { - ...schemasDef, - segment: [1, 2], - }; - const actual = buildPipelineVisFunction.pie({}, schemas, uiState); - expect(actual).toMatchSnapshot(); - }); }); describe('buildPipeline', () => { @@ -174,157 +163,4 @@ describe('visualize loader pipeline helpers: build pipeline', () => { expect(expression).toMatchSnapshot(); }); }); - - describe('buildVislibDimensions', () => { - const dataStart = dataPluginMock.createStartContract(); - - let aggs: IAggConfigs; - let vis: Vis; - let params: any; - - beforeEach(() => { - aggs = dataStart.search.aggs.createAggConfigs({} as IndexPattern, [ - { - id: '0', - enabled: true, - type: 'count', - schema: 'metric', - params: {}, - }, - ]); - - params = { - searchSource: null, - timefilter: dataStart.query.timefilter.timefilter, - timeRange: null, - }; - }); - - describe('test y dimension format for histogram chart', () => { - beforeEach(() => { - vis = { - // @ts-ignore - type: { - name: 'histogram', - }, - params: { - seriesParams: [ - { - data: { id: '0' }, - valueAxis: 'axis-y', - }, - ], - valueAxes: [ - { - id: 'axis-y', - scale: { - mode: 'normal', - }, - }, - ], - }, - data: { - aggs, - searchSource: {} as any, - }, - isHierarchical: () => { - return false; - }, - }; - }); - - it('with one numeric metric in regular moder', async () => { - const dimensions = await buildVislibDimensions(vis, params); - const expected = { id: 'number' }; - const actual = dimensions.y[0].format; - expect(actual).toEqual(expected); - }); - - it('with one numeric metric in percentage mode', async () => { - vis.params.valueAxes[0].scale.mode = 'percentage'; - const dimensions = await buildVislibDimensions(vis, params); - const expected = { id: 'percent' }; - const actual = dimensions.y[0].format; - expect(actual).toEqual(expected); - }); - - it('with two numeric metrics, mixed normal and percent mode should have corresponding formatters', async () => { - aggs.createAggConfig({ - id: '5', - enabled: true, - type: 'count', - schema: 'metric', - params: {}, - }); - - vis.params = { - seriesParams: [ - { - data: { id: '0' }, - valueAxis: 'axis-y-1', - }, - { - data: { id: '5' }, - valueAxis: 'axis-y-2', - }, - ], - valueAxes: [ - { - id: 'axis-y-1', - scale: { - mode: 'normal', - }, - }, - { - id: 'axis-y-2', - scale: { - mode: 'percentage', - }, - }, - ], - }; - - const dimensions = await buildVislibDimensions(vis, params); - const expectedY1 = { id: 'number' }; - const expectedY2 = { id: 'percent' }; - expect(dimensions.y[0].format).toEqual(expectedY1); - expect(dimensions.y[1].format).toEqual(expectedY2); - }); - }); - - describe('test y dimension format for gauge chart', () => { - beforeEach(() => { - vis = { - // @ts-ignore - type: { - name: 'gauge', - }, - params: { gauge: {} }, - data: { - aggs, - searchSource: {} as any, - }, - isHierarchical: () => { - return false; - }, - }; - }); - - it('with percentageMode = false', async () => { - vis.params.gauge.percentageMode = false; - const dimensions = await buildVislibDimensions(vis, params); - const expected = { id: 'number' }; - const actual = dimensions.y[0].format; - expect(actual).toEqual(expected); - }); - - it('with percentageMode = true', async () => { - vis.params.gauge.percentageMode = true; - const dimensions = await buildVislibDimensions(vis, params); - const expected = { id: 'percent' }; - const actual = dimensions.y[0].format; - expect(actual).toEqual(expected); - }); - }); - }); }); diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.ts b/src/plugins/visualizations/public/legacy/build_pipeline.ts index b08583c376b36..3593d62b9d2e6 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.ts @@ -17,8 +17,6 @@ * under the License. */ -import { get } from 'lodash'; -import moment from 'moment'; import { formatExpression, SerializedFieldFormat } from '../../../../plugins/expressions/public'; import { IAggConfig, search, TimefilterContract } from '../../../../plugins/data/public'; import { Vis, VisParams } from '../types'; @@ -76,16 +74,6 @@ export interface BuildPipelineParams { abortSignal?: AbortSignal; } -const vislibCharts: string[] = [ - 'area', - 'gauge', - 'goal', - 'heatmap', - 'histogram', - 'horizontal_bar', - 'line', -]; - export const getSchemas = ( vis: Vis, { timeRange, timefilter }: BuildPipelineParams @@ -230,29 +218,6 @@ export const prepareDimension = (variable: string, data: any) => { return expr; }; -const adjustVislibDimensionFormmaters = (vis: Vis, dimensions: { y: any[] }): void => { - const visConfig = vis.params; - const responseAggs = vis.data.aggs!.getResponseAggs().filter((agg: IAggConfig) => agg.enabled); - - (dimensions.y || []).forEach((yDimension) => { - const yAgg = responseAggs[yDimension.accessor]; - const seriesParam = (visConfig.seriesParams || []).find( - (param: any) => param.data.id === yAgg.id - ); - if (seriesParam) { - const usedValueAxis = (visConfig.valueAxes || []).find( - (valueAxis: any) => valueAxis.id === seriesParam.valueAxis - ); - if (get(usedValueAxis, 'scale.mode') === 'percentage') { - yDimension.format = { id: 'percent' }; - } - } - if (get(visConfig, 'gauge.percentageMode') === true) { - yDimension.format = { id: 'percent' }; - } - }); -}; - export const buildPipelineVisFunction: BuildPipelineVisFunction = { input_control_vis: (params) => { return `input_control_vis ${prepareJson('visConfig', params)}`; @@ -278,13 +243,6 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { }; return `tilemap ${prepareJson('visConfig', visConfig)}`; }, - pie: (params, schemas) => { - const visConfig = { - ...params, - ...buildVisConfig.pie(schemas), - }; - return `kibana_pie ${prepareJson('visConfig', visConfig)}`; - }, }; const buildVisConfig: BuildVisConfigFunction = { @@ -305,55 +263,6 @@ const buildVisConfig: BuildVisConfigFunction = { }; return visConfig; }, - pie: (schemas) => { - const visConfig = {} as any; - visConfig.dimensions = { - metric: schemas.metric[0], - buckets: schemas.segment, - splitRow: schemas.split_row, - splitColumn: schemas.split_column, - }; - return visConfig; - }, -}; - -export const buildVislibDimensions = async (vis: any, params: BuildPipelineParams) => { - const schemas = getSchemas(vis, { - timeRange: params.timeRange, - timefilter: params.timefilter, - }); - const dimensions = { - x: schemas.segment ? schemas.segment[0] : null, - y: schemas.metric, - z: schemas.radius, - width: schemas.width, - series: schemas.group, - splitRow: schemas.split_row, - splitColumn: schemas.split_column, - }; - if (schemas.segment) { - const xAgg = vis.data.aggs.getResponseAggs()[dimensions.x.accessor]; - if (xAgg.type.name === 'date_histogram') { - dimensions.x.params.date = true; - const { esUnit, esValue } = xAgg.buckets.getInterval(); - dimensions.x.params.interval = moment.duration(esValue, esUnit); - dimensions.x.params.intervalESValue = esValue; - dimensions.x.params.intervalESUnit = esUnit; - dimensions.x.params.format = xAgg.buckets.getScaledDateFormat(); - dimensions.x.params.bounds = xAgg.buckets.getBounds(); - } else if (xAgg.type.name === 'histogram') { - const intervalParam = xAgg.type.paramByName('interval'); - const output = { params: {} as any }; - await intervalParam.modifyAggConfigOnSearchRequestStart(xAgg, vis.data.searchSource, { - abortSignal: params.abortSignal, - }); - intervalParam.write(xAgg, output); - dimensions.x.params.interval = output.params.interval; - } - } - - adjustVislibDimensionFormmaters(vis, dimensions); - return dimensions; }; export const buildPipeline = async (vis: Vis, params: BuildPipelineParams) => { @@ -396,11 +305,6 @@ export const buildPipeline = async (vis: Vis, params: BuildPipelineParams) => { schemas, uiState ); - } else if (vislibCharts.includes(vis.type.name)) { - const visConfig = { ...vis.params }; - visConfig.dimensions = await buildVislibDimensions(vis, params); - - pipeline += `vislib type='${vis.type.name}' ${prepareJson('visConfig', visConfig)}`; } else { const visConfig = { ...vis.params }; visConfig.dimensions = schemas; diff --git a/src/plugins/visualizations/public/types.ts b/src/plugins/visualizations/public/types.ts index 68ab3561d375c..3c322f5e79165 100644 --- a/src/plugins/visualizations/public/types.ts +++ b/src/plugins/visualizations/public/types.ts @@ -76,4 +76,4 @@ export interface VisToExpressionAstParams { export type VisToExpressionAst = ( vis: Vis, params: VisToExpressionAstParams -) => ExpressionAstExpression; +) => Promise | ExpressionAstExpression; diff --git a/test/functional/page_objects/visualize_chart_page.ts b/test/functional/page_objects/visualize_chart_page.ts index cb114866322db..1acea624ad4cd 100644 --- a/test/functional/page_objects/visualize_chart_page.ts +++ b/test/functional/page_objects/visualize_chart_page.ts @@ -218,7 +218,7 @@ export function VisualizeChartPageProvider({ getService, getPageObjects }: FtrPr } public async expectError() { - await testSubjects.existOrFail('visLibVisualizeError'); + await testSubjects.existOrFail('vislibVisualizeError'); } public async getVisualizationRenderingCount() { From fe807d68a6dabb735e1488c66fda6de8675f2f8b Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 29 Oct 2020 15:10:18 -0400 Subject: [PATCH 45/80] [Maps] Add readme for Maps plugins (#82023) --- .github/CODEOWNERS | 2 -- docs/developer/plugin-list.asciidoc | 16 ++++++++-------- src/plugins/maps_legacy/README.md | 7 +++++++ src/plugins/region_map/README.md | 5 +++++ src/plugins/tile_map/README.md | 5 +++++ x-pack/plugins/file_upload/README.md | 3 +++ 6 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 src/plugins/maps_legacy/README.md create mode 100644 src/plugins/region_map/README.md create mode 100644 src/plugins/tile_map/README.md create mode 100644 x-pack/plugins/file_upload/README.md diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 525da9d832b53..28380549c751c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -171,8 +171,6 @@ /x-pack/test/functional/apps/maps/ @elastic/kibana-gis /x-pack/test/functional/es_archives/maps/ @elastic/kibana-gis /x-pack/test/visual_regression/tests/maps/index.js @elastic/kibana-gis -#CC# /src/legacy/core_plugins/region_map @elastic/kibana-gis -#CC# /src/legacy/core_plugins/tile_map @elastic/kibana-gis #CC# /src/plugins/maps_legacy/ @elastic/kibana-gis #CC# /x-pack/plugins/file_upload @elastic/kibana-gis #CC# /x-pack/plugins/maps_legacy_licensing @elastic/kibana-gis diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index f30afce3ee02c..dee6e4777884c 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -134,8 +134,8 @@ in Kibana, e.g. visualizations. It has the form of a flyout panel. |WARNING: Missing README. -|{kib-repo}blob/{branch}/src/plugins/maps_legacy[mapsLegacy] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/src/plugins/maps_legacy/README.md[mapsLegacy] +|Internal objects used by the Coordinate, Region, and Vega visualizations. |{kib-repo}blob/{branch}/src/plugins/navigation/README.md[navigation] @@ -147,8 +147,8 @@ It also provides a stateful version of it on the start contract. |WARNING: Missing README. -|{kib-repo}blob/{branch}/src/plugins/region_map[regionMap] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/src/plugins/region_map/README.md[regionMap] +|Create choropleth maps. Display the results of a term-aggregation as e.g. countries, zip-codes, states. |{kib-repo}blob/{branch}/src/plugins/saved_objects[savedObjects] @@ -180,8 +180,8 @@ so they can properly protect the data within their clusters. |This plugin adds the Advanced Settings section for the Usage and Security Data collection (aka Telemetry). -|{kib-repo}blob/{branch}/src/plugins/tile_map[tileMap] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/src/plugins/tile_map/README.md[tileMap] +|Create a coordinate map. Display the results of a geohash_tile aggregation as bubbles, rectangles, or heatmap color blobs. |{kib-repo}blob/{branch}/src/plugins/timelion/README.md[timelion] @@ -355,8 +355,8 @@ and actions. |WARNING: Missing README. -|{kib-repo}blob/{branch}/x-pack/plugins/file_upload[fileUpload] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/x-pack/plugins/file_upload/README.md[fileUpload] +|Backend and core front-end react-components for GeoJson file upload. Only supports the Maps plugin. |{kib-repo}blob/{branch}/x-pack/plugins/global_search/README.md[globalSearch] diff --git a/src/plugins/maps_legacy/README.md b/src/plugins/maps_legacy/README.md new file mode 100644 index 0000000000000..4a870e4f7492d --- /dev/null +++ b/src/plugins/maps_legacy/README.md @@ -0,0 +1,7 @@ +# Maps legacy + +Internal objects used by the Coordinate, Region, and Vega visualizations. + +It exports the default Leaflet-based map and exposes the connection to the Elastic Maps service. + +This plugin is targeted for removal in 8.0. \ No newline at end of file diff --git a/src/plugins/region_map/README.md b/src/plugins/region_map/README.md new file mode 100644 index 0000000000000..540ab47c102d3 --- /dev/null +++ b/src/plugins/region_map/README.md @@ -0,0 +1,5 @@ +# Region map visualization + +Create choropleth maps. Display the results of a term-aggregation as e.g. countries, zip-codes, states. + +This plugin is targeted for removal in 8.0. \ No newline at end of file diff --git a/src/plugins/tile_map/README.md b/src/plugins/tile_map/README.md new file mode 100644 index 0000000000000..633ee7dba46d6 --- /dev/null +++ b/src/plugins/tile_map/README.md @@ -0,0 +1,5 @@ +# Coordinate map visualization + +Create a coordinate map. Display the results of a geohash_tile aggregation as bubbles, rectangles, or heatmap color blobs. + +This plugin is targeted for removal in 8.0. \ No newline at end of file diff --git a/x-pack/plugins/file_upload/README.md b/x-pack/plugins/file_upload/README.md new file mode 100644 index 0000000000000..0d4b4da61ccf6 --- /dev/null +++ b/x-pack/plugins/file_upload/README.md @@ -0,0 +1,3 @@ +# File upload + +Backend and core front-end react-components for GeoJson file upload. Only supports the Maps plugin. \ No newline at end of file From 915997e08b3c98df5afe839f19810b89f8e77db1 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Thu, 29 Oct 2020 14:37:07 -0500 Subject: [PATCH 46/80] skip 'should timeout if payload sending has too long of an idle period' --- src/core/server/http/integration_tests/router.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/server/http/integration_tests/router.test.ts b/src/core/server/http/integration_tests/router.test.ts index e19c348511f1a..ad228d9b0bb9d 100644 --- a/src/core/server/http/integration_tests/router.test.ts +++ b/src/core/server/http/integration_tests/router.test.ts @@ -384,7 +384,7 @@ describe('Options', () => { }); describe('idleSocket', () => { - it('should timeout if payload sending has too long of an idle period', async () => { + it.skip('should timeout if payload sending has too long of an idle period', async () => { const { server: innerServer, createRouter } = await server.setup(setupDeps); const router = createRouter('/'); From ca028b79aab40a2a432b5fcd23af9581f5edf8b2 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Thu, 29 Oct 2020 19:45:37 +0000 Subject: [PATCH 47/80] Add sort order to getJourneySteps query (#82038) --- x-pack/plugins/uptime/server/lib/requests/get_journey_steps.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/uptime/server/lib/requests/get_journey_steps.ts b/x-pack/plugins/uptime/server/lib/requests/get_journey_steps.ts index e4392480f5b72..d0bb67795d46c 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_journey_steps.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_journey_steps.ts @@ -35,6 +35,7 @@ export const getJourneySteps: UMElasticsearchQueryFn Date: Thu, 29 Oct 2020 15:14:59 -0500 Subject: [PATCH 48/80] [Search] Support non-shard error information in ES responses (#81967) * Display top-level error reason if no shard info is available For EQL queries, error responses do not contain `failed_shards` information, and so our error toasts contained only a stack trace. With this addition, we'll fall back to the top-level `error.reason` if those fields are not present, giving the user better indication of what's going on without having to inspect the actual network response. * Prevent service from changing the shape of our errors This ensures a consistent interface for our kibana client errors, whether the error is raised directly from a `fetch` or emitted from a search strategy's observable; namely: that both contain this top-level `body` key. * Make our body property public This is the same visibility as the original error: if it were protected it wouldn't be very useful to consumers. * Adds a unit test for the interface adherence --- .../public/search/errors/es_error.test.tsx | 40 +++++++++++++++++++ .../data/public/search/errors/es_error.tsx | 11 +++-- .../data/public/search/errors/utils.ts | 4 ++ 3 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 src/plugins/data/public/search/errors/es_error.test.tsx diff --git a/src/plugins/data/public/search/errors/es_error.test.tsx b/src/plugins/data/public/search/errors/es_error.test.tsx new file mode 100644 index 0000000000000..db719eb6a70c9 --- /dev/null +++ b/src/plugins/data/public/search/errors/es_error.test.tsx @@ -0,0 +1,40 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { EsError } from './es_error'; +import { IEsError } from './types'; + +describe('EsError', () => { + it('contains the same body as the wrapped error', () => { + const error = { + body: { + attributes: { + error: { + type: 'top_level_exception_type', + reason: 'top-level reason', + }, + }, + }, + } as IEsError; + const esError = new EsError(error); + + expect(typeof esError.body).toEqual('object'); + expect(esError.body).toEqual(error.body); + }); +}); diff --git a/src/plugins/data/public/search/errors/es_error.tsx b/src/plugins/data/public/search/errors/es_error.tsx index 53d00159b836b..f1e7eaa707a06 100644 --- a/src/plugins/data/public/search/errors/es_error.tsx +++ b/src/plugins/data/public/search/errors/es_error.tsx @@ -22,22 +22,27 @@ import { EuiCodeBlock, EuiSpacer } from '@elastic/eui'; import { ApplicationStart } from 'kibana/public'; import { KbnError } from '../../../../kibana_utils/common'; import { IEsError } from './types'; -import { getRootCause } from './utils'; +import { getRootCause, getTopLevelCause } from './utils'; export class EsError extends KbnError { + readonly body: IEsError['body']; + constructor(protected readonly err: IEsError) { super('EsError'); + this.body = err.body; } public getErrorMessage(application: ApplicationStart) { const rootCause = getRootCause(this.err)?.reason; + const topLevelCause = getTopLevelCause(this.err)?.reason; + const cause = rootCause ?? topLevelCause; return ( <> - {rootCause ? ( + {cause ? ( - {rootCause} + {cause} ) : null} diff --git a/src/plugins/data/public/search/errors/utils.ts b/src/plugins/data/public/search/errors/utils.ts index d07d9b05e91e9..45a318904665f 100644 --- a/src/plugins/data/public/search/errors/utils.ts +++ b/src/plugins/data/public/search/errors/utils.ts @@ -26,6 +26,10 @@ export function getFailedShards(err: IEsError) { return failedShards ? failedShards[0] : undefined; } +export function getTopLevelCause(err: IEsError) { + return err.body?.attributes?.error; +} + export function getRootCause(err: IEsError) { return getFailedShards(err)?.reason; } From 0094f7ea8e2ce989fdd0c9687a925da1da629dc0 Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Thu, 29 Oct 2020 13:26:51 -0700 Subject: [PATCH 49/80] [Fleet] Add experimental copy to upgrade agent(s) (#81410) * Add experimental copy to upgrade agent(s) * Adjust copy after review * Fix string * Adjust quotes --- .../components/agent_upgrade_modal/index.tsx | 56 ++++++++++++++----- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_upgrade_modal/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_upgrade_modal/index.tsx index cde54678b2d2f..43ad7208c3d81 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_upgrade_modal/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_upgrade_modal/index.tsx @@ -5,7 +5,13 @@ */ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiConfirmModal, EuiOverlayMask } from '@elastic/eui'; +import { + EuiConfirmModal, + EuiOverlayMask, + EuiBetaBadge, + EuiFlexGroup, + EuiFlexItem, +} from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { Agent } from '../../../../types'; import { sendPostAgentUpgrade, sendPostBulkAgentUpgrade, useCore } from '../../../../hooks'; @@ -65,18 +71,38 @@ export const AgentUpgradeAgentModal: React.FunctionComponent = ({ - ) : ( - - ) + + + {isSingleAgent ? ( + + ) : ( + + )} + + + + } + tooltipContent={ + + } + /> + + } onCancel={onClose} onConfirm={onSubmit} @@ -106,7 +132,7 @@ export const AgentUpgradeAgentModal: React.FunctionComponent = ({ {isSingleAgent ? ( = ({ ) : ( )} From 2a3846181740cadab56935cf2df23d5d809e6526 Mon Sep 17 00:00:00 2001 From: Michael Marcialis Date: Thu, 29 Oct 2020 16:52:02 -0400 Subject: [PATCH 50/80] [Lens] Adjust Lens Visualization Padding in Dashboards (#81911) * reduce padding on lens visualizations in dashboard * tweak padding and axes title colors to match lens * remove faux padding (border) to match lens padding * update snapshots * Revert "update snapshots" This reverts commit c63cf2bf1c023aa0b6325f19af01940b066915f3. * update functional test baseline screenshot --- .../components/vis_types/_vis_types.scss | 14 ++++---------- .../components/vis_types/timeseries/vis.js | 10 +--------- .../public/vislib/lib/layout/_layout.scss | 6 ++---- .../screenshots/baseline/tsvb_dashboard.png | Bin 118701 -> 123348 bytes .../embeddable/expression_wrapper.tsx | 2 +- 5 files changed, 8 insertions(+), 24 deletions(-) diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/_vis_types.scss b/src/plugins/vis_type_timeseries/public/application/components/vis_types/_vis_types.scss index c445d456a1703..9585711c73dd2 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/_vis_types.scss +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/_vis_types.scss @@ -3,29 +3,23 @@ flex-direction: column; flex: 1 1 100%; - // border used in lieu of padding to prevent overlapping background-color - border-width: $euiSizeS; - border-style: solid; - border-color: transparent; - .tvbVisTimeSeries { overflow: hidden; } .tvbVisTimeSeriesDark { .echReactiveChart_unavailable { - color: #DFE5EF; + color: #dfe5ef; } - .echLegendItem { - color: #DFE5EF; + .echLegendItem { + color: #dfe5ef; } } .tvbVisTimeSeriesLight { .echReactiveChart_unavailable { color: #343741; } - .echLegendItem { + .echLegendItem { color: #343741; } } } - diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js index 2434285bd94c6..c12e518a9dcd3 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js @@ -19,7 +19,6 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; -import reactCSS from 'reactcss'; import { startsWith, get, cloneDeep, map } from 'lodash'; import { htmlIdGenerator } from '@elastic/eui'; @@ -150,13 +149,6 @@ export class TimeseriesVisualization extends Component { render() { const { model, visData, onBrush } = this.props; - const styles = reactCSS({ - default: { - tvbVis: { - borderColor: get(model, 'background_color'), - }, - }, - }); const series = get(visData, `${model.id}.series`, []); const interval = getInterval(visData, model); const yAxisIdGenerator = htmlIdGenerator('yaxis'); @@ -231,7 +223,7 @@ export class TimeseriesVisualization extends Component { }); return ( -
+
T@K_K+AM;O3gURc@YK_GNOj<;^<8aO*XfIu!s!J`y4>2Lh=g6C-j&&#w^jN!ru zUHjf2luCOphdh6e?^yS;r`(hGUnV?1U>{~GHx3Qy7xXe3mzy!Zb`6#hTvizuDWxnb zl=74^z6!8;<>-KIO0#G+@6WIfe=q0OY+o7i370?j%XSJ?`#{>5B#-%~6L5Cc!_|}x zC(RJ-SSkHeq3QFDLDsSG_;Xh=U$-xA-g<cltyMeXlv>kWm#{e$#u8z)bAYe2 zk3(|pUPhy!fb54e0WQa=Att34O{JmXZ?YwY@8}38>JctxJE)neMrlb0;_}^pFb&(}eZa$ShwefDfK_3kvO`Q76S z&w1}k@a}|k4th-&;;0hmH8G?Bw_6XQMlOJZ`p*xCTt)@se_nw9f4bcFkmYPwIsEr; zl7av8QUy6kIP~{j$b7|QjPi!op-g|TbLiq^3S0E8 zSzljl#o^*nC{#g6h(y9&x0&K+3V$z4>-LaE*VYD4O-{GERn%}@`k$4^A3F5BwGHP- z_}^Q{tZ%Fv-McqA#Q#56YcN5dt3JoL9`OEqf0c}{$N%*b!W$bCQ>k=1jsEW?9HL=O zzsPt0z4*{0U37mhcz64M-sAoE{UN+iJ9oCw*GoT&4ZLQkx1Ou2R@=8)&Ue=(RcIdg z?>#~p+I|8%r&bR(qk^-(Hi!z6-VfRs-@U7eb?jBU)yY#J?P?a}^uvreu6Yd`gyY6< znY-6!b#--_@!)@XIBdV{9xArZ<`v8`5*DSwi{E@JweJocAAdL!NU@Zv_U-$AGSP$T z&usF{u@}`9h33U?g{{ym?XIn~{C5p$zI@r78@@;F(T@J_d6{u4W7wbyR#9@H#>{9C zZX|F!onnhMQ#5_jTsZde#=?NBhbtQ^>p)ATs;Vkx)dI=Hc|B)w(dE#gL;Wq=Mh_|o z`MYpb-h|wYe`R7T3mbv>OPweG4dsga>oUoLMOs=ZiuS1`rKQAmO{ zS=pq<4Klxsj5;F6Iq%+KrN;{jV>iIljNe>m;kVwX8;Lp7v?~!fiNsl`nNirM0a<=a~ z>_)CliLnsEN49926XI^AY2ppL5?F_mbH1Hj7iRF#i2r^IMArz*k*1UEk)rmtvJaaQ z6N64?v-+^O$ce9?YBPyD+NG(XQRYTvSQ;!f$<583|FOnNTprOpsg)GRp0U5I-IDLv z5sam|&+;%-POi$V;la~#msdt@aozJH`PmO2ni<`54hg9rC?uq5B~|2TEu1AT5!9oi zI`Vf5YJ69^2Sm+d-}&Fx6TR4cb$Z4_aJIIK$@m$tN=ElKOWS={cM-$+17LAB3Mt_FFEW zFqSnr?kFW85s|L(uL9&B>gwvbCPk@JR_+oBo0F$| z+ZJ{1ULR*o)2X6p6Xypr8s+mg;3yG6K`6pysNl<&ORcS~`Ww?7XHK8a*rSrGiLYV1 zgj0O{+>dIc<>X8mS$EGvIj*FkE?&IID;FOa84+PL)0r~4uwee{NAufEC$PMsvVd^H z9>$J`8W>oc7CK^4v)|@r>IgI;J(BS#K zE+uGBjo0)XWreMJi&p#q%db^$XDNnY%exR7lU}L&lIBe9y8`0amnKJfgME9_&qWV~S16e>DJ!woirMplmJq zDG2aQy?<}N}pMXH5Jdd_4dXt{0+_P zg`GiZsG;VXFM8u-PBuRkyiP4tP_VhR&UdVy%Av3<52qqvhCiGGfI9_l6#BI)N_!3D zJB`&BszqEs>42b&kfvVDAieQ1lr#VQg#9X=oSJf67xi=K81k9o#&vdfbNOj^2hrXy zuzo5BcCht_*@a&8LZqN4}&iqODrw*+CS}iutk#{ z@@vD2(PHZ&U&byr@x2aF6=hG}7SZd>z)23>3X2I^X{i|1TP|85jforHx%1Mle)pyp zcdo|k@Ng;HR;sOC9?E5~WU6|(`W&%=r{2KB!=teOZ?;mPUyi_&p8^XfEV&%%Mo3*LcvtN*FI3?1}gpYM5IPU804~%?9d$p;C zy(>X&1NS;oNX!*Mirb&yi9|e`&#yzbMz(MiN)QsghJV|O#am7Iihu>kj9$61|F0ua zj?yOMJY8=S?CJeo+l!@$xdr$7{8e^g{eFAeb~J9dapU{< z=|HD%6M^JhfnkiI$7(>MFW;Anusk-0NV2z2)Sa1yiIa}kqS%0@JP82UQ)`?&J)#SZ_J||SrU>~^*GEI%u-h!}O>5hBC z^%j=%nt6J4>FMblO2O|JNG86%Z>3#_3PPylJ4n`)z6>i*hFO-m;i~98N|SjD-<2 zROu^=%~%M*rUGJ#e9Oz13$p%D`A8j&jGg#aZFec@E`aZytYh?>qS@`^+)|#;dU|?d z;^O$BPIye=fdjji;>VLYEKrMI*;0+}-W7)G_iETFnoMS$bJxXjkMKdchAQwxd?dcW z#LA0H*?aaQub>=XX1nJoIH-&TFOX6tohFY^SDI0ImbZNRHz~^=Zz%;c?)51}@811m zDed&E+IQ)Lj`CjGH>p7v={ibhQs6=d-d4h>LB>D8$!z6)evvn0H3AR}Dw(LKrx(R4 zvi%vWeEs@e`pAZ7`l;vmtyau9MjjT=PD5p?NBkzfogTYo*tSl%nCybX+#7T$?@bke zg6!%|2$|}~$0jCbUAV=NZ_wbggDv{9yjZi>%ufm#n@LsZa@}W+ZWp#& zq}_I#T!Xff0}>VOt)3IJ(45gDZsMg42wFX6wKl6$c?{mN{g|Fo<4Vv>#?^Q=Vm78RzQ6nIb1DrFOf{5Q+St@IY;|yZc0z{;09wNnbMOkeBnt3xAE`YbqM^T7f9vJy(IeCoP-8W1pWAZUK=%KBm7zlEHNWqv>REQrH-5QGUITkfL_txpZkQ?%Hj^3LKGh)LvF%Yy@bxx~A(Xe+=!bu2ow5r0`6)dwW{zJ* zyr{jNKV2&ijxyLmNnHA2BciOUn3%j+4xiu95b71EDev2)NGIGSk2UVh_h$Q5%`6cr zU@Nr>Ch>1M3xAh3$<>CvfmEt1hZivxv&5y~D|B`3CE%a!OJrej9?QAy?(XHWNB31! z5W@cg1cD2vB&EXAk$G%x%7B;`MR?^=} z)Je0jQw1fp!56{#DED>vQnka6%%KYRhJ_!CatQqCNF6U%(gMLmGcNVW;jsY93HAt< z8OrC+H|#B76>gRzWDobDTGgeYlzZRgg%t>e%^NMi%L`Vf5i3KfpfC^BHPMXxO0-?)_qZbY?s7XXogj53xQ!yoRf9} z#K3LF-hRfRRgvTzw8$UXdAaCS;()^ReEw!fg+QDfY>VPq(NA~rQW79Wsj+YC9D7+$ zuuJ^F!dJV}C4_~_UcQOpT^cIJ+A-gI^_ZT#K*|g+vze19w7{w@;N36xo`VDKlDO0A zoG3HH6&cC=AN&a|)$|EM;;&vEY==?cWO5xXF{0bsJ9g}tp>9{g;aSCMKd*(ua3>hiAihn>bj9FFTb5SR{Cqyf zgHQpoNoXJ3sg7fBNJ~p=9FmZbuz)w^ z=jY`7aHZUx=aR7bXwLZ9&mQL!bkw$yh_9;K)lH4fH?BG~yD)(9Q&93yK}6Qw_n0ru zMspfyyS?@F@?-%eg>X@&1#$yVqB1KDjE(xY`78rE)R*ixmbb~bFK7MvNh|L+{h+Xm zd;pxe!hB^Fzqge&>Q7~X>f=%shdWWy)T4Ez$SNleZn2sXOvPA2A>Inn>l55aoFES6 zU&G~OiCN0mxFYtxns7+YUXS1i$YtV`%>l%@zR|hHZ)Lii+88dL5AqU*su@qkypkDS zl;`fvi#5iqE+fZT!&OIW{CWopi!pE+?P^t=lHx7nd?Of@v~bLRILJ(^VI>;{zX5|2 zVfekEtl>-n)O#@=9-b3ifguU0#Ev9|crx1 zV;eib4|Q+2rVb}>4(vQV>_{l*3f%h|Kk}BeI7lrc<=nBwaf4*}ph>-&7y=4pW=WSH zs>hg^22|OYd>FfMb6t;DIsa>9I`hh(w9dQ@VSW2ov7hgEy%FH?B9NxyY1vBzzdJ|< zW_g`kVW}(fKCcetvGqxz+4e zJ=xRNdN59a@%Zt+CT7K-L!E$%e{aL|sj@}tHqbpCZuEjyQ@6}JE3I_=*VpFU2(MnL z@3VMG$8}fo9_6`@u{yA>uv$&nH?QeEODe8QX(#J?+Rr+TpU!g+P(^@@BMFU#))~=h)I-GaU)z32?2g1 zkAkYOE+f@iNJB%z$#M|cG+>SH=eODpZXnA-n!a7bm>?OB&%*c(+&!tiyQ&x;XIXLpxb%et_i$+P?=m%JidXLODs02iIAJE^&(Pti~7;f)1;t;VUs#U;J4F(TXXDF46pXN@0b-r)xCbL zx}Bv@*QzdacX!tUC46j$FLtibZ7Vm}cCSsm;ckQI9#p(;J6SD)GyP;d6JAqXDVwE% zmX)gLRFC#k6*5b#;UB92j$Vpu?@AtY&jpOb7W3+j3ns~}`bIc{s;8(83jHlYN?Sil z-Z=Q?6JD@9YYWmF$9|29yQ$to_KYBwW@vkN*1T|z4Q*(jl`SmN8Za8aH$zUESs746v5@cmZ$2koR4dmzh zxhIQSFYUw_HxjjaCr;nQ4MDh4P4x9YJi=>tl`j!2+rkj!wZqjvpQKA9 zyxG@+_=m5w6zXg_7j^bMTWAi-xA_l-K_EnxTSvQuVGHL@yzX`|#91j02kPo1E-wD! z2D(5N$zLV30aF?5oicFb?`KBGySZm&DOyQnwiD-k^%AJrFJ@8{{CfPx_9}Wt|D{uO zz5Dnq=#rs@3qDeL53Qp_%`SHtnLmcJHpA-2i>34z!FWaj+d4LL_WLe>esuXx*dFye z;C=bpHG`0lkb~3zc>@A*LZ=^`-BbyC^5jXa<=@I4;?Je{Z)y7u* z6Jh1qF{Rd8eq;Y1i9h*jJ_;2q%IY5fNbP@b({3ZtGB(Da-(NH;HsiMC`!7L0^u=cz z3BgZeFjk)MV~mVO_YBcUziTpGRRX zsp+@o%nips3b!}JV&>&7f0Yl6iZMcTBhP}iSQA0@zZWOJ;_PdDwUlNL zgr%jm70G*ufg!N!)X&A(`1ovqmY`x!xXbSzPoEs?>E&fxLD=y+VE6&_9G*XaUUE-l zok%45%6&3@r7ZAij)jd)SX^AkuGG{xzn?G#vFF=MmQ8rm`Mv3U%jex25S0^uoi;SE z2>wHbZ|2Kf2GPKh(&&2Cs^ADjmuKx5>wh+vLsIh%)Qx(~WkEL29 z;zmwxwZV6dv5r0FTGWJJbdZRSdg}%6^YGGLQLQtJcnhv1rgdK^BvdUYO;%m7>aZn& zeFth)zyQ&O{rQrdV)2Uht}XP~BH8}%G)6@7q%m-b+cKC9GtodBPD=W;APlJ;`iVfkEkpqRMH8&13$->I# zy6f_*eHK1|-bRjQytWnQLmfpcH8Z9zI$^c$&;FspW{GA=UB z23mYRoKimDTNCeAH>D=!cxrxa=#RDCZN6`)Z>KcRfG+i2`PDnl^oNrwKy4C`c-C3 ztP5seZ)Hd8u@x@!9y|u^Q8aMFqm%es9VGjF0=SFqaVWDYr-%de2PAzLV*wJEDQ*8W z5H&0Nf_1GRw4LZ`pt?P_+RLZ-RrswaEsfOZFtYCDRE#EPrYcqklu7@=Tq$JSLUPAR z_A`ZgT&R9jZrhopGChic%&9bbl}o?g-3rn-h9WWZ$SZyy$t$a+pmr-ZI9(rr8n0)C$`c}59p_yAPuV5cXX88knzp!VF*$eL? zY_T$V8Jv0_aGd@kXb{Y_Md@6u?- zpx3AYV6mn=X)D86brf}Dqc^qU{;x>PYVhh$FQ362O%_g0^jHYRl15o$o0^_>8rsa> zL?Pg_-3haQ5`+`)a6>Hb+#TcE`nT|Va?c%+Xt$2AfKm~N3YWz9G%HcD-mGUln>*8j z@}u3iM4!k9R$PI|JW(C`&n$pS#u?PFF#|EQ)ex^0}`8?-;R_wv80B*criN>IW1Tca1Fl}bxEwdFxtIm0THCW ze;|CCA^3Hce4o!WvYtDiVmX7vh#IN1E+j3x?2RH`LbYIB@+r>jxY6usx9?KFgv=p zCIXW$cgbk9X?3CN-2=UM8|v0D3mfL{_2aCm@$00Dxw-5t=dnFm*Rgs76k-oC#V`xF zpLw}kFDi&6sCentuV26BdonYIDxA%ie}KOmtasZ0Fyc@T z=a)o9o3N6BrFJJVgIo6D;tgaq1;3>zUd6p1u+6?+@wlMTJR@hHO@|T}>7*>B_4^4% zbPOpnx}X7_6LC()u`TZ2pMV&RM+WI0O;F&2+GVJI<$FGV+Q(P?Bm-o%_GM_f6GxZv zVD32^$@d_E)EM*8LDDds8j-QQhs+vn-`%KJqC=wFYcobg7#;ei-BCuFtF?Wj*3O&M zwjzq$1CtBE&kzXAQyOVFW@kD^mUrupz|!^0Medy`&BwBDsKlo4Iv z!|{`KYtt^!o(uyXLmQioV>qhY-c4walyy-I3guokvrEjhzYat5S{Dwp0Ekz4N?KU1 zLZXk*d|w~Gu8xfHsGT_vNqZ!hTyKQzE1ugyqWcfmZ`#QLaKEf%oy0q%VTzoz_hp#P z4Op|vKkCrVl<6+&H@MYn>Nk6iOMZ_gitC&2U$8(?Hs^eXHo}sX?>L*#vatCGFGie~ zmlyH-rO28mi#a)WBFID=h0O~mGVy(URc4h*~vaS(Zo!z0xYVSF8u{9=V zbGQy6kEo*%7YZ9cTyz~OQ{@TSOh`pMh?~aIZiG#ob}H1i`%Oo4$^nVMQfE)GpHRax z^Zc}6y?RUI`_SA{4?xF7k8jc}v1eMRPot;lmRRDe_1F)oV>f0cd|scOUs{JiB5ns~ zZP<<)(0j*u9ImxC7^ij44#iy4}>4Z7b<0QjyLrYoxIt6QKIV?$5`} zW~12V66|3EMd5Lm`Lkk|t2g4V36pu()?NjYQt*;#2pGOTQfV)Hx|5<3L|X1m#4hZ6 z$NT`cwAyE>;1DCC??pt?85Wk@+{o)ci{-D|c7NbAD{dS-u-ej`9cPN98iIQvd3j1B zm+MI4L$!PZJ}#dddHA65k=(iLI!Zzr-KAdN68@z6A=c$!OXL}rKGk~uq$h7_@AA9{ zZ$nfjPR5t(ANykzUV83GNU0tYtVTtDFb>D(3<;b*L~ zj_=~VJl>h(b{XBe8A0f5`&rVIFdwv+8~&XoRTJ6m(3ca{B;{LBnlgePYgcZ1Ju-6T zQLQ;>(nh-_{!H8n+4i8CKDZ<-+$KfYora$7Prp^un+kK9FJlKgFqTfz+Fw0rHR|1d zw$VV`huwtIQC;Y(rVJuTbik!^;<(h~g)Vr-x2y4BnU+MMC5caMB;Louk_+GLqI-ww zAYJdiWV#`FpWjQN3*7kRWg|^?fXxR2k`+)Y2~oKe6@@}4fACI-U>yv8!YfDb{q%F% zn_b>m*+nbNKMuh?ooVpK1dE`O591f1$bOvJM9|`BDV`Xx_+Ge8apuLV2|nn4p{y-u zJW;IOPw|IsMgwl>v)reLjCp?#5wf?wyok6gDr$N1q?Qk%Fj_k(#L208!OP7J!@vaG zVvmGP4RNXl$QC+{pgb4jQPf9nF8MK*IrVcy4ru-!lS*sV;N&9*kT{|GcOBfpQt`z- z3EZy|YHIb*LDH7xIQd>{QUKK&XA^`M|F=L#0R3LV4)=qc!IBO8XwZAC+g{H{qTAFg&FrA$*V_aa435p} z%57=qL8F6r`J-PXBT{)C`{%LTIa>!y)mQfAfV9s-WiyUzqaNrrt-UIp(ivIA@>ObgSbuH6vmvZ2fcpw}#B)4o zE(jXPxWQN;v1djbY$klpdF z#ij?qWaXhHFvKKOi@5iGLqY4#>LOz1|H59wn0q_2gwbHi{ixA3ny>BK!)D1e2Pm(~ z;ZU^+mBdn7K#o*NdvV-_&R7lOuW+%j`Q~*bB$V7DML&XrzsN!1)*yJVv zz}{zWZ{JpwrwZ0lw(>y{Xxm90i)@&kfw5{L`L)lAXLQRQu7XoepFT1gVxP*LwDpnT z12|(5ZHWu2pKsg^v}Hf8@V9S!0P+4+(BK?+Bam(69}JolWD=qt$*U;6^dJEq+}F_Hb?AxnH>*tI0<8<%2US(3DC_Xz2FL6U%$AyDIZp+Tg*T%J8r zX$aXdidPUo3s8cWt4DD-6VRLv-&-41CzBU;oJK`%UQ)C8@O`?YjD&-O5e9dQYv`2( z&oIId%NpMvM8lr8dL;isx8pVMl{&xH`I&6&g7j=Zesq1-OG7`5NuY6$7D7#V0rMG<8Mp$>e@e%=BxVjxzNU)$IPsK-i2UYzV4}XzoAL+KAjQn&0?%|uxl@A$RkHX6f@l&Dwx{KWBy z9?yMiwxN~Wo%Xg&vr}G;ij$op!)B0PtYjE0&=}Wn#h^jV?8A>AOM%`)Z#;2avS}zQ z|Bx315l?9K(m;~;7{MgrH0c4~!r`z8 z8Xc&!t(-vvkSqM9L!K9Isc2^dvHGLb*I~>G%pkmu)ai3BYRCZHI&~APt9d=_Kkcu9 zeCZgegr;!6&nqkQR-_EW+LEn74`EMvRBvNCHRa2VKeAvf*%4nO^yo*wNLt+ik@VQq zbN;(w#z!}A91dkDl2l>d60Qjj5-jchF#VW|7b-llXCUAM0y2KPed1adys3?Ix*v^KXvPv8cfs$mQmj5L&f2><6w#;QZv_UWO~mV0 z%k1`ua>PYF-+=9Uc;FmpkPIZbw}Uw@kAw-3a3Zy6;rt_#H_9jA9hyxWU0weu$`fyB zRfbq3EP(tl-2peaq;}kEsdUhV13q{JjB7YMaV+ny#6{{5rxlVqro=nkBsn%e2bKP& z^zbBU_rig?g~T1nwsybSE^QcmEf-|=9#@2e!^`~?k3f;KhAN8uUj%8fb21%9I7^;? z^ym>1Jx~Z#l6|2mHkJ=+Wm$eumH>t>b1N(FNhd88%*N6uNBmKo&h4V2pS4>iRs@#3 zVTkT@m8!q1^VtA|s6$6O%^;M|uvctz*t{UY2Qlc~7{k$*b&aIcZ5FQ>L8x@rcOl^W74#j|v#8@|<89=`(Fm5p8DH4l` ziMgz#bVK57pM-p#ar48Yejq7BSjZ2uOHqd29{64`KWMXYG_K{ovG0RK2}UH#q`5D< zDny04Uk6sHCPu=3t-qte@IcZ@ig8a0=!!Itp=^eQUR3@(B8Px1DZ( z5^-ZC{bo>V&&FFI(!ZNbj^aMuTcUIA*VqYs(8nPxhi5~S zI;G#T@2JnC0fndjnfFh7qkM{W{@(J9odkNo|EtXK44lke6W9Fu)f^$ArJsP*$7=*< zsOD7-<3v3VSa&g@1fhdZ`v(G|8^Dg{W?0;reqIDaV69k}6Y|<(W z?0G)$cg{yiOWZ{#AV1-AJFi-WuJf06tJB5hksi66{GrGH6dGh;EG#OX&MJHmBFVt_ z_936`5-7tdYKH!)s9f)(e*4)x@5OIBgeJuvRx~ zFutK7YIp>)n$@#6bD{q|Tx`GW?>Hd;{X&>A*Y*c#jeT3ZN(i#?JJSZ3K*ndoUjZ1t z;f;OO&*;|g#P^A>=(0h>3e6DNcVV}dV=UYI=+|ezY3Z%gCPTDgGb}K1IMeb)=n!DA zs$0R41BW0E7C`nBwmP(9JWR7d7TDQ`rnb%tKthH7^e}#wOyZc0bdxhY%!Lo_Nae4= z!560edaXHfIX94s)7&w?$uiECdo!qBnqOqq8`xZpS82kZ=GD+j@160Px3t>?1XrtQ zYfd<*NQs<(S|QNR)N*HLstLo>HUE{3M8^G`%pjP5UKN}?u*b306ZzeW8usZ$uPGKx za@S1(1wHxb&}=hpNsm2WP6Zj08hI2?@%tN&QcyA~Ot=_mx%55&2dP)3n+;#{M8xxM(*|KGUC4Z%7IRNQoc$C`-QA9HU zi?G}18hY6OsWs7Jpw>KvDmDQAzbl$9VR&JBbwiFjZRQ$17sMm*w@{{XsT>5`K9f}% z+eGt%lEM#E50S%^+dP|=+*Le~PZSONv@o;$G1{&T(9>FMt~mOw9|I(ic>9mJd#ic? zAG{sgSwTLi@sL3tlIHYV3l3GAuTUPtH_+ba@%Ysh#th4Xitp59F(sa1_Lb>=qIz*2 zcub4jqy0SdF*&4axOMw1yuYuZkkiw_c6f$6?;l9ly-G5QVzjh!2^Q_e5U8dEPVndE z|J{GzIeE7AmH4AO!`ag@9f6w29?#R)rPWmCj&B|ZXX9{WE87hK(2~7m@=j!o*>mrB z-u=SjV$dG@7&D~H|BL;8D4K=3Db_y=G85bHX#Ahq9iENr%Lo<8YDV1XN(-ijh)K7KV~O%xwCuv3y-3w4n(CX9+b^} zwf+fj><-;)%=3;Y8mxL2WOqZ~HI4z|aQ^=`k)st|53+1uRDnO7i}KO<3;aCv*k=9^ zb6Q^GAI@FycR;HF1@yJ=b!$G|T!mNRUQ28~Wj&_Tf@otGEs6#~8A^eD|{ zDjuVQ5Dn55b)a&H*85k4zRNUPlTK7%<089tz!44kxzsf;GeR6HLA=t+kF2|z6)x<) z#obhn^ZGHd9}BGi_a#m&J-3jcN867b{0c+))I$k#_r_W_(ZxYu{WQ&!{5 zV*1`p<{O5L54Wl{kOQ3LR%KEpsZDx?JnDo2+x2L>v^0m8)o>Bw^AjEQ#3apDUr8-&T9kmj0&7Jetr?L+%iSbR6XPq_xXNb=j2qYi0u3tg&x8Y z*TXlQuSh?VEvceBzLp3c6=eJk23>cSw5={c!3h*#uUcH|x^@%*j8eF!@+fVXb#5() zau&`4dM+S>;ufiQ2A}70^Uy=Ou1ucE5-vS&%Aa8>jr!?ixiB+f(Wt2S8_Zk(v~42Z z)uHcD^zl$6hhDU24$Dr$7Z} z@80Ndmrk!zcP5@326`2T$kMUh_w!<}GG!{zNAZ`Re?D}8C1}z_ba*YW@XaAePJ;#o zW#YHvJBR*Vi$X&GvwU4g+QyJYeVw6WXs5(7L|6H1CKs%}j+KmxZxy`G59PqavoLde zCA@-L-#?h0W8S~Qo}0O=P>Q+h+IsYLv(u2YUsr=__IU=x$K7Pz6RQ6nv2=Kru9<%G zOS>gji52o`g9+^p#H4|nv<-c`jH1_?ud&KLvAkitxsEDH|GBA4^uDf~4=?;`6Uz%= zFRv1<0xni}204lI|3EAnu#|oDJ|}t%^L6l9<^gyUFBIf%XSfI?)Se~&%)D-3!EuSp zIdNo^rv5wkXY1jlg?L3&)fVW?WeB0RZp3^8NIbQI8n_nB&2a#K-(~y zUuzgs*jWV@q5|KTDaL{#hGh|d*Y4Jm=+~gU^Uel>1{(VsN?^v92l!u`g`o2Lr(uY> zOH=B^OTB$%NXIO1uiJXw#RBqaa7mXe4d~lgg2=Cs>nis9+2<6|lOfQ~E(=KBpapxJ z;Z_2TJwkvR3~S!u3E58fT^iy8MHVOx+M1iy!7Z~6OB|Dg`9|N8$ zTCLqIYT2lG;VA(6`S7MWf}x@QL$cOTidf=1Pz@L2b+@|6YcSx&-NR z_GL@fXf3+9YIhw&c}A)(c|e}$97GrX2*^OL9SgyWtDyr(G|-R-c7E)CbMOnGg1v)v zP*9rt%$nh;Uc#Xkp+~EwArO_Fd7seH0@G`@_Vx=nWtyRq{)-6Mwxyv>|e`*O6WVz%>Kg^hXnixHq76UI8&7~evX(-PToVTW&L z>Q_yr+e0cA`YAScJD^-$Y=4Jt`C&EHD_AE*^BYp$rMo1RCe!C6WhBHR#c^V=T>P-p z0dov$CHnSqGElQWe14F7q2C)ZqyPOC6d6})f)(CMb&GlFdghob?I|3>5GhW-=^ zLm;8ZG%iyoc>J_{z&e^E;splQfJsjuIP5va=AA1&EvktFBOZg zX2y)q4TfX_zue)vf-83ghj-|} z$vM|BuQVe#Fwl%yX*&%)@OI5cBA^WmCgoF zweBFNjd5oS=^-EM+j0l`klo+4n_|njcai7{*0<*{2O;-wW|;QgTz(>A%E6@NGbPou zM7ljUe$&JX6hVk!wzSB|Nap~#T#%m~LPGZ9it5%|g^^|oJ$_3=nZP%|L*eR3x1+<( z*hH(~HC1Sjb)+JHTZy!fC|J)=ff=N7EU(sW(pk)Hj$>LH$Y~QC2l&#Dslq7`DqU0T zolCz`j{Ue`E8La{Q?#$PXfr9n_VS6(Y=cP8NMU9c^pc8pGOWSSnm}6f!Gb zf9_X(5Xo(6v`(|Mw3Iw8(~wK5ol)fA<{pR@Ht}8>l7jXWTQ|#FODgZJMJ^D=_R7Vq zYIE#U1Jn*PbN4-GWQ)(6>}#wv3?Pc*Q} zjgKqmkf5~kaGXN(I$kd!c<>?l9OcVlUW29bb(^ob&xTa&UqEmG_>CSA%5f_eF~@M} zRaxnl*P?&@V_;7QsaUr>Ty1Mg9%pOF0gsR7TNN!t$c%R77uDy1=Vw|Ual)6qP`!YJ z$>Uc>YD{#LsbwyNf!5a7+R3u%hC-Q9Q77R$ZLoUV<`z55ewy38kF7;N9}WPkv{vkb zUWVRUy1I<-%|32&0OFsWxogXkmw)W=xM#}CIZs|_bTJ%>?tNvl|LzaB(gfqsWv!C= zI9T_`iA0MNQjg36xd@xNM#?Q}hL#R+b?J?VR0lwr6 z>uqd&a_ZGHChqGwQBhG+u%K)B{psAgRt#}T^Lp;@FP z%a}M+zHYnZmj-ZvDYKv{0}wIx<@<+sY)sVe1iB_mrtFQu1lsOCU> zT9v?ZxzfQTTV}B5H=4P|p-QYvb>JaSerpQv)o)x7hUaW)%wgFzdqbn>SZ~2@BAx-V z4g2K%d(^pF+$hHx(n+(N;|VnnAtV z!qK?|+I2MFOk5BK6`X$SLnT2V+iYC>^Mp*=RI5qeru zQb}@!4cq;++;+v~vkh?}nn=k>?be|Wev%K|-vmVgdKYT`r?7|5F7|--_uA~!7s96I ze@+<~;?F4`F93+UfYaG4B7Yu4T!Q9F<;lnTw|E#WBykLhLj!}>SejxX5Vts?4oxKY z;MxMYfwrbYT-^-nH#A@~(H`wx=&&1&E0Y4=_#m4rt-|>*2&2 z{}6OHzLZ}x?#0d1NVi~F2FQ<)nRo<0G|;>GB=uYUm{HfGviA)+4GuY&heec}}9Oi;0hUMUcISpV;k2mXr zrCN1LaOI5o7ID-*L&P$$JgHaG>GtPD496lv@jLuSJ=2uqsj|N8uFuw=;>{-Ki8ZS# zJ(`yHt;^%OdcJCfXQEH$`34qA&t=;h)2#PLY_XzHUOPbc`p@!-csbSPH#RGW%d?Np z*=It*ZS-TqnXS!lyxGBX?OXFGwXy68yYu@qafRutp885#x6&94Tk>Vee!SYLFsbM6 z`mD2fcBENcxM|ONjc@$)ro*7v;=AQHH&X5RGX464PT5C>RdXo>?|r%S{moFPZ&L8| zeD02Mu&>8;aYynG$&HUk#j6);WojVDy)XCLIoaj-J0p)V!h5>A?# zDn-oTaYIC8ySmx~PN#+>Ma_*|Tcf)hGG6*@&;C?*+5Fy06TReg`>C_u*WL`JrtR?U zzv+^l59hF~0}B!!kB8>Djl^(8i?rc0ethX7?Q_=3k*7+=mmowSyf_L)3Mp)uU6^fw zP|))(@m>Y3xIJ>=FO^mLzk4Yi%4o;w-qI|7rVo5Ja_KlwDCG>o^f+CySVh;U-&9CV z-tud_vTWajb=Zjdd>v|g$-EV=t*+{2FY~TH))>`%9FAjY{}U~68+LrTs(hs!)o}mf zcc5AcyFsR*!7;d*(urJ{R=o&_tVVJf?T2pEe#-6>>U*NL6NV#?Kp6g$6~VwU(9P#5 zBH}-_Q5XDpl5h^wni;vR-dw%3q4T}ODO9%PkNYByAan-@K#j;wKa0l)^@b^n=_3&L zlSX1w8+zV8tDyF{YTrv)rmCMdMwjWHL!a$4|2MLwS6&zAwgQxfavJW6*RHe-DpT+?rUq7I0`TM&`?U^}mAd zIB^-#gn!p3zPO4)*;oF9W1=^C;%GZ}&{>o)Svuvs7qv>Y6U1q9(v;KH8z9o~jNev_ zEacifX~2L=bgQtM*(xeEbZd{c{OhnCE{}h!k8*tOK%rE>Y93%&XpwuX3DK~FqLZs_12Fcxk#Spo7Tp6n)#|;Jw7UE zF8oOkF4|T4tHn3uvgWDkGeeWQ9_RTwx{vo1GdnN7=chptcDtbBdDMlXo8#1KoP?PN zAK+pXb${xIp&>b6?-C%3xUP*BzU0~C{V9aMSd<`r(`z3ql3|_d$xe-iOVva9e!*F~ zxxBIJzv%HVXiR!-43Zt;pTj1hP=Bu5Sj|2&35Jkt)v3B&fMi7wjGV3FxtFrG=W44v zqQ0_4@gG6$f6j1f)!cAaOz|uI-D74nsMF)GrRXcRX$fb5CV0k4IpmtjCIK=YZ7%q$ zdSMoP26`%Fik|q2Z8cc*#+D~WwZOK~L>qPKlIm>U*<&OdZ;3NcW^YQCZmMZa-+_~< zG5T@hI5s(tp6&ah1u}~58RaIU*etIw;qo?xpePRLHfWo$(y5`7$1*l%@aI%!xF&I9 z0{6-)MC?ORf1Z(|U$ZisZG2vm+44sTBvL8yr*rnB_N(Ep2uyvu<{){H27h$!?@Jyk z6e-Yqiqgl{|DG*oOT<-dp@4e{drL{3isvydS&^1ThfNb-ZmVj;9}|YwF1RxKS$_^S zESo->h4u=zjZ6lo4@ohSAwX=YqlDDD8L8mCTPsqUW#WDu(lh{WzNSN(!fO1t+j6(> zN#YmTL}OVeTyLfw6F8G&@%I~h#S-yN@MBS@d)O0szUyi8TUxGNUuX_%?MH11=o)Ay zX=@Sa8cLYkCi)rXnXebFjx}95j;dM4oa|#EO2j-Kb!e5{O zkf462M}VIW3$eikOtzbDu&VcNyhDN^g5RVMW=*F=Nw!r>u4%-|RhpD>qljLEE~8y^ z4wyr3#{IOvZ_=Q49Dmgn7Rir8-78$e9JBwjwQe|h>0NgI>7c#xbtWMVd_jpUj(!il za$$}w}GhWGc^q#7U!j9Hc8f__5QbP?zvSqS*-V}zOc|bLfJv4fb=r#J)x4Ec0`0NuN%r^PG2C9bjRe9D8C^=2&qj&&(y;gA z3vC|=C)#X|S8F6jMc<=0mrBBSq!K%o_jrOpjFlBB-E_0|u2g$>iDXX4Q z__nw}t)0_0Ev4KB>C8^Y=&)|O1TBFBLO=+bZ?eai4y9|JLWp}fN@_k+;I;X$r~S~p z`L!#2m~~OoC&X}+4XK0&faM65@s?pTtNkM<85fQaKR`FBPH{tpk1R<|I{bcEg9>JJ@M3^LMcMnQw;bQx#d65E41YwMhd{EFmm>Jp$$OB7e%V!@gk%Q0_kR(0{=CPj1bI!) zpO}-6jsV`UmEK}?QOzLCw8!J^_A< z{G3#z^`LJPEUx>|l&V``z;R){`py9VUMf+_hE&p#?wx&9hTW(;@PDp9QJsy3c(fEx zgY*KIyeQp|K8A$U&NCJ?#8>cyH4!>o%gu8CAaKEr9rJH)X9V!Y{JN7=&hg9oN?k52 zMEUE;%|EoY`A5K6u|T0N?39uc zV~%t$W3~@VRH9%wIxE!-lS6AX?-tk1F3(&a4XA+d=f?~Ag%OWQZ$<6K zln?K`8;0RDgjnBQ`-^f&UwWXF9E@1O_kfE=G~lf@awut~2Lzz`NfsjZgiY{MWpGqA z5qF*UkhWdUW(s}7Z{ev>`;YG!pU~ie70>mA>DcqJ;>1WKKiM+7CrU6*yo^yj@7w~p z9U;E*=v<=2nGt?WqS1_7J@Rc*JG{PoYTMLNVl$n?)Gu*j7v;k#ogXi1X@{8h9J;Oo z@tI4MKxJfUDt8dGC48pAEqFp426voR*gcWt4R;!lSPd+*lKPSITFPqy*UavL97mr| z)w}BCM}-fd^d(9TZeZ`R;RO~3ja`PAz-jHCLMWp*O8nU4*$I7qJz>3rC{pCjGei8C z5>p;Pcnf<7NPd?!}gjw-N;6!-6~8F8hD+31$rrGG&tpDm36=9Ec%1C&;Vb zXlEUZLu}VU4We%q)}mVA;Ct{MwX;u2JYTgDG(chcJxV;jd8XEnRxU+V-v#fA&++ry z*Dagy_-Q5MTHUWU`iFO0{sA9c>#L)y0t;s-4kD*I}@z`^@B z!7z(uw7*Vgz@LR&v4_jpaM><0}fchfY7=P+5p{jx72M_aTX{%&h%e`yc4Xy!2z5aoE zYjt4^h776|_EgSVW&+vPHDhu0eF5)GNww9+x9aB>#TjPt9-3y&Q0!{=R(n-H|CE4m z7B(I;x;pw30YdOF@4~HV*g}lRG;Bw|l~GG|rO^5=oQ>f8)e3$=_nf}m-RWkUf=VGl zwTDoN9OfQ!P5}A4MqMylq=Or@%*e~jW0R9)gQwNv*V~^Mmhxu)9Ws12vJbc|MFj;S zkKtONUY7>mpsTBT+mTN|V8)NZfB?Hu%rS%vZpb@2NF1=uBl`wFw!J;oS{XsBKznDoeIp&|eeAWTx3HusWiOqa896L-T??n=8V1vvu9nsvfKdpF{mymi;sUe3g`QJL5@!g$wv(5zo|A60l#E1M@d?5-CTwKD!wnoBm8waBJ2- z9G}jI^8Pe7gW9SX+R9m6tBiX#dJr&vvqsBGln3yRKPK#=qoP`1irW*h7NMvhVCMj? zh6x`wYrQb<5{+4M)&KjKIT{|~5~uiCF+z$aTtGgC90c}XmlhmacM&~6|6qW(vxnl5 zi4h8up9Z(x3~#~JsVQaeSB|>@%TSu~pgsG}6r7o57oO<>*Hf-%%~OR`97fWr)Ta~NeCScb+sT31 z3$r0qw1lz5r(8S`I8)`RysJX^muA9eRA_v@m_YkF%F;JZdJhYbLfDmDTvg0}@~LkEsCH?TN^gNvfW2$vYlt z+5`1(hEC>p$iX=tgj!cAUsLlgelqES<<*Ns`}rMFAK8JIWOM(_EDnnm1I{p&*&tY}4Z z*SbfF=A>(Bc2<_d(vn;X_K@E#EyLqP&cUrFwi53p*oqDdVN5?yjcef7hm)VfW^u|9 zvBAe#peRk>} zb1Z}-Rcq*?_-RDWFfwLgL{UHg=zDLs$_to3eToSU4MhlzU%zz5>Y%-4avoYH1M9{R z&Pc0zy`#?ncG6??cs!v#l(XaU6$j|~XrdobO)vU2KeNwTcj0q+A6r>(iDEa^e`jgW zEDOH#&6sU2YNl-MMo-QLTFWwhlQz{ z>+NY0#d9;)-Xz`UO|`lTByt)|*uz*l`-;48RLYYO6l{&P8NV<#Hm2{E-O-`p_j$xo zwuQRvGA?#w@BMgFZP@fcnIw0qef>A_21A`2$?vShuP`2@YdG?8l9e zT)->uBPA7b_lv`IDdpa#jpU+U9ec(@hnHqujvb_fg=%PP5Bj5OP>cHBo~wTz?DPH9 z=ee~w(I9srl#z+4%?Bn*5v1v-5GHMCvvG)6<3nBQH-#{y&A^c2gbr2RyLd55!Q$b= z5B9S^e+B`uy~oEJGzz7EDiGMIGm^ha-eNX~><`h=1y{}HEVSSchzr~YVc|N_E-J>f<-;P<< zZTWW#ba|8T&>Cd8-WrK6j_Y?@_zD*%SbQ0(g5GJHqwv7@)qcn`Tu{&Q+AR6PxAC~=nxWW_V>T0BW=%;o^j?lR^Kj`rbPyXScjq-kC@}A#_2mXhE z=fW#dn79QIX7JhA5j^xC;arz8AlOYxtd#5GdRFFOx_G>&PRSEXQ`0+~N-_7i!&|?9 z|F>#$LZGk^87nB`SQ|{mh-b3yQrUH?yP%41t~pd$d%y{3#Bh8`gI;;@yf8CqHLZB=PNGU8`8TZiQRy@sqFzz(*F zP~nor<~Z5Fz5V&~=cPei$rG4wC=Wwzr!~#tr)xYgCv`r_I-q3dWd@F#@?bb?g0oZ?T43Xot`2+xPn|b7t~ z-+ktP>Te`zl5;!ZujPE)I-l=JDgaUq=PB(D>tA1A4)A4gci2O!MbdU}FUO`3Di$aZ zfFQtz?Haij4o|L(7b{@vSx}i}^}KzK6X3b>r1kF=aaZ+DqKw3LlXzS9RpJnRM(6Pq zKuhM{clod$w6enMO9qx3LkZMDf#}F`k*Cm0D{}wHwv0~D`i3Qroe$w=gqo$y`!qJYgy4&fLrR@NH#HR+{tWRlXd^6tP@rA5G7ZQ9% zhr@enQUT_wVej-jZBF?59PH}0^*6*k1g2DPwStNWd*uvL=^Z{sDGn3rQhKReAH(x- z$cISjy?zvn9NEDr)myJ0>E|2|F^S?&<8)X~$St5@L0x4ZgYu2ez*~Z%8?0D0?qJeD z$b}Nd-Ms=BgSva_Y2n=jfGd!1dcf7`-GAYiD+@B+CGQNF!W-L2pyv?$wOFO|=Z}MJ z6Y%*Rc!)4|KvL)Y9LU48k#?8Y(>Gq6Wd1EQ{%C>l0!`T~)BVq0RG<~Vt;l1W&<2+g zyUX0UTjE(1C)QB#dwF%>)5$0EbNZ=ZAy;|zV?xn>2MJ>5ea`LsogkR=Xo$aJaNAkbHy-wrd!8o_yP z>=V!KKK-O6u=688-U4p-Lf~@&$bwoFd)^^o==`q|nKDj0m+BlAF+ttk+x1{@uJ<2+UaW(jnn3~EubxpI?4-v{rhP!JKF%O3` zyARX)Thj12g0L9_=6R;HA{77ufR3~)b3kzcVmG4p;HpzoDAS&j%=|yphyq2C0pvC; zJ2yerg}t90v5je9UQI@#k+nDrM<0QBtsS8_oKGhoasHEv@cScx^3<>-%Y$PQ(!Zv6Nq^sH2ww* zaqSfXWe++UzYwE0#kZ+fcKCTlgEJ#&?V1|wd3bKJiFU~?rFMtw;vA=#0R)sgIobaB zDpC-M*CV==Y9Rrs_=Xt7N0D+IDyUWZf(; zpzn;0u4Z)tsA0|Yhdfedf%UQFO1G){H1Z=faPQpsoi5&T3 z1J9XGIK$1-1^{+A)>`4)=%>M@``FYE+5Dt7`JksX-kv*26Y1={Z^i*O^=z(VMga0; zacabb-tNvKZ8R1L zeAJP@_D`ts^>p9arofXJ>rmz(%u3ZHX0F6=>__bVf-6S{cmntxP(+$tpM|+xUF+IxB|C*AesX~@!ut~|%R(#Zu>WFyRVAAN?-9Jw`Ta>)PyitF`EVMfq zPxeG4C9qu8e`E84`YFWj)|7ofnM1xHrTiVZ+^EL|4?-8Vun14!xvN2Z=TJ{eSWB2z z0&Ngv5k{aNdZxP1#(e{fcaxLRDwcRYKzySi01a9#?FY;doU)T>N( zcYTni`kxu`lznsZ9?%(pCF>d>^$_U=a7f3@zT^LVgGdSX1(J|39Tws_&F5D433TS@ zE7_nzvzM0?hJQTFx*K;dboBT%(P%gyw+F-%15w{QnMqCIn)FoxRs{U*=j~t}X)?)b zjQSVxng*L8VBn~gz@0Sq9K}fFA`td5wPDHyl44PC=g{WMU4$qg_K+GEHGR=`6cTPQ zuXj$$?8U|}g*qKKLNo8y{nw8^+X|z+-EQvqn}2Z4BAgUo9tU5K=IWS}3NE1bXrn~z zHC{0Sl@zYUht=+xO~ILwnzs)>T@JT&(Konmj>w|LAvJ?DbN#oJ93$?_bo^k^o)3rz zJqub>oyoiJ>`mI3c@m(J!vf#kvq6jU{kft2U0VCS$Vr>mPrcrQF%Qe{Iw}msxSP>_0)!i*nr18QeGa*5@pmYb{y z>W}WdyUA)Y5Z**mcMy{sA@?-++MjZeKIk{Sb%S#LJ2nN>*r3+?0U^*xA%oy*cZkW5K&v7JxeF0!h(3u6fdNq;_A5YPw@?de@B3{rmUu z2Guh&PbfvhBU^cQhG9h^RE_y-oM#sRQlUATIAuZ0;qOA+j{R~9#7yAaE{Z#kp1@-0Y z5lIRzDgYT!^$CMw?sUFtOt^!wAk9^?8wI+NYPmD5KQJsd5=jl|kjMv|7PF)}90AVU z%B38y!~GD)Z1@T{Yp$L3ehE#w1Ol(%iSEYAeD#DSymc)U4GctMbF0ukquA&`)M}yqX{+! zU!Hhf`pW8nqUP3*4*kOTcEeOR!s#0u$o1v0>Ne_!wf3U=1oSOtB_|ciy;PhPuthOu zs;5w^0RqkmoS_(T^5$Q_v*XE|lQy)K;sLjBVNbl4>DqKfA5(#DysPguQdE2X6c0qm zr9j8qgq`-+hxtgyTc~O}8gpo``x^T{-KXI13QJzN?Ypm=e_uVRo6#<>^FvRgKUPrx&HSD7 zN8311r%_cKw<}v7!|2F3HJ~`nBsa8Qzj>46mc8;RsZ#O%RK=kyp(1GZw^6!RC=q=5eo82ZOjArii=^Yjn z65thq`o3)G+;J!Zz6aR7bnp?ebH3~xV4p(Mzp2eY_Ci_C{PMt>J15Z09x#(*coCZj z$WKMqpFi)Aa+qnj0=1PAY0x@4ioL+eS!`TK*VtGr69z+xn}#NT{em7J;VbQom&Y96 zSA{Y}(;qqFxP31_#IoXvRhFCoBZ+veizh}YU0;%`_CU`S^2!(MD7HLykY{D3UcUot z==CUwu~Ae$BzC#{6Tzc;FyY`;U2;>zD=i0(6?>LA*M8eOZ*^w!ph;1$OMm5osS&|( zMxtIbk^`gS9A=+P`?5Bh?$boA#-P};w=15%q2R=Uy(j1Z@1iCpTO%A+Ae!qGyu3`&dbC_1drZuE6d%l87qei+3%*K!eba zCtboo<=jW8oP+IG?Vgl6x?RZ`yB5^9Z?0x$dKkJXC$GJUZcJsaOEmuHzQ41L!;Hkj z^Wb}D`TKrV^#!>LXA8;a%7OknuxjI1bvyJ}WHjGc2GLTYL9X-M(e2;+va)qoFsbbZ z#*=Ss-#C1-g*(ctH#(^mj1XBlx-0dsg-qWGrOTM3!Sww6%PiMyrRc>;Z;_T}jB4V&dxBBzU%uR)T#t%6Luu-xQdCxUc8a$d zr*!u8wWf3u2kz!=91mU}csTa~#8s>VPj5?)aK%<`m%8#i)vMNBH$?hKa5qrhrv}Rg z9@}=?a%_Fd-*af+L#V^$B7X@pde(pdA&)QG0&aGssWzNr+XQK!fRrJZ0R@~%g8nwP z>vp$g-!PZYc6qISW}61}fh(y+c4<6R*~!xb-l799R*J4#!Ou_08?M9HD7tru2m(v$ zHV&>Y;5~BW$dlEb2UhiiLg|9k&=s5cd79JK2{tC9K+O>B>^ zj*F^b+^t*q0LX@>msjOTR<>WJs^A0o__xQyP4io`nE<`;j{9kdlyyePGum|4Np3&& z*ytPT{Q8Pv>8DULarl!j&UWOvYI@k{LfIQ2!(h6*AipmquNgWD<%1`BUI4KfL55R?EJ+!VX;}qzu0Zp8+TRu^klm#y*hNBzi5fUWx?_n=R75*>$93;$kn|4FJ0jYf+=f zl5Q)E>^&ZXYg^7a8fh6eZ9*|;=<3g1U%dO_Zb-ph-8{6KrP_U${PSaX_b{X$|Kh#( zZor=J-(QX2VSeUw@jklXEMKRpcUIO#CNmBup89XcbS}3gK{ll3rf(=ftfI z2WOm?1fV&s=EX%0f46dxsm#hD@wdeWVm44;*C_2E2`|GLpL)+JoyjrToY=H}T%;+6 zRNtp7x71`wBzAHVZ|26c$;f3-srl=F-oMP0i*!$AO2}1*59~#~WG@%NTo6l?EU<3% z@oYj6wpd$5ijYtwkmWhaVcam*V~8DQrwi4rzAdo(J(K^A@dAv~$tjv@0t&nO_ad)XpP6@|7`%BPL zX=?w}BwrLhK%n9J^9Xti4=vG7zt9Dw$J^(A|E6D@KxkRDrbu-tM?K(8(wNsCYc6uoDvMB(rK>&9lt4(m~R!`A*YufXp z%msF%)`?*qk);~_kqfeAD~lOALWr{7b2gh!i7g!M*Ak(0(qK-p|4(d8eSs?H_21uc zT&U9?ITU%lH%3$8Ilcd%N<+KBtgG)cbuwc+@NTS#7V@yVU~R1QeP4K^TbJD(9T5D# zRb6SWHl$}=J%TSMRSxR8YGA|u{<;#|V^&t+Fy)xgg+RSYZ+1@Ptjzqfp@a}8MkhB8 z@dAejW!(Sa85R}1r1q3%-EJZbdEiUD+Us@mo4Fhy51iQ+pYM{U@ll^X579c~(C;C^ z#w@6ZS)UMGU?p+Ghk|w$m~Sslf9&P{QD9{nQ#oa)%5mm(nWiy4>?wB#&Oc9(m1;eK zgKAw4-Z3Gy&U*sJNj#$dR!XmvON~d+u+yeH`*98)>`q|VQ@d1oOsspqPn9MISdW22 z0=@EJd?cDLLK!Li*KHEJj}Ruiy(Da}2ZPa^-oXjI&tWEwI!)c(swXPZQicdkbht@I ze9)(f@vYBaE5kFKY1vBpOs`E5d~K+`^lGt={#)bn=s}GdW_N+NG=f45k>yC2Xo~S*)@A2c zlRYOrygtTETBf+l&E}cHovdGCRfwf%a1FTzKQ}VI9f|t!I~>i2&;!ZRg=%f86VEEi z?zvNT7i5N=#R!O`;Zng4Om)uET7v`Q|A@7ddc#XzsK+|Zp-^8)TXTAR6JFD;gB+*? z)57*&UKXNsXfWq{-f*u62qYWqcgxv*L(eu1dX^Nh?(+%rE{G~OXGbG{x&UGZ8soLr zSxu;RU5mF!ulx}8({p0$`seVJhULe%fjqq%|L_S6C|_E9$rHs4(U)O9TR)p0X%w;^ z+Py;FBXSqyI~AQ0>@&t?wPS$QnPzx)Y2R7LKp@HY5M zLziQsQhWBu9Q4dja~St`aU;ga3cp)k4l^bW5d3-Po8>=Hv(&8WUStjZvg)K}XW*>U zDN5r(WrW_fsAF8MuhO>ZF|9}>&}%gLZib^;cb&~bjMM8XV?*ExuCZ~&NWrHNGprgk z6Fm)LZ5zN%+BPUL7>1%7k0vl3T^-oVYu#8?_$be``)3N_x{2xqUN&x6$+5uMW zmbjRJ<7ERhYL*@QD1!16mIHL~el($ixiEOt^72%f3M2{Y4!2M7B4~EEIy_wD~C{yFXIG7U@u=1!W!~=flBSnUHv13NS#-3!l10 zbIG77%##}v-B3X8FNzt$D{JQhR9y3Mryp)Vv5s~~<+NjwNSSQ;v)gPhdDiR=bK!(f zdxihP)qZ4euK!W+EX!DK&@4#Id%*!m81RyaG%;dFEju7BfQwkF5?og*1_ox%EhK=^0j)*N>3|RS%wE-*)VEr_ zL=6-T-ZZ>mN>%fH_qoP7q4t9>?D^@bXto^1Z}xCWhP|_iE9e%IrOk3(#ZkEyh@5-` zTtWkKpzI7HUOCx$DV5c-IkWK3M@MEX|~W5^O>buT*AmChfegM2z5MuZ*1 z-C3qg<*l+q${wznc_pdtnE5eAB-5kZO)*kvp`@-%i1ldAGae51etl7b;-ZydTx^GC zT2AAyK=>Ua*;9cqW2SLmkPX{OpS~l6F3U-TZ7n-Naij#Zkn{Lw>&hIMm7n5PWsG-K zn`YiTHOvGTyccDyoF1~5_*+UOTZE!&_$GD2PgMVz2KLH(4k`FHfQwN{yWBxxsg^-2 z_>CK4Nxo|Hm-Ok-6YgM9$)9CnQ6B0FW))DGai<}_EK;f`kq*xXTNoD$$>+oRocWzCrts-jQVaJtR=_crTO~hzVeR{FA^Gxq^e%A>=ry)8q%XChZ;K zgTt%@Yw=3R1MR9nl4zME+j?4=kUQUa!wARxr9`$Y9?4GoaWWNIPTgU~6^m9w;0pxK zj8v(DJzQFEIx&WV!6@t;Y-}Vx^=70w(w1w7$_U>6MJh#OoRzBO-%Omz*&h%T3Pfv0 zNuY(31yU#Is%G%XVGEjyM&!;up&@2=v;}@30KH{vOzYPLBjul09M*a+51AHoLyL_4 zogHhD+G!*rh8Fi~Z@EMJT!BM#Kb)#B4_cp?Y3kIm=d^N)OeMLWU5ahrn+fh2rF0f+ zbG*{zS?`u&9r5hm&Q!ZW-i>D2d!4W9$_hbDBC~(zSUCmax2sQZwfdwxUmP0;SuxLE zR>%&6N)5c{ejU+z{v}Kj?#Cm@_Kud^Ga|2Dq{WI8g<+|uPg2~R6q~v(2fk{R4UJiu zbBQ0Zu;p`+oRi80!Ai|D?v5!bHsLk!n4pUBRw=m$DY$tA>>F3)@0+8r>af|yfh4{Dsh}3@4G06sy;lZmT(fnG4x%xdNN~*`A&$XMa~Hv(^1v!CH8X-jBxn3akcd*u>vpPry`s3 z4dH=na*B{7kpo01G$RM{O}HkTxdLzTX~A%rORlF5L7iv+DfT7LrzMk^80H3*^5Pt) zZb1kzQd|cJA|fJ=%fGe58z!nehm_KiQc^e^MPsWx4PgPv4e#a2r9T=q;Kv3+s+%3I zmjxtO7-!c4Hb0i~E(rJ~2{vK1g%_bG;T+kC3Lz*DW|OhYbNy+kn#WLv+h!sosJ4i* zlB$`-9_M)?8>Z6J;#%2*Z?tacoVc^@E4fPTH&QHnMFIrch(Nw$gUrCdu+(qgJO#KP zp8PAPVy;!F`9{*(+8WiCH9XU$H|OuTE|ADvTvHNhWcT)o%Iha*7>YH;GM%TTk!!&+ zGb_1rfFP?VK}U#e;6(0!WM)yPh6QiE^PYWkMN@XR)Gjuf9hx_1mh45Z*@JQgb!p*S z0W}4=MtUrS-zy?Rv=Gen#2vu(*PEQHlE&(SR}3o3%hO?xE(V%tcWRK$`ue=~>gwuJ zCSH{edFn=(PE~Epg-*JNdTm!$Ef?pS+uOH&p}fnH{bT#J+^$pP*v^^B@t!jS*SD0Q zr-a5%B9;a9O)dS?_Ft9om5L(_JQ{H9K@p)dk|F3u(BekTcL8a6eSK{JY7LY zl1uquSI*m4vXn^wBv_AhLz!*uJ0$2lJUsYZPO9}!zBIW#KA!1X1}=B7q;zEuxvF`2 zO81n+0+439Hu$ef07-ZsTyZud>yh(FY~jr&j<&AV==A&5A2rjg%LISl9*hq~XKPTV zm^qmxd7|Zd&z6hdon#-6WL4@&$_~xI_>tLL& z8YlyP;0OS9p7P*3NT6rFmHwsfgZB{>ul?^C`+@$S}$XNxD;}ib`~3mXF{fF zjO1$}AewPX2u|kmGI-yp!KbA>{U;9LN>HNu*DeHXO^($%@7Vz|pk6)0X$EtG-aUq` zHJs8NT93GT^(q>pa$>4QmJOff>kf8?bTc{r8NN9?RBf2191l|fI}JC#8h!+Fi=A!l z--yVHB!XSJrQy5hXNj+a=Sy|6p{O`(VZc6<^Y)Z6oyV;7U~*+*HnWX!!hC$LglAm7DSN*MSqklsV5mk|; zv70Bvw#}=iwS}}_)@OA(JLa%LlN+X-UhLmY?F*Y<4FAnYf2u+E)Hm15{QYqL&X4Zv zj-s>YH2q_LbPv>{8YYhSThgK6%k8zcV`8AXnH+E_?%PWot8rdz)x60wp%%R|F9M4N z{otj;#%u|a&~4|sxlqS}$*tbTRc+1M%yj1)Bh5A^_xgB}SG>p>2ofRSH5cgui26Qnnq8h>0+4v zKBiRfh<_0Ak|nxi?kzgIU1`Bn1Xc2c=dg5nPD8waElcEfjKgnS=d{^GZ`>o_tyKBX zbQ41M+*g{+3(ITWSWu_0I#I1N*;FP%cdz)L8fyHT#V-)JKFoWOH!Q9&ias5EF}N|f zVz9CSEnV&sxpw7Q;4`A4=00ZMO0?~;Ou9I|ZwBTedTb6jO#EG|^2mjzE|<7E;5YYU ztx=vz-ZPM9DqH|9r=E0v6+ai9AhT9UV{`qrsKu4L*uW)Pch=L#hE~=J_gjz3NOBhE zp~17Y*|F>)sf>%p>Gf%4s%fdckFM{3fJ;_~A(jk>?Zl~aW?SP!+ulQpTG%62ZXFbo zuCO9uYHS&`B8s|X^;^fZDON0vjl5dt3U3p%S;d__K>EgHLk!*~29pNnJy$Xe1x~%f zd;9`*Ko|HrzVwPW--si@$rWz6v=q90y!-}BM=I_`I*DtV z!lnUQs)5%^+#ofFRcom_-#LJK7Zzj_PfG{grWHra1};=DO#>K%LVe?xl7wEO4;Ncu zhM}gGmYZSlhr93^QM+8VO+un{bbNeQZ!gZkW#S|>ni?#77(lx(W`JeNpN^#!?$2EL zBr68TYik3y3;v9D6zk_}U?k2XGPVj@;=_G;CorIME1DwUF(of*H~ud&RPtf|$MkeAaS-r)^BjT&oMs8v zbe>iIc20^-%SSBfQAI}a^qEE)XXvFwS$}N5yT?J4AlsvUW5gr{Y0|aViH(ln<{a-e zuo2w<&DRXEXvhX3@dT^@q((*$U++x3?4OiKtC+9Sja8Dhsai_~k}?%u+1gM*$`AHX zP`mFBC#e`+)eY%7}42l#d&FarMh|rPtPWig*2fuR;(_Zc%7-&-;)o+rHsC4=-z=OJ}wqo2BCa7axEe=ODsjE;sX?Cvkjp5 zJm!7S!Mczsq5084LY)e~5RXR69;m5mKK>t!y>~d(ef&RuP*F-Hq7daEThq#F;F#Ha zWt6@5P83NxLM4$^$PNb?l@T(tcSeq#z4<-g=X8I**Y|f_-|zLkuKSPsy6@tg_xm-T z&&PV^F+iIEwt7uVH+NvF#4E5Uu;rkn2c>URh|RS5ic>8ax`%Jez2;+)-@4$BqFnB_f-p&Pr*-fQpXcmt3 zrcjpW!!|_WDpY+D&=tOh)X;)kBEOar90*k@I+^dfxS#r;$Gka41rThpm3Jr2`bCs6 zHKC`>rCiNYbWJK^Y!oy&Vy7m4xYZg|rUIpMixlhO@&V#hUaSL zol0{Y6rbJANZ-y*_wPeTTS!rpc%4147=%P&gy*aJ>R?~GE<*#R)Dx5SRwDD_kwV>x zfYSkA<=xDg-;~Sjj~ndkS30#U$YQw^VMS`3P;TIY&M)B7KN`(Z)iMinK~g#B3q+tC zU_?o4r?(9TzI#vRYcpOhmQf_9oBg)+>y!~RbpbE?qsrv5pVh^47Iwe;CtKYp72Evu zbTMlAJ{mKlLA6C1zzNG57EjsT2pOEW5`^;M3`%eXrsZx3ed=I4mzyqKcA?H~qPJqo zDfiaq&o5vl`3Wr_7?p(+;roZYnJe=1TC5YP=wccar-MWD@<7HX268;KeF2wLBXs6H!Eywttz~35AWwNl zC#vvM2k}5Z2?-l`+`+0_(yq$z-$<<#Use20OY-VKut$<=NIIKoOP;=`k|q?potpK? z_J2Wy-VBT%d6$k~adejno(DMSgSsAMwCR(sIOge#rAAL%Zbl@3cYZt}T(mb`UD?(C z#}TrSWb@p5RBbcSbxt^COeo7xkfAXsed&qH9D@a9{EE)$fR}nXZW4`dWi6})HHrLAhJuol zz}x*KLL+V$!}~I9ZGRNmloZ*QGOkE18Cw-PAz_6Mg{oq3EW;uejdpa#rU>-4r+;e% zIvSfI`eE1-bg-OSpNt~W=ChCl)yf|@Y;Y}_F#?4;8f#q&3khYc|8i`1vf_JC`sW`| zq43B|5KfTGJA;M{ezse}d;BTHLPfd-_uav$*2V*@zQxuXh~&S#`u9-p0!a~y60=?M%O~ic@fW-J zxl~gE1k7d?HkV8N_dwnuY9pKf^Yj6hRXAFhH2qTU@Kwm@AoLLIZ(@8-?ycz4tOLI; z_VVM1;B-&XNyvISe5)2fAmC#PvlI)zBS21yK4>T=S~aYMVz^uCfpzd&e~$|IO@x8n zK0@MCGMShn@{)`Yn!?zH1_&?bwcdycX)PFG*3U^d4~GV2Ax0fm5iLBAM=;ZKT4eX+7a z;*#h^;6K7jdCb*h_DGb(s}JBtYuZvc9z#@bd;={#vmS6zwD0ddM-SUff(v57TkPDOquVTaP zTiSiayKEX?+`r#JrI+!!3%X^N)FW_cX}V^1h{~=n_^(ysvnD2wfrd4T2ov@M$_4FC zTE;Aofhi7N2?+ySy6ZjnMdz^*t@ob64ZaIEc!q7XnO;P`9o(zx~0ZziK{(eKeDRc8Nod*T3G7zI`FF{Z+OHrcTJklXBA^e9SftX)xPp2$sy zqz;+du@IpT3J?TWwMwZ!FLsuV581=0u+?QO&M>8O zZ|9`%$h!{{+JjQxn1yyQaE(-r|MzC7pF6C_S2?iJzeGv{7oWL>mG24r@>!a_!BoZ@ z8Clpq6Sa3y1hdCiTe(`U*t7CSk`ZXXogI$pd@`{@9#<_z3}Y>6fCQf zIZ8%d-|P)>JH)Lfc#>1KP~)Y!&H+59hIKR=vyW#==ver&a6Ee1hgVA}qeJ_${+R$w z!O6-6GqG=xpJi)tv3SM>C`|@UbjZ;zwNJ+}MqJl!m#J@8gR*yYI-U^FK5_HXV#U+0G|0n8qo1LxtUeI)=V3m=J> z?urQcVR6)oN}ih`^>zz~)aCj|P%{eHMOTHQ8M8BkiyppQ?*l$= zA`AF$58EXTaLHnQVo%OnT3{Nyz0tPM?;Z*;kstEE9PXg}Y_6>gR_4}+yK{%|3JPxy z#2{?n#aYD+5(pL{)S?cj%Bfspsa8JAi+F@RVniJUYkz0Ixo{D8OEWn9d`CqCA)*er zWC9-$@KScognU*qfdcUg{wA(0yCmub$rd3v!3=7f8uM*5bPwL7Lfz7O!W>qxf5Z2o z$IiUhDiRQxA|+~*UZjCF?;S{1cw%$ob%-T9N`N@?t4cAK%s1a`Y$OcnM`FV5mA`4G z$aI-}I~=g5lk+aRdT$v+y)lR(t2x_!5=BoO)i}c5(BwfbLb7#R_8~X?&hMIG>u)UL zfthW!?;Y=JAL%0C}h+E7qsa-$nc7Ql1_OTj<<09&)e0l}o z!doshX^JBpW!BI%3{;ryd&W?$guYnDMS#NZ-@-p3Z3}&KZwx@kK#HAb8HeC+=>eqF z7IOu`A6r@+3LkWHNBG)ERcAHcHPM-gB;ftOUuvA3cOg{36l?QbX8bn|h)ASy1!Q8r z*vem|j|)&MQkUi>kLye0l#dJ_hNB!rJywr-5tY&Ozu$e=GFu+&BX}Q2eN?{6<2EV; zoymH69+YgY_QLj>SoMzyAoL2jda-L16;GyhicJ__rb(d3Wr?E#Mh-P#0-E=hLti+S zex(Iv*HJb4LJiAocx&d2RJN&LJ9L^0?=z9_)I<_3YV`x*>(h7)!X73iK^Z#`i&=(` zpD9{7o-LS}>qS7L1OLE{r|{(2A1t7S`Ipg!UZ<3V5)Y1Cx49ZaE6wD&cwbW?B9Y)I zLmeU(3b??_tOFdXIb}gmriY}cFU(7{T#gVdEDAcF&5N=#SlYZQv%Xno=*x7$Z5{^+wjR_FC#Z+4Ac+4kuJ>6BUVeu(f*xS1r11E{w8)SKwJf0 za_XT$C{s)e@-A4Gl^vb>#qhh?A`6Z*M0z*)?227+*xNryj6LL@%~OCo@7L2QcGTASDRCuDDibI4 zV;@SmsjI5s0>f$WS8OEtfxQJh6sr|6jT0;2!_bFO5z5avW7=#&e%qyR?7l+I+A zt$(i1 zbgEY|nV9Fk)YkYHGqE37(4^=e3vkqcMSm($ISEt^^J*yL#QzskYULw(3M_0IfcFoT zd#?ub`$$zRWd52W1ow4yb*;=6v`oLg|E_nH@Dlt$#fsEuqO9^zM+@AB#ZQf_W|^rOVqeeyI!Ho)WiB_>D)VAvzRu>Q_oVi^@MnP;bXj;O zW4Ff)V;t&xTobjpXn_UmEy_CXi@#N#X11oB-6YEX_p9j+p(`L|^ z|D9#ZDPJD~kp^IOu!_pOkm)__WN>Zi@sE$d=|a+P<5E|AB|>l)%e0QfO5zUIh`|3g z09h?Y2PL2l(53Hig>URL6(d;TF#QXX)K(#V4TC-BJ$ng;&Q52bEn$FAM(&^^qoSf> zx@tNk`2iO*yHN($X{P3pvgeIIJzOdFc6(K0+O)jJOGkz|*z=`R9%n4DmmjE@7u2{{ow=^}qg$35*obO7TA^GN#)B2&Sv1MyyEi4pX ztiScLx+0AF?M>*{b`kyz4szCkD|}4&sEbq7$l)o~Z{w!bc2GP}w$Ii`4@!$%@8FHU ziZLkPdu-%+I2jPZp4~?61~Km>Mlefc|N5YuIcSHZ&niY}xT*+Y+m**0H;~ zWrM0T!C^`GjKk8hAV$+HJhvkfBkB?BSrQWA@j7F0qG0Ppx(vbr)Ce5+W8M5!7tq+0`>G zeyQlI3Gd#``)&-?TW{N*cz*+4o1IaX0k)cI1rr@EGw^^9N+ZcWjiN3z=3P@mG~FqxFl<{S2rQN zb8GRr|EI|W|GkhL%7>Ef!@k8S^Rmm_btwrqJXKBT8(a;5t@PJIJhfG37X?cbD5LBy zDa5?(7Kikg~rmvL<-VW%X4H@Qeut#O1e4yV5$>%u4W(<@&(#=y=-`{ya*OG`2M0g z=5&jBtp9zAkDmeURr*kG23;>mM?o@~_LL-2b=3_sm&?}OJb*qSrE4~ZDwq6AVoZ0W zbN+qY_z5a@t$eGnAZ_Fm{NFf@4y!^m2B?5XP9=7+tx?M2>46FETJvj%1%4#*`z`LoUC zb9qv+ERZR`*)WXXjPh^y_CK5)0aEQ>x}ZgE5O~mw-uUQfOOoqc-x0<$BhGGkIXF=g z;H0BJ;UbZ5hYUmU{mqulyB8lo*c~v@V96G77zywhuAE+lP18wNxp9Y=m)FwMQwM|v zZL_np*DC)#td)$bl+d}bOD32F4*LpeWV8*EBvyt!o8NBmruw41Kl>tQN>pN(f3+Z5 zu;W4OF|81(#+u(+>0b*ERy9Kl4_Ln}mC8%)gQO_3D={Rc9doyb%iMF;zy+S%-CvY- z>oL_7kZ8WXgfE?5yg$$cCjt9vsVIE`WnzmD2RG)(moqx~wAIJIGg;d(cN#y=U!3nF zWx}J}&QD!$zWmL1)U$}cd#w}Rp>6cb^+|=;1E}=x24~Vkmdp>!ztO;-JS=rZ_vqJMO}d6K(}e1}HbBOi)Ut`ytsIhm2?45)lac z`&~sqwZ?+GigV!#CR!fEL3 zxxW2JYm>lYQ-?ev(?z+NmU}5-X->RjjaeO=p#Xlx_}{#5YguXBcDO@=$Loy~ci#IA z0aV&3PzX9CxYWO^ zzZdja4Yf6MuY@6SauAqP;~ua0AXlpUB)F2B1Lkj6@scuHBW#(HugqY~2r=G8|GS0h zopv{mu=>JXhpgOV4Y3~nN*&7Ah$dfd3;i507z%|4iW3KQ#C zMdh-h-5><+hL6u`u~YX@EUvg)$UDxyYv)>5?0tQ^<^04AXybO>9j^@e&*wp9F#%u^ z+fCT{k+TS_!4!*lR*q5;Ti0N@WQN51J^oY%?QB0_ZTPx4E(2!Z5`yx*tg{sV7IdwE zbiywR&jsBn2ztAle-z$;WY`s`ksq}}G^{uTr;rW0!-HBM4zv{pAPpc9SVEE1 z@b%Xcls}n$!vr={ZjhlvdpxBA(GfJj5sp+Wg$HR!^( zjMIHo<3DBr(?oc<^7aT2QA`G2!tIrHkLw4?$zp z4=7_oGr)}XMaS>A2~&)0!Ji0ssH4T+qGen<_`g223Aspiq|4zLJVY9iKZVY4V=Xi$ z+=2gu4+ONIk@93$WvE5B-%`mrfzNLOH{`jtOW z?lEvyGvS3rS{;wo`!?tjJS8j!|Na`lb6V4LbTARxAr78VYSUQ0SzDm^Z=m4e${x`D z;C!O$8vH7N_;?yYD&76k71V;q;66_LH@8XtcG&1+_0#Z$F>93B-OX@pRpIpb5>z>? zxF?(HNArGGj{$SWpaVpQHvtR~$iP~%*LbLspb{l;YRHP?1E7h96Kid*5c}}tXm15b zB>{V!8F=qs)7|mAr0y1f>T@uG?v9~JjWV1r577=D- zFp=j zNKJo`1bP+(6NRQ!Ui}Sxu0Ah=hXAQKJmo{kojpT1deqS~Qe7F82+$h_i*64r8v+eZ zc0Tk^gDOz1g8x20{qKmGdXd4%AfT=6I!7%S6Ynp8%}N@`Sb#m?*alJ;%5D1d#3Cts zu93KH%}2j$BPoEA!$iI>_9HB(?mRJzSmXya)c`Z!?Yp}-jo zl@5&%o)YCt#1r(BAPbGkMgP{4Lm1F_WrZLbSL)ClX==#RM~;;Pe$<(N+3fU7_k7arK!m04^niHZ;OF-K2 zB##$B;fvuSKt%xXSVf_o^DgS8LM?D@L3t-|i@rx@Bq5BSxc;mnt^a@qiJVmCF-0SQsRJ@LczR^WhI+srADZD+05hvU#U2PxO&W z_RU{lm#kA_+t=)}zK;X~O%ZSCYS<(36#AtHNM;A*CSJlG4HRUpa{|QiWHcr%4xV*D z(J*B`SbOuXfI7r_8<0W`JvP`iRXxN@>0Y#^6!xVfA}YAp=rx;u5X#hzwW*&>$bT3^ z77M5nFyO>0iwbu{NMJi6!o~vU;CrQx80+nPh%_Z<jR(OB#f#t-XUU_Sgt0!^^%2gP>QH@ z&rqinkX2Ff#6%(Y>sW2Rk~^sqv3yeC>cB3}xg?mn=bu~WM78o09%eww9uoy>QO-b0{Ee6jUA=Q~xQWw|zEzgcta($W%W@2S2tguy z3RHN{IoL@0EjLpu_utMt+sF*X#Z({Dg&}=DqIQ~JsLYb{9)JW%mN*$o;fugDh-a|o zI!m*krko;CjTFLS!sx)dyyxI~#u!cp?GmanPHNKp6+;CgCw%8P!qm)ljlb{@k zA!`DQ8FNzWC5r39b_1#NR8Z7vg^{gr?t}h45?%6hWZ)a#!1zLqcjn>NJT)I_l7KeC z`CL_>~22qQ?lTB_=$ z#WBD+jbjb^K++Mx5X-DTpg;MICZHS4f=@dEQ2l#K6#JaxtwYdh0hQ6*D|H)g11b7x z`;5AiH%L*UF+ZqQkSRM-C-4!X^R3Cx#ku;6XhYs3I`Um`gAnG@JO>&A8NdT_S~d(= z6%xeZ;~Fk%$Cw}6-v#51YN2lD?Cd89>u=$Vs=r7{gEdYno zY;Vh9s0GU}4IrP_HWvof%w^IQY0P}ed}VTv7L`6Alw;Sb3VY3zZ7HAf=<;Avhhdwv zwUo>%AMDy5)>+&dfK#J}XsgizB!^*B5SaY6f;4tqDB_$K9wxH>H%%w<=67g{L|gO3gme4@ zqkv?(M;ZMKn{v+r#B8z|`XN*<#?%JWl8Cn!%eNPv-)0Q)V6*C@q$_~FgXFcp$aUlI z@5Vizgck0&Cb@P8e@{jNEC+E@Ipu3_-~s0JgjRr>l!d~qzX(b5=}j1P>$kb_^0fz8kFu;FWqvoS*Gg?#dPws z_m5T0n2EvR6sz}oWXQ$?HBq?<B&({5!)9*%@@8cUwNqw;Z6irj1HUFrK}xtwk_`ZXXRlAd%Q zP6?lo$96F+ztuZbI+)!zSHxI%$>4~96P@6@SoCh!;J&JAiiE_fMph>uUUreG-|H<4 z1+5?1O7^m$ z)$HHRP8bLw1gnnM_zM}A$#{3U=>=JT@I$QrO4w6Zme~C~4;t*>GqW)uQwT1n#@GJ-UeaDipDkXLRre);clb zi=oPR$fpv3G!YS6Ta-zqHQ8_!Rr|~L%-X}fvOf5Av^QQ43u*;7_2@R3>Qo>^txy*RDE$J{71|PP6Je&w z7tbD=Nj_R;np_b%E<`ov7ASbqU1Cv$B)iFx@s0|*&Jj<4d-__?o(R)$Q)7|+&Zb>| z(YL$#yxw}lk6k#oAWk}Zje3DM`vS$o-zAUsC0-qnFND)Qb@nTRxL}XUM}g1g{cn{W zFwJqQ@I4C)GH#{zgGu|ePy$QVyu_XnJ`{GkMZs|ByY;mx+wGx}UFVw@b>JL&s~ow! zNot5m3%}NH-wi{}>KpfLOifL3 zEr?5_uQc4aMZ9}lq)>l?d0pM~CLC-dV z-*t?Rj+*cFuJe1 z=IL&^*>UlW5r?aDWXEqL68IM9Kj8$v1qr`f?bIsF%R@{e;97PRA(E#SoX=c!CKQI8B{2X^qV?Sbyxfy9e@PS`7JBXLx;8WHZrxQ# z`=kf>L55pb2c@XfTwC^wgTP|xlW&zcPloId*%jw(X74Uxm*#a{ju8m#%onvj)yI9+O_MyH1zmj1EY#CO>wq6ebLM zZ}gE%pP!*YLxLE}?E*Ym=8Y=y74V?!m)6xJcR82572lmw&Qwi*;OM9V^%q!nyP&|a z*>2b-pZ~I~AcAf+!fTXTQe-P-RPR{qd9!QjTh^JJmx*bO- zh0g(@*KSh7<;WB&5tfHd1objPelVcV-o zMp9J&OB~9eJz_0VSy9o_YPxplQBP48m{&E5hrDKr_C?|A%SOn)n2vXad2k8v+Rpof z9;)C@EQ>(>>5SdoNkEe<;s-sH=&tV@0%!i-@A|&~%;+BpeC6J%g!uvf$eR;efFZwI zoTJa1HBS0^C;=GEeriD&{|s)SXs`PQFD{gvrc2IqUi{c}49x7OY)u5d`G!GToZ?ab zQ=(!yVWzTdf4|+OC^35LOqSpu$QL#i`~=-Klm#75hC9OM2)hwU)WW^eUOZ?u%nPDt zObnAtqE=rfKz_z@C5}>qiK%Zz*}9j&-v6i|Yj2|TriJF}drAQV7D?uj|bDA|5#;Nd_Ip_%pTczYFAaP~zMt$~=&cc&b;@;Z>q{a zNw$5l*Qishcqa|=3TGc?b>(}RK#5#m@H#BG4H7YmCO*=+sV~?dIZ@O^nC%qz5QOSE zBTvBK>~kFAi(&t%Wr#&b6FL-KZLH6SVMjyDtXI5;sfrAQfoW>rOO34csqY1Burk+Z=$R3cHblT@#7W=|(@^*iP z&CBZn{Oo~B5T2aECl63Fz9(Z6Tw`q_AK+p`$KyIw!bA`Y$}t_(HIX@|>YTk$Gdmm9$2wBh{cQUwsPe zHMbusvQzvw(iRf7j5HS3M1v-a_6%2>Lw+|zUf21+oTvqpM^cpNgZmgiJ@|2d4QwNp z*WSLo11rmhk^nBTw|9-)ygE2ZA1yz~1b8x3q}M+9Yj1H+T&eKe*4m2}_t-h#DH^An zU1?EzHAP_{(9jYz^_B%)xQ_xy#zhbI>ZjH5)q4k>oX-NE7lB@*YW@k2|COvOyxHn} zI~8n5{B2ZwW@ow_HmzWLU^`~j6=H&E8oVIQ4jK9s-sj-s9Re-28274k zKCc#brQCnxR=n=si{D`=mNWXlK%W2`LcPx%A|>eKKh=5MHda-*e_S3L!_~MoJ-l<} zS}BZ&SJ(qf_01yy9LeSs9s-A6J8ZW@{beg#XV{-T-K6 z>^1M*P+|9TIQayy^p~2h#nN)Ndqpw$k&Ji|ciIae|0-kxBHDhGI0jT82#xn|*2)#5 z^l|1$bopeLe@5AH|7wRjvdJD|KQyCIOtNu>wSY1W^#hciqH)5F4MR>@JhSn0S48`Z z0k-4t8}>%hfZNEZ19%Xsg@X%{>$AX6M4sMbk$hg~NGe;bnUi5v#?!raHQx6r&#!~$ zqen5qalCfTr0r??5KhwIsRnyfw`PXKPh>sz&9IjWWwbEp*7rVws+{HIzejQJk*IW2 z!4*(a!iH~}N1PtB`85rVNc$P`m$9riPah5(6Pk}hyeeMPU6y36OO_s5*m7;&xEgDf(djwBb9S+frZ+l}$`%V)2r7^ULvm0ZMq1 zl)65L{Y?m@5#Sv4g?)%nMFB)Hb5*saTQR_V@N7=USzo#d<^klQNhga=`(X?-93{>6V^ z?m-R$Lo@@Bvj>a?Uoy~jP?j}#gO#z{MOaqY|F2&#l?#j5DBs9iL4d~;!e&QG5ExSs z4mRWonZteG!Y|I6UU@uwXz;4u3DvRa!pcqyYYY~CkVxgC^X_Ik40odq7|d0lTae)Q z004X4ynL?|tTbd(d8!M;E}(H(lRN**KRX&Yoskd%gJpd0Q&-D0Qhz^h*-OA~{odq{ z@t1uP@j~1FCk89-I~=<*wY?{ZQT5Cnrj{(_(IOw~_l3t$0jg)f^ISd_HBJXJ!2?60 z6&MwsyzO6*9DYD7GylC@Q@a^D-R$@_+im+_(zA?!@F8rz(3txwy_VP9xCeu|@fu!o$zk8;~ z1}6O4C6p*vZp!ZmA^(EynAT8?34Zyip6La8cdCB4d*5+s9X8^UjAG0I<5(UIauP2< zUuMPooyPkr{%3;>q%5&i{XCgy`n*Qa3`%^&ayj;#`1Hr%hQ_q_t|m<7817=5ZFeAW zczx|P4<)B#-R!nYF3e8pkLozybYIZzH&HE{`U{WkYIVL|H6 zHWXCRg+tCQdVd0o@ros8ubzLu7z;aSmAiOPZP0gvHN^Vn8yLZ}dkX-atuw3Nih3WS z!u7xGe;Jtr1qnOm#vJ0@Ajf7i65fY5&%%0w^CHaw2p1xr21(W4)*lLr9~iCi<{#}2 zS^*+0_@_7mbY#UMj-Kj}?G|t`=ehgXw*pc}h1P`|?Lo6VcIk{=^|zrg`@V}v#nesU zwF5%))n}d$@tWU1+>&Q4_Zp@!Z8q@3+c55kfgCC*h;IS1#tW+&Q`GiWi~iu!;6od} zCU|YE1Kr5NE)|johTS-cN7FE-8gDS0oo?eFzC8eLgGhE28Y&qa-LB5}PGfAfXe;-e z2KfAOXOPM@-2U+yPkR{KVx3%)C~yRc5HTf^5U0%3`xYcQHmd9ZZj!_PIoukk&MC;3 zLFX3jEKk_LuUNh#pG-0->)IBH*TCVUv%FB~T*T-m1A#e2bTG3^3qG(+E@A1*GaLk!yEMAuaAwtp+icz}%io>{h?B3XN&Bg2>lL5VfoFQZHZd$Zp9B(v z_zLNlqhrySnxCI|t|yw(>Ex^bT=~GL-{bQY%s0~Jxcvbrd4`;Lw6fz>=nq=C5gfvg z8-lWj301E^`Y1zvH-e*A#Suv1s%q^FXmIPkvggJ@d|pb6>X-euR4() zr4&6g$%YY5Gx-|nvGr9K@jea_XTh=8QpX4N+)A~PkW2v1PjyU{Tm(p=h0SK@HFFTc zM``6-M8;e`Pvg1y_lMSWn`fRo@E1Ud_CF5=3X%&ORp%~llA|G*HswyHR;Q-5PWBw< zWDFGWhiTlQwC6@jrBj)O&e*F$k8_odSd5dCY(Z;@`kO|)r%wV$;k0@UqZ-&&)>A%FEK5x{~1L8%Rl&tK9y#m^Hd)+&@81mTVf7qbc&DA4yK-+hO3PXO<@sYCBXo zFR}W36y2wDP(|6(UY8(DIF#1{K;n*|gXaI*;PaxIuQc#>w*IDQWNCFoBZO+`g!n_!+EhwKB zHk1tCA$WVCD#R-?qD0m0^ws%ixn@oiInDQsjnUTkX`}<+3?lXnn_J}t@7-D>t-TwB zgn_O9HUU%*GOw?j5aJim(Qn0@*_qi;cx8!v`&M9iKEL}@v}Fb4c(J6z`Ef zD>i?^b4KlQ>O@R@?9$N^eE^UIs+MTxSG9Mf_W@0e_d@%*6(eLDD%EVafREyPuFXK; z5U7DO5?|xU&cFfPm3Ti$PpsPiX2_ zigjwidtY;*pGgH;5M8gEEWstZpa{YtJVS(|J;bo0vWXXcda-(_4DOVV@dDhbu=aqr z^qWCQ^`11P)(+SiFbQyy+NX*q0m_9J$a~@ojtQ`YGlJ3j8A$Jd=puNcBr{xtVxVr$ z=Z&M(6tEDgEr(oD7R%Fz1SZyeCm~!N-3*qrOVaRnvIxhf3PaPuV3ox1sMw|nkMK}=(N^SrXnj9} z3@T19QfCOa2Qk$li2t3uu8fGJ+<3LNCtoB%K;kmeR;Zgi5{;yvka}!?zM#c{t%?nL zLyT?~LT{qNKm7j~J)d8uK`aPP@{k2LKV~Px+YzmUcgoGG9u5&9h5QB^( z5#O!P;GoGftsD1z2gaF|!W>`4XgPD4I)v8SfeU$p>nnNfEzWae6*aINIJ@3BLlF&7 z2P1c$7=`R>n=i;DSjh{Ypu7j81ALxhf3-SYXC!n%z>j)!Y5}pxoH$TA79qNVPk!D| zWD8kI$T)3e@HZh6FPVAw;1Y>*Hz$doyc z=@%hBx8@+1yHF!l6^Z5yyI_E8^*41|8pmMT zzaN+Qq`=OK_-2r?BIv1(bhYndlmETJbdetacP9J7KjRwCVbKNyJKjijpt4941#329 z@wYeNE~GBTvp`v2*Mm4NJ`7$*6XnqdL!Njm%E<%+8QucUEM5 zu$R` z6DY)^w1)&KvO5UbcD2f*q%KnpBR7uT+67vz706yz$WUG%%IxjcDF-VUcI*9i=eUz_ zr`0u$ObrNeWDs}jc+>PpmN}#n!0%O`)?5$mcudJyBaLQ z_A3c8LqI;mUr7ZQFn!LS1&#+=U63EKGY@wS(K*7ozK{5IU5^%_d+DQ?(>*!IKE%KpqF-}avtV8%&Y zD#@mhjtz6i-$JW}4NG&NDCr`0OsH&c_@>wRm2LI8?DRgpi3Kf`NBnKS%htvHTMb$j zN#L`D-}T&o$Fy{RZ#xI)AbbsHYK5?3bx)EW(8nk%D|1skL>6gS&FGJFnfiQ<%Qxn~ zkq+JVc`S~+!BN!UI`qS6%@S8b?A2&7mhLmV2U7%&n(4gPuZy-_7Ww+jG2YU%2y_UV zsbz^lH9&lQ=70yZP#!5XA-#V?^=I>ZgXj3_R^a2ZnSG{|#|x)BW^6KOHLuPw1CyKW z%y^$Z(OFyyd$fgZ?`QTtlf52%vvHq?wwxQ=DPH~=hy5!_;oPx__8bl6_zbLuKHrDo z{oUbi`<+^Q{lb~aEPLNfbUJ|mo6DE*hMd0;`!C0tL_TMk0v#`~hhQz!?o^~>W?bGd zRM5z?4Nm)^pQ^47=jwk#4TQrk&>)niIdT}rSh&m2C7$nId+8`G7`U>fP5zJ}c6m$j ziFFeJNLj?ja|#u&Qo=9vxY7tz;;L34YOL0Mo5U-%@E(-E-3aJg|5k7-G_C66IC)D;;np4a z!&M%b0gCnD;Nai5ReQhXxb7SC;Bjq(jJPbsC1$k0)$RJ{=NVs^%GAC%R<}BxnPUYG zz?yq12)FguyU3XbZt_|!Xw=GuIr{T8e#{CQP&vF#|N3!o^9YHEKsN9JaA5-L`>sj+ zZg_%_EA>0(R-dLBc~EgZyb}s6+{2)NDH#P!>yP8EDe1Yky4v^Caie>IMiLJ z+MA;yt*L%Oe&t5?ph~d=UuyZJ*g}aNOGP|kx%ojYUjXp0a;g;F79${pc`law!q$=k z?|eA;F@09;ycFS?g=%9M^x1_bwJU! zD8@|hxbcb3Y{SR6tzF8}J1d4Uo4T zNqPr`ETKQdWnld!V|cQVei~@Z5hAPzXWgXQmd_<|yf*^te z@DxQ)6za-G*O;seo4Q}B0FuE(pxN1P<_>fY9_1d#WY1rLK|>==n@axS-ocmVt9m#E z;nrX*@pvQ((J#itobmL0^*M6p*{m8|+!BOT{eeC{JbFS78hI4cm@SUH9GbWAxI!G+ zAYcO<1?Jo{r)i}FufIX&(g)-b!BcgePiry@r?0@fu}_^P!L;uHVj`e4%8&;S9QTxL z1=#>@4M9qVBCRiIzVodhq5Uib0EoqW)UoHz!{gy4pf7~G$9SNcbwGZP1h%9-%)&AD z$pSF{aFjCuZ-9}b;7`CdOOY)!(9F~V?KLpi(BRl-ME3I6xoKGDWDrnk)T(>e+P7?2 z6@(lJ54B$K5tQ4&Q_BJ6X5Rz8ANe*w$4@y0Fi__(Jh9(H1z-r1g#$XYKebntpx0AlA& zqjPUxnA(D?pLt9i#G%GK)!Qvkp`olbf@-Uv&N-T?#dj+pV*H1<8WfXp zS!_VSKqD7zC1H^wZS0dg}BC zq4Rmo2g7a&%4=Mim5&d8MAbh_+DvaLQLJ)8;d;Ro{qm-0;1+L{w8^NSa-m9IYebZ zbBMdtD@DGgY26DOy4}*N_w>>0rES7~epRSH zGyJ5+^8jYl8z|#w_-;I(gF?;@DwY&+4A(*IBh6NNDhN|ul8n%n-cZlq-@&TZf3$8A#Qy+{b?BSE|aft zf17oHj{5_#Esx?hJP5&*SoF*q*@|2oiiw_lLb}p9c6U-X=?mQgl6HV1U^tN;02;b? zQzx=o>We0WROiHM2+6sC@?!Ow1R1%Y!XuK@W`~&Yv?8s6c_$Vmp39h!VX&_9gcoW~ z6t`AgB&>L}A+Xa@9Z?H3kgg3YzW?-sR02Q<#?`uGNnR#eXE^FS4}@Y@!>}n$U07J3 zvh97qO-?F7@7(kHtsWMgB?vp)IG^}(7Gp+tC&iKPOAXe&WcuNV6enKgh=~k_&mGg9 zfV(PuaoSBnOXFBeMknXtSHMrK;`#SUZd8Qumq|aUl&a4tT?Xp) z@OT+CVHU`Gs4~m^tOeSQrT8y4d}XZfmkj-Pt8@v9{3@R2aX0~Fzj)YRWgU2-4ijz` z=G16{OL3ks^|-1U5Rh1*=PZFfA6U|vhe!nO+X_^Of!GwS9RbcF7Feb5w-0O0d`btr zC{Lew3NXc;os}~B2v|ywe0(B;{qg8DcyGgVu+i%Rs~FrCRVhx%!+DK+&gfo;|BtWt zj;Feh|A!AMR}>c+l~5ts6j@oNIEXT{l^Iz%c2-i^bz~HBgoKd2M+rqZ$SC7vAA7H3 z-LDVV_ji9E_v60r|9ZqZKA-pdHJ{Jd*q`B6YjL12?*(*8=I)cH6+7z5Nd0E-$^EPH zAQ-`Ff1iOFTux%OYxUCj67aZTygdM0KYD|V)|Z};_Jp;(w$`_*J|m;3g%1#%;NpE- zET`0QYjX$X14|rxwVI1|H`ZW#%B$P@C4_+LE;viI5G50Uky2qpL2ftFLWcUe568;G zvjB1dN8G`9=`wI-U>1PC1w(xSRvuImPvAJ-Y%BbSXvIAo^YVM@eXdUGUrxh!GDOsY zDYq~@9X7}%uhaqH@DenyrNiDnwTQGYyf4p#8TuFo1qtGYssQ_3&;ua;p#UtqIyl34 z>?+CbpYFGybN@|>q|ah01YGYWm+E218nCtTx=m+ZegktTB+%2Qd>+)#)9vPg%*}NH zX0DbB1ZdD5;eXnYu`%LlFHgbBs}H=WTFwLcxi3K5FgITL;5U<_{j0}mGdPMWNI+(S z;8U)FA3(vvqAnZLd^WF!@q{{ngPx?L43}I>;y64!v1s6f;1FgsdZ!?6eR(&u$YVxu zr0*4t7LeD>;(JgWQfu+T@f+_ZC9nnkX9z8-SSXGl<6z>2ff7(Z3U?+hWO5zpMT5w1B3i%n!#qYVGH4C)FjOd(P@_|QGaoN`y&nafp4k&uFp)%lEkiI%znM|7!uie z?n2Nms=9#Y6>pvHA19p3q3SIgqFGr3|L6Z>DKwfLSia3xp{Zo|T_J3$m-~PPx>k9# ze^=^B(Gf5!Y8MU+h9;PEVJ<{LB=di!8HD;*EKXEzn%RX4{Jte;w$2mDeB24vr?a9R3SpzK> zrZ_kcbu(T2%SC?vw;XZio2I33b>f^$s~3~9%gi;(n;B9>d}8Zd zr<~M^$d7zZnG6%Wh~Y`66ZwN6Q-HG0r1h;6vRtP9(rX@%#naU9nmA?p(rJ5=#!1auO|}y#{T0P`FT8qEVt= zHQ=OE+j^jB16iPwh;@JcW}6PCvP`-Y;ZH?bma>^KP`%l~rovn!GPVCaPRB5e{rrI- zs=`vwsTy7P^89iFH+N-Qwg%UZvhof(l=7bSnJXJhkus{hj$K*1UXyIUEdfHY!)K2<~ZvH%2IsHg)k6MVVf?;Y2MycCQYfB~7zZbgI8fI;(8Dl{5sg(fzr z;S!bt3I<3cv$ju=lvI`=P&RQ48k1n@%zx7`{lC3VP1$$>Eqt?Oa2$vna#Xqp8AeedAdgu4@UX*R( zadb!7>V!7?w)D#@^+PA!f%8bYV(NJZMnk<4bf)w|n1-3?E}+Sjk+f8~%o(Yk`@H_& zm&Iq_fXW=cvWRTcn%N}cySnwv!GT}k&nG+ljqjYqT&hn|APZ}_=>qk1FtFpI^gm|; zL{COIISK)j5_hJ#OOH#W{m`UEvo4I!MZoM_q>60qfa|2cS5O9{q+F-6NgKv{2J=3B ze%*Us=Is{xP%|d|M%Na?>=e;{zd7V3_q(4VHr3;{fv-@m^0L+ncenwU-LM}CGA>$! zS3;(@nIYw3ka^LqO++eVnfR8yme_Z_cl;)HwXvdxS8en8&3e8K4chK}+Gn_4vLP)# z;FKq$oR_ev*-Xa7S_i`n#1?vhKzNN+fsBX6LN;~~dY zl})a(DxbGMU>oS^&wOW^S;N$3Y_rjgl)}8KfvBoD%RR{sZW=rvLO4~}rwu02Yp+1- z)C!WF7D*x3f52@i!tDRZ%4urw63W$Fczj?HmrHc$w-t{QZb&Aw+1WM$8_Yxt z`E<@I#R|Q*oyfV6z=#VF1-IWlGb1OonV|Gi9jcmg3!&S}O$%~8aT{1JicEWdHe(bwLL3 z5K&B~P{`A$}6;uW0z`UCcMnLz82`O7xy+UIlV#*G26~f^^z( z0UPL4bN{)!KaW*|vzlV(=bOt2N%Q_<`BW0j`GS(={XIR5H4nEs_MSMDWFhmEVC_hZ zrM{HgOx)GBPUuZQw)DW{tC_AyUAl0c!$9sV?qFiP9vL= z;FxaiQGojVEg$C-LQg#pj`=iw=6I^o7ee~#c!I92^-4q?`xP*ncfo4F^--}+(4`u7 z^JM%mU(eg$8P(~K=T&I=cM8g;$2I+Qqnq&HzFeG?#sn#MmX}KAc zK-@A97}|E9h+oZKP@}hxB%ZB`$;?%Oa=8oFTW9CxO+QwCd^D1PY`${jgiS^;N(kBi z6gV`$hpeA?E8RMR+JO;v(9C3DV$uyQ6tGZ0h=uUKy09v?=lc5`rsq!`dm;}*(e!5Y zk>bQTLpJE#Mt@5!6aBh_cry#bGYLv6!1biY&yR9}U8_jzFu4ONQc$qJeyuh~x?=Y- zS~I&KId^yTsqD6DQv36WJ?c6gvf4Qn3xDXqfaykpTRTPME6|1YJm|kJtXQA6|7Q;t z=7V%Z3RLDBWPdQozS5C|RAGu=m|MEoF8ShU6noeaWBUX>hM@dUiZt{TVJvPqYskF@ zwjr+v0O&JcOx8|@{0)bh`a=>mn@@D7tXhy*@9qgj3li>l`Di z%|Y)($HFotG%S>ng3TF&K#FAE<>!SizP&9%PeGe39~urWh7*>JWXY-v#zt`h3H7Sy z%)rqnj=98uRk~)*7 zCexF;Vc=jo^xL891|}RC+)HbGXSP0mJGb{y^mMrKQBpvm8TQcr79Z&RQTX>@44Z*n zf{xG(tdL{CP#m_66GT^;C;@L1@}BR)NwSm}WUiEstM96(W!-4MVuwRX*Q^_`B$g+> z_*WGh_(8tNLE!n=Gntv5Gl_ln1jwuzo`1ZiBuBKEvCULl^Msx$my9ymU(>5F>T0w+ z$E)fc^oS3QcWa=ha#d}LTKoiqfzdfj1g7Y)0xa=M{U*C70Eyfrw>3on4!hC@nXos! z@}ten87paUz*qHor0B?!{0WmbYIYq0~4)}4!6jUk*Y?B(776Z^>GdoT{e ztAOAc?~)GpGE@Cvk7=x*r%KcJ!A4Pql^ibPr@)aca{qx?5^Bfb%>Uhj#4@LCYHC_D z+7es!$p=;$#+eyXhhkGFw}jD<^Q>SrTE^LwXnvU z4Y&ox7r|m-y_PbA!fw6qPPYAFxy z4n?WD?ySbvR*9avmO5;0yRSAavbwBwEW3mv*ZJOa+}7pYWUyFU9$ogSCd`Y;0R?Rr zaq`sZ(;Y)~s{^bsZ_q$rzig^(WMl+v+S1m}>C>nGZ2bibQL2);kjcrz_I{PAif3vC zjg6r?@hl3J_~4wWT*NnW3i!8oTV5c*Txlu_V^gc#0_44K)E+1pb{#+L^QxHlooS00 zE6Vtr=Fav5{>7WCL4ZqN=xL2Rei*fd%c3SyP*8v+Xoq%L7~<#D)mFXP;;522uguQM zs&kdCht<9R99oaDpD#K@{oPd_wAaEH%2Oo}u9(U5y2HZrw1oh+v8wgh9&7FFJdRVn zIh*}}B=XmW-z6SDXA0$+JZZj&ET!o2 zBKc{BD$$kOZt~~+eqqj-nI77?W3TsV_yxzwKqmP`Hnp8ZF!~ne`#4`}NIfF8ZTf^uc{z z0)53|Qc{`i?d`gX@b0yO{G)9DxHI<1Lse57MXYEMMCtUXUPA^X-@q4V7CkCx4jd>V zy3(a<0DJVQ?V|x-d;|sNsb(5ZjfX2~Oz*W%5%JtP*k%azrOo`~ECUl~H1KuwU(WrG z(NL}Dv48FIVFXqCE_pweFD}xK!%lZIEHx6B>1KR!m(ff1K@>WfIeh_i1Ick5{gq=cLO6DS`3h2`R{d@*k9wBp) zn9Gbu@)So)bKPhI{d0b5vdxZCG-eC{fvu2J5y2qZsFt;GMe}-Y^4DAor%RR34V8e8 z7nX~p+h#wMqQQ5=@s5>?-AItt&xb=v)yASuj`9v9M|#WtU}11j)2_>3-aF}on}Evx9e*o+KjE#a>+u20=#QESpRA-rN$kaXX zZ!P{+>MSx0_n1mzTd}Z#@__24gdtHB-s?b0Vl>OVCeEg~2V~s{3@7(`MT7ZkRY`-P zA`)*z*|pgTu0u(rW?x5%;9f?x$C~)DbaJVv>23hNTQU5#oy@YF=(h&ua42)v4-O?A zetC&hn94VjN%reT0%@+L{wff);rzK8Sw;dpqme)IC_vn|95N)h(4_BmH7T@m+w)v# zEtoFkX5r~$kYlLT3zpAWl6Aqu8=tP*b`p*&yO9oBDpB^_1HFE1&e(i`q#;px@8By` z#5WyJiZfZBb)se;oCAVE9&3ai9Fx-%i@M_C0Jf}z=wLrz87DgJD5TWWWdXU308u=V5p| z2a{LlV!(Xo7ovz{^~+BU=5mjQC&H}ArF6=jtH%=k$V%UXHh>97l~aSWK%oi~G0B4g zY_1m{qk2x*VdMpno9;1M<3ej*Ri>2kin7-)cifQins`M!DZdiO`2cQdNL$|8z?K1T z4&%3S+V}4T(nR^#|E$X8q>8iX5M*vjPWtZv6UZ?=s=>LW2uEFk6O;RK&%9!B|_P0~F-ZvTxM=UiA0k(lDC-uo6li*rbgrKcwV~NN6}Fxq9y^EbMktJ?Ccx4ydN=Q})!e zNeOwwg|#Ft5Hm+k-)q>F{-3cBt^FZr=804%{R z|5l{~qxHqru7z$cua*q4n0S7ixEqGNia#;wB_ggQ7*5JcX=7NoSiy<59^bomATrgJ z%UKtv)BO87nD4`=z&VA3uet{+1OA81R55~8n3aDP$az zoe#WkY4odJ<9v(B=rn8X{-(GHio(RS`{s`;U?`iJG$MkA|0z&uM}RsRYcI|GSBJNP zn3dAaem*RyMoC@X_0uoTfHGqQT{}SbXFWQ7-YZZMYuz}nb6`_5iY|k))z1C*Eeljg zT~FVMqrVzUh3?2J(HaiKX_Xmh!n2uEf}@rCn!GW9O`Wi+eh2}9Zzao#DpyIAgT^HZ z&gT4R!LZBcsO6RR{T^yWCHl#ucvT=(>9`-j;oYfh{fN2O;Y44X5M<=DCkb|AR{Gy6 zEnjI|+VE@5vQR`bEHj)<7>~m^wujH{H(x)TQAo0Y3!}NYe_;(R*12H=P$#cWfnkD` z>zd#JS8{@oT;wXI)`=eHayMU$9(LVftagRK-27?Ob-n&ZQzeGqVeT-j7}O>N$|5b# ztYQ1|9Hz<$cQ*67=Tvm7=_T+ZjfNETBNF5fo1GBTI`dTzA`FnSwa*)G7iatXsUMn} zrkd>Un^*tufznO~)p)#Yuc&o9>_fL{uQWZD5Mp==+!hB!y9!9O`+}18;xMNUzcuFG zB>cd?_;c?`0vq+EYS!MPh!h;zmmaf(689+9z}i+1^L}P(#QbgLYV%yIDLP-ndK=Fy z0>XJQCiQx-H!}EO!DB*;t~wqijci>X@IQE$M+0v=>Pa_vVZKn}VmCXaHlWLEgoopm zoDt`0)mcN5fK|>F^ifSy`2r54w6JGiTttv(z#Kfoulx6|fk%g{Zd*d4;#B3&8rZ_P zByh34ei>i0u&EyK$3CBkVAb^VP}3=S&kXe`g)8u;D7R-|Z=_iF?dZv9-e1t+L_Q-& z>6R&p4A5M`Z5mbivr*GPc!0^d9()3udfCNP1Ww#8t30`X9Q&|Yw-*hvjp6^_k8>?$ zfsPgotXmU{$ds!ZS(QbyzWjs)`OL2`#58BG%Dg!_$nF$R3Gy~&{#>JfzSjf860V^_?Ru4Z@P0y-}lC;BI=nqF2n2X zBiK}}%cfTnjtE=l-K{zGYG8X*r~Tj(McJ?4T#racbNS2UF^-Mb>NEQ_NWW)p{{pqI-~VkvrscI4)q50*bg5Mdni-m46nphp#uBIuvp|jS`SpYS z;QI`rZTfp8v_+X~ZmMEaZC=s^*E)C}UI}WLpdz|~2ub;&WB5V(nU0dqPf@dKc4gy( zBHl#_{&Kt)CWT3&$i^NESH^xgh!^_~qR|E*Y;9N@X`1q`^XiGe?lS^I-s=(?gw`1d zIj^3?uMa0=JaT*30o`#5B3=CjH$Za9v za0Mq~aIQOU{Ihl(IILdpD7$nn=MzkLTS^Y4u@Y8+Q9+x1Au=PRvP@{?ojr`f={#&s zSNw~E)GAyMgGxLI|HG8Wgnqc%QAr>D&6J)d&!?Cui`KjOl6=4>LpY;Nc1vzr$Yc{z z3oVt5(jqGfM!XDsOJKV>Hnp=r11#1|QvKIbPM!{lBy#-eop2<(Kpt4KR1@-Y6vuu7 zc-Mc<1*h{qJR*Y&Uh%$0)ylkRqGWo2vL?l=R4}Le;R`=5E9{$wGPYWLFBY_ZNVIkr zthNXQF9OjI8Sv?F0>rZif}sc(fo0eal8J2X4aa#x>vNO*oKvk zU%NvfUhY9ZyUDQD2&QUfYN-UmiZvr=z7&8|ipRhvh=U2@^+~>mMjU8F2jk%tsH%lN zolJx5!4*&FJ;~6XifQYcbAe3zvk$c=+`jIztcFPd9q}d|HxK%)(N4q%T^MFEx^e9S z2bpmrRuo%m2$p*8LBTzLpTDk2O04B=0lEbON!Tx5bcu*P2_j(pbvK5YYd#`-lqdXl zCy*g+cD~iHh$4zxV`{h_W}Qu$r#Cb-AX5P!n3QQP0CSB>&%)Th72+KjjsqPTJ^+F13dZ)e?;nv1BtuPISU{)tBYIqxBDoJX z^~M@5MRn&Vg$D6<<=`n6>SM&#YRZ)lL+dBi4`Y&4n^%w0<`|_dQk1XkZ$ zG{Pc-0>_p;kJHdhjj->Pk_Y%_c4Z>-0c~MF0Wy^gw!-Au?~k>Uj%^ZKOQJ;nhylL@ zt|;77fawBexON@fL}7yEZ^-dr09-P=Ccl$>%#fPA_)-WfyXS`cXy%8uBoeb!((bdt zog?M=b|1(uu&F0O$Hu7Q!J)9rENZy!Eoe-+q_g#eX5=D=D$#QYRhS(C1K_O+ke%d3 zg_z~xGR{OPR~0PM2F3gDKd=H#Hc56NfL0mXnj}Z)cd1UCK$@;5G=my;m;d4byjov$ za~EX#04T)T&9vf-vi@eQ;^LX!>p6y|_7|J6?nm=BPvR{#H%Z5<>D&N#vo>5cR~8li zc;EAuY=tj}MYuVY|CMfN2ZPa8q$1O;qH(!B*jVr8V!CN(S)dR7G*DO$bB;__3pkV_ zl(BGjOiWA+k&TX9Wj%cbNaEjD^3q#J(`QA{zq=gvC-ghfn>qfp7E;CnoD?!q%N8Pm zwiIVxRchOLw47H#vrQ2g>|gbYV5FO&`I6wq03Gyz_NadkR>f97-jx$&ui)^k!6u*6 zdWHHMBb84vP;3v7+c$_JFW*^7O6%KCChy9t>ew2V z7cLp2HG9#gA>K+Kp>XWk&x&#U=zD%fa;}7$OVCN+kjWv9chr+gjN!a-{?+vE)iX4( z0OMj(o1LBAba7H2G_K^N<(8C{WrT-^$5day-%?4#a{ic~pQ<4bF#g@!Ym*}|RPaPM z>z9hbKwOmlZ>m3cqWR)KaLg)~RdW5%`JM0Jah=;t1<%}WMTi#?Y-tSbS8X{h~yb^DlHm9{go;wg_N!{e}=_EtCiFeNb6Bqc5&J7KSJAJ z6Qfnq(sGYtPRuWVnK)D`GJkiNu{}WdtsREu*>-S*ZzN=J;4QOtqo&KjyWL`mez+{N zIjXu>p?+-J-}moA+vy*$r%5|Q+d`k|25n&&08mr&^Td%C>AG20LRe!mb)I#k>?l5_ zfMM{)m8l)w<=bnkxrwuBJtot`6;}<$R<^a^%|6`~{&e?jj<)Ze&ff*6Ln;*_STC_U z_EnAq+h_4bL=t5q7+heYz#9}rYpoM9XflKL&g_9Dm|Bc zq}%L^6wkNk_rRD*sw08@L5KUFu5&$UJL+T}V+pMJMfza8erQbdC#c&T4p2CpfEyC6 z7%3N%RF^NVpExv|Jf*ujHC$4pljY~95BNl$1W)79sppZt7KG)E$FeXqj_2Qh`WLJ$ z&7`Reo0}X3niqo@s9hURzYLkxDza^!a2Z{9U9~)o`Fz(*9?<{nhsGW4yCt(*etty; z(J;YxYlkXGD))2n+G{=`73`qvOw!cW-1dvzkrLl)&GlkBMQJva5iYr9V$sbo(T}^a z&6D|$)+NzTkm_eU+_FoZKMogBd)#$Z{Bo{vRe8BrOPf)TJyUbk4~qhv8}j;QpNp6y zd}P^Sa9{jFdD2D#N_>2I6L`bNvh1vZHf8n05CpKvLSJP6I*{UlnapUy^e+D|+1QGP@rB zzS4N2FxSFH5ni`t+_b}(l5mfc0{+jyZ{sCr#$A&x_jI{j%`#t#`*`-rpEZ$o*scwS zj#r!QC+NQff=+1xwZwLE=MH2gf1j0;!j^$j$EJe!&i?et#>wgPX2Ig3Gqeb9?)V-* zeq78wiO_oB#3wpUdoFA3-J&kj<3u+HJs5aZN^s)ENpA`yg&5j}9HvpG*P_RZSrtIR zCwAx_1QvrG%xvus=PEy3w!WoAW-z`{+vjS##W_InH(aR;*1&arF^O!kGx*_R6^q&tgJ?Y>b{8^?l$w{l_ zb@MRV4(UnGw>N|hQpj>9Sfck@?ZRpv&`_B>BYmENaDEO+ZEl=s-@f$W?xyIx4mUkV z2J*0z5o|qm&;1PCIS2XmI*bFY+`7oKi@|e6|A~1YK=zxd!Z=_j=ASM-ZlhM;Hb}Bv zJAz2Z&$Y|fz=6&yi(WX|Vzm#Gi+3~X@h5od7J-35Q9(5Sb~)u|;ByH6)2P)^3icjRMp2tK<8#rAd>jCM*&O3CBw z*{g^Em5gs(BXQI2#_V}mf~ofOSQrQ^N8gjI86HC%^o<oQ;NQ+e!&C0%ovN9~D56`QJ?P-OmX2!_ZMV|#Y;^LIg`wHiB|BC`J%8)wR>xLkn zK>U7gN#^NH?TC42$&cD zb@wS81XLAFkA0eys4Z@>n3|@n6y!o#ZSpIDzS}zJ6rAb~#9j8}=uaVoeDj0Hgd2Qq zA;&(P(5n>%tE&#gDf*u)Yh5{cxlD;^ntj^k5`umCjMOx6eYh`ufxeQ>C*3h@J=qUD zeN-SlWfM*~LNtaXv1aySNm=T!ZUg2Fs+8*BK2Pc8G(g^Qaw5F?T}ubgi`Gl=o@fY~ zu0p2453(%E$pXw%53q2{{EX?^8PSYOjiUwIaCb5SOdko~E=3L9G)2t@?L$FpKd;T{ z*z1TxnhU>%oSp91zQA{|K1QnfVb1QmTQKt!k(*Z%2WP{061T& z4o)m)pJ}27a5OH)tc$__$^p0O{WUrZP+V;4F7PL{g?#4yWfDQHF9p&HO zU2G}{djkt$Zr0!k-h_0Tl{k1jN}jtn)8S%8*+sb6qbqMBDC9LwN1lC>1XRj~V;_9@ z%zdHz^hn=zfC2w}v0KMcB${0@^vi8vnKuS*XKJO{QM$=dkk3#BKHML(Ur_RGG79>C zPNNX+wEz(;x&y&F5tWtBh4w+d>6)nU*#mkIR1btyz;pTtYy^V<>4nG~kza2u2^Qwq zFb}q1A+|tjPx$r~7&ivO8{1>@l5_QWBOt?P0iOcHf}p9hx#PN`Nj~~O#;hDd&87<( zv5(9pu9M9QCT20?QvfNKuUM!~`Dtwm7&?5^UuyrMY|7sJ3~j2$*zS`9hA6EDdGhC;js00kmrai`xHA`yCAiH?XmP(>f&`+hOGX5B84>|0v21 z=(L@CAPKXar*aU6T&besQngPnh>Lg>P)YH~=W7G!5f?jULkI0i#nRtpEeh z9#Av}4)@1ib7sI=9C^dC4xaBHjSI!+FGMQ70H92|K%hd>%iVT03?QSHY=@s2MguPi zG#CF;Ll*y6tkR{rj30#Zf4(Ub$YIR*C;nzlQ{qc-tR@_PsdiePJF80*oW}Z+C|s2%E3x4B za%Pzh0QxMdj164KZz{z+yg@+$Ali6-F2K*IgPSlo0T3aY0ueXOd=Yx@3#yb-e>&A% zkVQ%X>VJC`ZX~4IIuvbg9{$q~-IQPmXD_lzoJGHFc1{sOEguM+C2x@cgsE7r&{hT9 zEv{>nmWIU#{v345?&sK4g;3Nzu=$DSPu&lb{$mKiMH4BEUq3`@2TVq3gyQ$Uz}@^I zP83vNfa@0!EhAOJi7ozBKpaIAOXOWwzPBxv7E&}$j9^KWlUr_J{y@w@K>d^aD~bYB@S(&s@edgB2H+N_o% z3-!p>@GITJ;fpV3GH+D8`2mzZQ4!z*U+Ir6Q{{j{BX19s^S)k5hf+>W_;;#_l9>S{ z1W#1>4G5d%vRF%fw*u;;^4?1~&D%8PmEso%qk0hH{o^L8lOr4 z1yRE13pi4*a2iZuEHLv|piaeJ>73tBkVWx!0Im|m!Pw^>lz+s;-OXUeZ+(3ZnU0e* zeR9Leb$;e_Jllt!R)CX3Bm-gXQUrxr{C?!20c_P~izOV=hu5&9a}vI%Hv5pz9Z9#_ zzySbc2#V-+a8@%08Cbncr#rIEJ^k6oK)?rBFY5z*DD!jl^j6#TGfMvIz*An*p1+o4 zU|xRokCMxtrxPA*NeM^0M9fc1Am3}x9N1T}+^ws0r(^7$LylsejC*{WY2L?`{YCpu zcD+Gl>Qi-t*UM&LCRotkz-x5}q7u*2+0H1mRa!_K^*3qgf;Azi83XtWPr>q}FZ7Xt zitrZQ5*QT%39-4LH7~Dmg~|yf71<;99nL;V+t&y}c(^qwh2@)sGjRFi`&U?-12jVQ zzlfd(&wEMG8Q6u3E*gtTvAfJGtgw`KLL!pQI5F_5Y zKnON}`imU6Aigve6R11dw0{nd^&I_dI_WnUXyH%4eSqp9+5oW4FLALayFDnP`19Sk z*ZZYh2f;(>@l~|`Q61ZO173Bw9-Pua#G7Mew40Mk`fl9p#DwY_8CV%+6e82IDp*}N ztIS)bm!AN1{13Vu-|MHoE{VT0JP4N!-4SsIgmXp583G%OB)~s7&>`LK^nD!)WE;Pw zpnPSGn}TTc!)eFmF%mbAi>)V7LI9k|$#(T@hAa#%Q#-J8#xOGpUj~+fa%zCJ6ZE_j zr`OdVqFJT~9q8|!^BCkOmRgTO`l{`c1wZQn%a?~FYpCM7zChX7{qUnIWZ&7lefnIK z3GRQ>KHc-Vgn#R>al+dc;CHNkTAJSJ%D%{S@@2gx6>bE?kB&R}tsyL{3saqdxnr33 zibNd0zRHA9#<(uTQTV_On5~KOXJs+<)P?;mY|yKNPo@t~?7S=q2X6i$Zx194I9B;A z&TC=L&pqK{puh_$-i#6j`+wzbKI8F~tSQ73*MkE zfsIB!00*YIm_I2&R2U?o=Fju^x5hri;52e%9VL!>>1V=|p0)|j#3*C~-D686G_GIkpqhe=%XDF2cyKVF8Mbv8ojcq}BPTFuP{Ea&h z5+iUo2gr{ZIBY~uUi92SunACY2d=MRDNn88%>6t^603B`QRPa0rMqR-m2TZm^edS_ z=z;ksDnhxUY+vsG$x4X-i8sgK#+od+16Cor{h}3fzZMG!hA>%*=3!fwYq+|X7;};W zzZ2vUDCv7YG=H9Yt;j6pzjIJYA$fmp3K;iWjSITC8?an+SoqBMs zg0N87^~h+sSc?^Lu6EaH0BrDpBB<)z3F>1_P@>cqr|0Ve4DL#tb_A%XxEZY!O6wry z>bsz)0TZks_Q!-6ICrBCjpqXw0$K^N!R92*q4Eg(-ztZu8)Gtxn2)6^B*Dl+l>D_I6 zNAGxKr~SB`5I;W=78R9yEZ$!xoMK_=L^_`W$ka>W+BqLQ-qc5H0%!-aXi(30-{iyh z0G~^JrTQGFK7ftQvhYxBQU-ngkb-LzRVoGaLCWNk=zCDl7K_#?U{|iNQp!gXNi-`^ z@@ref+v94f-!0|`s}1%J0Tzz53n7~rfV>4-qRIJ8OKa;CESM>TEjwQbFd70U!_Rb~ z@Ximu(MV7Oi1~0gzV4Pn#<%+D=5NhEa0&juA09Z>Dxewk^Pwz9(-%5Ed)c9^3u3Y+ zY}$)XsMGW}URuMoK_6YM>=Zl=?EN~J^+pTZfO@w3^FNLI`I08nquVCLBqTnC_?SQ8aLW3iIVR~s+ie|c%5=5xz$bt?Uq()Cy* zPBO+OlftVY-00Pi(UNCpW7AE(jo;WPjfsiL`5pYO#R}HKSi&YLHW{z3wum#5=h1LP z26ylFCjA9zvA2D+3bP&LJ${1jX2%=@x48T)3TNnJzFk0S*kGUPXez*_YNp|qCmn$s zG!uIGdOGW0+MARsZ8dv5I}3TV=<*KMV>8j1YAEc6G_pJZLj42l2XQ76Mkw|~Izb!W zYtH?h7~S2v%g%kptKT^yiLCP;&r|t=)&c?o?4&w!xRn=$0L0|+dFU6~Vqd^=@vYjte7CcA$4>729QZQo{*1R8lh z$!Z*DhW2kfL1XV#h+!7?qV4^8a8Y-jub;*XfZRn>9fr8M+ia8uocoG@ju1{r2%5&P zh>MF|y7WFd`P?mab>5`5>1Na2e4vtG!IC>qqPi;f{HyP-rriI-K9yWG&(OA=oCaL` zW($S*kdG_^)az#J#`~e#OpUiA0e^>S-u9b1S*vSXDY{t@i)EIHWw=dGP$br3vtM+k zgIZj+6S5UuY%s1Gw2S0EqjeS?)WV4Fuo)&B@Lp(qeR9tyJC?a9FIw*xP-NCOmpwGI zGOQLQ71sahy$6T06tBNi&*z7Ke3k9wpEZ#$(h+xK>K6}{yheiZ8wu6#NUfSKRU^S& zS~cQc*MT~HaLdMOHi1oI1*rxhk{O%I(*|7&X&fQFN!mPxEVaV|&9J`(25HgLt0C#g zY%kRP>Fs@)IzG4DvwX9<&uuz=u%!H=DQ|RPb@gCJ&!O_*bD=QpVYXotxZBwl^(-WqPm|3s{>+#_o|F?^zg{LjPQx zfDkO-R@T1DYob>ZSh(yM%RX6IZlcsZ(`#7KC>dxk@i%E-J-mW!A*vh~Y0gI$z?ecK zC){r*YE`3Vqf$|GJR($LWbq#F4kD z&D}tED6#FbmSs*Zr|$;oUa`WY&I>$?dIQXyg+9IE21aeAV{W8Q5oW<0Q@Dv}~ritl+b)~BBLruj#GCMUC z6c<;OYE!Sb%wbJ}3LBokJYx4oL)(GRH{L;%EZoxMD z(fJ63kg52xxIC z?{t~&M8o>M4~VzX+j(ejpDiinV`HQ2;{){*|BKb?|KF_EEI|m2D*j08Pnm4Zw2S-2 z;tynHAqrzW3Pk)7(pbR`P-UF}#Vbe7r8Ug)GhSF74Xw$5DoQABK*$>DtwDa()o5m@ zCC=ewGDB5yj7Hi?xWxjY?q#(^O$rv@&7V{zUdz~q(rp=R;3X zYfrdT7v+5vhtX~f1L&Rmhy56pN9|C z%*|8Y#>aQ2%dYYa`0eeeaMG7Q-pseMg2il+SC^DsL}#}K*JbzjMt%GCbbk>X?64}w zOk#neVhF8Y0gn^6?F!ek)&kkTAL(n&uZ^YxIQ2o%6$jQAY*kZ|P@^^ns5Xz50si6m zjRBX1M0mvOQ1QKz#_Xq+v0d-gvsqgw^(gVHr2in}8aL+bV@1_zEmHR=^Gb^QUM1Yi z`5ePeXexkSHi)&NA3nH)UD@4|71YalC$;DOcFf8Y<^3^B8ZXe?0qYF!40z91fjgG+ zUi%|fG!Ovq17u}{muMMR0468@+(wT89snJ-3MTwY{x$&Y9hA8J`J#DG)1^#LyWgNo z-a_pM{zWxrjsT?oxxReY!o71;6DS8>5H|UZ&${APtLvSnzbYbuXQ3}wEO&yo!s9Ez ztKqt!x^F4InUpfItG}E#bdsQfnn?t=?@b^4ls@>Iy-ZKBeRxEKEe3;$)Pm}=!pP;x z-02@Kdj?RuO)(@gAiiy~Y2S$9M;(FeyqGg%N_SI4SzN>~5n4UWR>=r<1oK-umjVmMT+jgufXJR-(2Zu_@%nbR_N+fm&7wx7r zem)DJQw>7Pd(;3RB7@>ThtXbzdWt})*QN0w$TCXEBgsbs z;y+Do?W+$6In-VvH+TFgB4B2{U?R2btdSG)8}YrSWw-kN0f1Y6kH+;F7jC%D<7uZ_ zIOIN5(C+#V74~YZvu&KamHn>$a#T{+o3cH_jQ#|u|NVBHn*twvH7cXehK9f29G!Y_yoHU>RUQ}qNPQoH(6}cTBnCB$2c39ccwmTj7ME+F zC^GZfZXDamO_3WEJ0Hx+Y$$^9pJ{GJPA>gP70kVb#scxTGbEC2&u>$e(7w*3J~i_d zeR#*Y%9;4wm9XHA=?R#RvR`B@h-YQ>P?l{@4{gpBWoHRt)50^0#Zk#~OaIwpN>uf^ zML4rpiRk?Am^KXOOyJ~_z zd8b(2>a0vd9Vo-POYouEe1AHm>IkKqo0h%>d60`bs+jJ^9FG-a3=$2VZLX>vR z(dms^+NtQY+{uonEM74-LNErV41sZU-B0l`WsYHfx{zGe*|Et%Ie_@_s(5vFRL^J5 z<4T0H;+b}ChDwRDH%Np`jvYsx46K%v+#vr4@5D)H*no_*>=76Ga+yncf~NwzPotmi zcXk*-MOjgDr*(4v0zlE_*2L$c|H}RxbU_I?r|t=O@$4Mm@r&Biab(?T%;)ce!_Es( z_ObuvQs9>je*SH9i!xTdZMVkDX@#AK>16+!-G^nEag3A%gM4@=yaHqxQx@7xfK4~Q zd}?q>vDbVz~5|e9X*Q;`t7dAM!m!ew0)G8n*c8 z)6v+qJJu#vRTDnt=J0X+k=DTmaIX2M~ z!?(xlx}WEMzklF;=ck|ybI!TrC{~SH>sh-_ zYo@8YNtnO;1!woqmguIl_B9aJ^X2TF8p}?Mt5qPf8r&X{$BD~(ZA;IU9ZAZX+bPM2g(%^gi)h#eXg_;ZhIvrq13N?V+shTGSw^o)>> zt&`JMtwQ}_tdvX~3*B_Oo%{~FT_a5xnIL*v`;B{C=EnTI@4e4y*p5Xlr8e=d` zq+(A$MMXqJ$Qx76D>UdIkU$PcIe!1V)Yalz##o~0W{_r}QPqFebDzEE;?{#v@wf9^ zUxp1kN~`=V!s%Ze_3S^FcE5bChxGira;%L0;y7thsmK=}_#Fg9C`fN_<6gZRh))Vh z#&TYIge4e*F5_rk_H>Woy`FZ3hrpkWDu+M6_oXATzAQ|tO2kDeqv=aZN=k);y8{o^ zseDYTCnWdcS9%!0mF;~RGW^(SmOp#w!U$ms_Dd!Z{zOq*0|{<3=~VGA1?G(I`N2Ow ztXhQA(x}46O=zK3_aJG#8Ju8p>^f(VrRC@5tXf*hPMf5;l@P`JD087nmG}yH9^UWq zVB9}_y8)j?M!b5C+$iY-rBJidweipWn7w;yxA4sAN~(Z3KZBN;CZ}hgwZ+~|Wu!qr zdx-H~Ys5jvZ^PU1nZ89C%q%p^G>rb#?)k8?M18eN1Rt0MdS%+5seaH~PoP%JrLk?# z{04$TgFX>bR4mATpv^5U5P`F8@+{+)o=V|Nb^u5WHV;c&WVKku$7 zDQ{LT+$AT985lz!mrN0Z)sZoCJa+NQaY}E69&YL`NW-l#RfyvZ^WN1taNk^JkfzOE zoiAgw+A3%>KY1NrW+IbW35hJS)mU4Q`OE@KEFycn;4M=Bee%}BXxHHp^%(RArLkYQ zA`HMX|e6-{= zcWVBqdGJ1x-cm$s^hnWJWZ}p-7_8-i@#-NkEc|U5unHN|zrm}QON6^+weGg$yq8vp zm6FjE_s%6gbr%_ zBLB`q@+9undm}oDcRm=KPUt8z8(|dKq}b8G1ok(^bae0OL*%}@?4TXYGPj6Zhzu{K z=m3^@>$P5Uq*SvMk&*`0c!QL7ui}mdqsu6J8~1%Xoj^5@$H3}6SfJ=k;FDo@p|NQSMt<8X_bA|Q zh=`1V@i1IQSWnYg3;5AruXhrv-q<^bYl(YXkjnBdhOjO8-mauJm6-h zgn5~@^?!b1C1md-${&?}nyf}_X#kLn0(KS&?CQuwKm-DYj7M4GWmuw)HG7ES+<3CqAbU!;qP3yeYQb#9VRf={!VJk|88$#eB?z z!dz+IMlb#l9Uq}>5l&}`7mESxx>I6M|BeY|q$z(faC^cp1sfODNPSeW(&4>@@^`cQ zo`|8~JG5x;^`_0*h*BwIBf3b1zyia(rLr7Yy{1;)+%dZPZD>lO3}E!v2(5&qS&-u_ z0RYp7v0WW zv^CXXYq4n%oB7V|I7&)l&~rF3gNbR4(ap1i+PVvlg0qkfVtM@n=eIsNMn_T7(7eEV zhp~^bg%&|(oLc{V%JoS3o%JH85I3oeswMqiqWHa*plG?$t+8@cEKw1Dhnmim6@!_Z zOvnm7`;S89U>a^&xZwS(LX;O;c>5d=T}ccUx>HV&fXIP&7Pae$35m4F^$55W5*Iq* zhv4wq^7F6?#XLH>3dzHxrnTpnEwV*f0azyfe@uj-lx=lzXoI8E%7ur=D+M@v1eWX` z(-8nvYr;C&ciRHW2r&?T891CGQBT6Ztar@0M_~t)kjC*~Z%n&i`EMf{G_MKm-s(JXJSiwB^)*6Pt#;udOwzD@VzNPrcR49m@~kF0+67|qCjCUlBbxPl;|yWQB0 zo7M^Mqut8}^#i7Awi}1?7pWSbr9KGYT#*I-{6M6|#t);#$J^xS*hTwPJK77Zef*@Z z-z0aYKGS;7e?jz;+=7mM30}aW{oajepUcW3RK(6Lw4nfc!~(I%H2^oyEkpx`oRBcA zt%3S3yH)uD7eD%rOmz1XTKmMmW0o@jCfax*GVgL&SZA;BM2hD+N>C}CtE{4}Qoza!4w`Fmm5| z%33#F6e0gQ#i?AzWsr_=tHYw)xVqB_O=Z6JON~oP5|T^jHlJVnQBPH)S`}ioG8p%L zX2XZ}6itCjp z@xDMQcHKmtG^UArq4<;*lYD`i1RKH$SX*hVB#f2-WzCct<+lMh#7oHXYF^S#6=rdq znImK<=0v?A9>7$bKkg`m=W*jZ?_mN2Q~>8D)#Fv>9q$Zv78-6Mt=OBdbuQY;PNYeM zzM)^IZ!qI{&;vtBS!(^pskGyr9zzx+(!G8tnqFO#_y1CH`=~JkGnD$bD5I^A?HQ*iq9G1?j^Y)myMBvQ1!ST-n z(zEU}J^l-Z1DGX#Y}m$K{xr(eh_2*U5weT}DFD{eMN60K2`Be%{c0?O4lT?ZIlIE* z+DBXn{Oa4opi|MEDHwt3xhbfW<^J&3H5AJvm;<3)ip7QYk@Xx!5L(!Q2Px%MStW8lvJK!LZ4ZIw1Ph(Qt2!un)PD8PB! zs9%?=AWdcN(a+-7?h@V~I-6kRY(_(qJ!s_ugAER2joYpz$pWmGJZ?eG zYg-XwLMdwz29gMN(E-ByDjFrM>pE*+^t-%jGk+}0|CpU`$=2QbQgu}_O|5tz1A~L; zh7qC>MU>VaHv3q~_~1VGlIw693ce}-O$m%ZyRGFt1O9CWdtIbMo3QC!a2#*w49aB8 zZ2RPO?n?klOm=0CvQ0DZHOT8>oq@FxKD7#scs$L#pzsKJ@-M#%d3Mi9Q`kOdOHR_PPteZZf{qpAS0TRG1HX#Py(X$#@xN1Ef}tdu2fTZkqM1zb zF(SgtmRMxnBH$g?AZt(pByR6i7l*&W)Ln~UqG+qKLHC*t62((YH;^#4_xTRW9KT7T zyQ03|W2M-{`1N%u^B|vXQh8DtS0b8ipsxfltFgY7uONE9+vXn`akG`Q`^fKL*;$%2 zrBNBy8nYLt5(4Wb52yNEb;aovYet-7*aOmXx>^^tKMxbE25+(U)WG4V=p-bUPJ_)Q z)%L;D#tMS;{j;84H-iwZ_n%IX>0-LCNDp`}*Z>Otla@`LkV_@2(9Oo7q}cU3PyFl-pB%m0@f; zNSwE24j=>2ETpYzQaRO!BP(h4yc7axWmqq%lGUO6b@fKLYuHT9lf6TWaDHmu^Ik7x z_8uM|%?cws{VWflKj79RJK+ChCRjWQZhNF`d}i>3Y;S^b!^efRWxI|eNi{hK=vznbeB?sxja?zB$#52o%u_=B$d z$D?}b0sl!Qh&*WG^{35ToKxz4TngzQ8Q6wTeL#fqtS6UoUyt{>tUUmZ&G{f6krLIq zWfE}3z@H@cOtU6kiQ}?pI_ucW>Lx&WT4U_Q!La0G(#cKqtmc*d*g8?P>;70#Knr;u zBQ-;MdrIbz1F%cH6#jq1tc1II@#^Z;4f+vBM)13J8t%r^`dLVg^=^_7^JXUozz)q7$|tvq4MN)#X^dF6D)08)|%JnX2{EW2sWXJ2pZ-L)XRXDpD@t)5KNhpUm4Hy0#<`>b z5iSWoTRH&6`F!Pt0mKYu%uF(W_X#d?6fqP$fjUj;<#d==B6rAr*y+k|J$&c>8+$Ba zqlc{Wtik!$I)$|_ZvA+7?eyd?UawkIn%j}q&KX^<-@pNr@$wRaprfNRNYijTxw*PR z9#T;`IMab-KvVP4Z^z`RDJ@(67+w-wFnK+w#9mD_lQk#{GW>=xmlh*m{Yuj8$#0nm zN5PQ!-4=Tntj+ROyLx7u>G8cvK}&8HOJ9uMePzeS*=`=OrO&n7B>GwIEiIf_J-SdD z3IrDO-LDWO8|c(FdUN zo#n0Z3BRxdM1@X>KYRxH0z|QpI3i!;z6>#cVW`iA@a2z0RfB4y-y=Vp*UF|1+wI+A z-#n($5bp#U3&hB4z>O}(#Mq!CQ5(ENgTDAWPWcOfS1s1=5LA#H)mKJ%8!%npL;3kP zpgP_H0YLHDh%>&)NU5%AS43L>QeSVWj;+>)At!W{pJzN>&i*HjGXXIy$rES2zXmM{ zMUkWn7LeGNKPI>g-tQl4bZ3LnIn6Goz}&M?Ojh2St4eF2w=qLYnnod=h{Ea|VptNY zKhANOD+YZ+fgLMH5r(%~D|Yh^Iu$fe7Ceg=2Sm^4kWfN8j!u)(vf7<{{$~q?0Q&@Y z&M2(se%fGC-7zxmFwYkL{x{9y9%h?EEw#LwT73p|@5%!U>wqAMo5k%T@E@8Z!uAI$ z8n0X4`4`8i70_m_S2gezt4=z7kgoO*ZZZ`g0imWL!<}J<8vG?ifg%Eww(x|%K%79Acgw$nR>3a3^Er5JgBD4SQX0b@EVy{ zEn8l9s_-HQls$vv9BnqPvBm8{(~B_6iBIdwqyF(w#F;n-2D)r-_dy>iq8-H$Q+WSL z7u)DwRyrIJ4O%j!=L6}sOO}=KDkhOcm$lbYPufHtqhDWL^z!$l)t`^COB5Z39$#QL z^A`>fKq{YzGyIiJa&TD0;&38ea+Yu_jkbM!2dAhS9Rv@2swjQXa{JqX(u!vqC1!rJ zQRbrs_d@S=E^0@}pcFRT#vAhq#LeDv9G4J}!>3s2&LvLP8v#{c7Hs)Q@ z)1ZFQvSUS%&-CNiOc{tdQnBgt(Y2WY&YXf|1~iBXXb0@{|EnD+DSOMEjY`IBB=?`R z_CWU)rwITZOO?T^m+5Hn*QJGk34ZNHP=|m8_GRb8&I~1%}X8 zfG)cr&Nh2=Fc)Va2o zU)lypj=j!;*g&YeM~VjL7trY4D2!V=SFja4_W=SFSov@uXjE32?|CF|nJtZ~evrrYm4AjI&h5 zSmN7JImH^QtdBzqwKyS2*jLG`Hv>ysLK0@2Oc@fLad6-axqtsY*kaslX=?+VWF~%n zq-h@|@1d`+4{FsWrlzISIqQ*gvWr3CS5C~%CcMM`EFcJF!JX0lsQ{91iCaFC-m z9Hd2-V>1EyE6NM(UIlxLfXv&AopgTbB#N!EbNG}IzHq}0HHd88LLuQ+dG#2mv z2W8z|*u$V_cfJENQATXLhKtC?vHa>~*`=LM=XrW4JoN_$L?|&VtV9b#g?AzjV9TKB zWv9nhzL`}Ll*Ftn^lVw*?e^}Ck^s8|x@*J*7VVt*QrcYrw4!?d0a}Tq&!{{A>(keK zjKHIs=N4b}er9#VP}m8#t&Ma7aqpgr$zj(Y!g#O%1*f%N+KJ*H3mkrMN2weWWiY7# zbj7qZAmFHpKEg{eVr?lHQy1J}f0bIjzutJGXxY^pdR84>gFp#fPqncnG<-2A=MlW8 zuci%-X(rigeA*Dj(#eh>jkO?fV zFmg~1`}XL#AM8lqM5D3x)kLd#EJTb8Yx=>;_;lI+UQk|Y~DFxf7bW>r)FAb>g z>jA%7x$`eD&`}_A3cN5OBC(CKb{EgS&*noS+~`Iq_ebZnWnC=kG07H${J9I)1Ih{3 zV0fA`QkSeiRRNM;xYLN|$ICW))E&xm5~E~sP;Usv-utul<6_^f`cHT5B87XJ8>RHL z{?&bml@qh?_UEM25@){R$G#r``MpD{FKD-GT-^+EdoTig(>PQAbNW_$AYg31qao+sR0EfkBB>5gDAQ(hy2-1&((4YoTC zVml2kMExU}ZLEUoOU~7kvFoq>O|vaYVn2u1TIp)I|E^{rt3;J0JE#;a)hRTnBB8Dr zvo*&1Cm6?Ps6tEi?&r^LxaMs28#ou|?4P%AJob%Om%$|=V`s5{U@@B9&@22zGsE_v zqqyagS`11Xg$wEls%yR>p6A0^>tG_2e}bf>0bVmf*Q4W6YOxnEw37d;r*@G z{&mT=eNX~Bs3gf5{9ICw<6~za4Q!FU_>!R4M-K+fP4rKq<~-L_7t^41sT!1^2=EDj zX{VjiCzh4=)rd~>xIGr%dc-|YUj&uA6PwmYwplz=uPjSqItH9Ce^gypzjY9oXCfoH z2_?WwcqZqz?qrYTBOGu15xbQnI8;N5Rid-gC$HVXCKqr=LgC_BkFJO6LRs3u#Jp?x z)zz*r(EI7Q7+{GKe3bM424bgbj6QKHlm|m)d4Td2@Y-DlZY?3ZZIO$*l6jWX}je}ZxXq&y*MR{K1Tj7kUYY*43 zhLyI#Tu$@Vy3QbO7~w=q9=ZMwR-;o*cw#>AwnUHnMU^7v&?rP&zx_8G{R zU#282m(-O&FmlBY|JY)E0{TRwo5NDcbeC+`*PO=G*K~crsW(W2RV6qHpOD2YxwaWq zD#iiySNkvanM^qlPZ9{7`Z=(b6hSuZzxTDq&`<-GqTrcS9Fz?l?8^)8DR6BhcQSvT?&^eM)kZqIWu!EbSj+*%eOdpd+HCh*-wMnhb$cV+uX|cl=w{LqqA2&X+n}MiLum=!_EVL4uk6xflh5CVlq5T5%${PANpOzH0%Gm^ zgBahG`}E+QVLU1H;)B&~V=9zTfhsuc4E&zkQHqhHzL3A5OKD(Gh2oLk1A{UX1@&&m zyP?lTkyEB%+Z0=Va*(m8X==LcOmTq*HEM8%ejko1Kwhctw_*JaC3~HBeu|^2 zZUc2eA<2EpVsF*r%Yr~n0!*+I% zHwN8N%d`vGN88I2C&MdaYKabX%~X+mrtdzt1GOx%GWCzdzR#YN)w*IYNHn5wkRTd8 zqO`rtq~n<4jb|DNQgQb6u(YJ>2(QgYCkl^Z-4Bm;1Ar#Qxj(?0Xr|9+-%NCrhN56A zeQFZWA9Zfq8yg!>`1n57@76uY9hIfS|9yS2m;3Eoq}%p{6FAR3g)#?3&FG*>9PyU$ zkAub#=3PBvbN^fQd=_I$498WuD0;cFQpNZ%`i`ebCluM3_*m1i!}3F12s$X^oB6E0 zUrmvtBU?)LpfWG4mvN;peX>l36@{+#LbJqA-sB;W-pjRjSO+fY%-KZp-psa+*5AAZ zK>(i$CS^G!7hJp^OAEBzf&N;Iw3oS7sO*B_K4nU}QD-bA#P|9zvlBG)keZZF*KFpb zd4h9qnAzDG@FV5Vbf@2ejK_RILJZ{S;++lcsLEVsLmR!R!JGyNmuAkXnNIh@$riGC z=3>zw$QH4Jf&eG`;VyHINS9)=lJ+*c_3ZZ9c;fa3))|^iWItt+Akd6FStX2nUI7>b zT6Q0(zFsssluv=M%!ZS1U(JTX>x8^OfA}QWtsQi9=qP#lpMoQD&>|#h#wI4-r{%*4 z!SBF^e|MamEjHe`UnU});4n9OP-c5-9~IGM)h_g2TYUK(q(~?Jv>n89AO-B1bsybu zKzl-46u)!owM+qc4Aw_<&^?k>w0yTvpU>9>x!x5C4Sy7M6E*N!fIlBNFlwGw=$?L} znw*-tEAi^pePX$rQEL7)?6}V0!S&Yl!xX#)ZNBqflq#0z0EI|cEI+r`IvNCw4W}_C zHXB5e6;L^ua0w9oA_$bY(yvQaWWujx9nDL4*R935wvp78`|g|8;HlwXEVQkvU7$7) zHZG;yPhNpZ))kT2-f7_<*{-dL^(|%{c?q>{xB#k-^q7>oE?&Z$WL~A~5|@#c{5Fe9 zSW<=2OkqkiT5k~)yq22 z;45Qyv{uP7r)Y6WAzps!^QD~_eihuAo=jjQ>1QW7+kCFjpot`mX)428H8Vs28FiI* zKvvp=)+*yUJE?_YY$YO_XN7)VwWagHjkT6ta?@4*Vq4-t^ATU#IG{-A81ckugP`Wt zxsnJX5BITrh~G=lrU8m95AR+8Hw7OvMagE8VV_Qj5kmLmwB!Bx?$I}YYuqm{SplGE;GS1~>8iq7Q8;|GFZXYWM-Q04D~@bn5i<%~}pPn-nJ<9}y8dD!#A z5aiSNTt7h;RMvdW#-8f6{V7xRbnSQel=2n++Y*N_#G%C;*j44l4IE3Lc+mGqiNNyW zk@amUMn=lkE?Eb|?by>uvfs;BZg1?cDz5TRD9ziWm2kHXIS-m9h_-&6Q27@c8g65G z{q0?FQQ>H_C{>CGijX(>-&9ZoR5w%N0ndHI`)=I2)p|U;MC$X2`z{w!5YC^3G**o` zkL;Qz1$o_!%eqXOn{zDY0Z<_^wwUeC;^)T)M}OJSP%{Ll$jSi)JtqPcWH7Qh%|oZD zK@)@#7gj5$NJOMjYZ$ieRLNT*mo>*uN)PzKb>qo`oQn&Oz@je?IL2ZjZ=l}e=t4$R zJ?lO?K#N;HXg6*aiwfY`TLaQRR0%l@9s+sfchlwKIbF1Sn87q?H( z_sQ0H$~Z;973uJ)$zn{ZXO(J$6C#c_5R3pw^3@-uMqo)^Nv`Z*wLYQ1IU&TbgB?F7 z2zFj{Z}@=&nM0BsED!uJm*W;-u%}k9rQiadBKU|k@ zr?UOwe|i6UuBLw9b!0H{yBxQap^M1Cm%RewVvgt-Z2j*G3Pj@K))} z3D3zS24#OGD^Fk3|EUdH1h&mKFYQ^n6rQ_6*Z;B8%PQA^i4nztX}Bi_#QfUq%sh!zhO5FE-7ifS zZBq85n3za*TtXgn*@%Zf-4lPja9-G?c{s{W;YzOko7bQqa81#nnLn}rk`+BA*oKzG zgG-luvLydp-(AyCau0#Gwq_vz?EKfvpL%F-Ruv^kOnUu`Ia2+o+3PJ|+pS=7eEI2N zCTYidU#}DMV*tf7#V6&)!^~d#AKd06T)00pPx2FV!4c$l*@ zlAqzZVY!jLksn|SBRcUk* zBU3Y>+{(crx4u3tB;<~Xi3yN@&7L2e`GSPu_r9lN{XFPD;-+>3|2sU3h>4+Rw|DFu zrWsXu^6*o3_U)uzK4Z*ktbY9R+wsicV>?U7-cG{lrp`FJfFlSG^9;qg)ao^WgXcn? zQzvp5D%#rGF8a{Z)9=jH64cKR98VfTsU3z>(rS_c%DaYpOFdYl%V@=pYLW($){q@a z(*UgPtqkV=fEwT>E!a`b0vm&~g^Jvwp%t!=vqhE|yFYfLpH(|PyI#kfm$KFqH~KL- zF9~9Rj;;9mx?jdeuS`l;a?%X#z)+-wm@%znjwSIVTSFQ=1U=Z^6m$fT`I?8&q)SG3 zmCT?TzJT6T_uPP@iUjDU*g}krUf3^hwM{L9r|>ex)(tVQ0MNgG$aB=tF|`bIl983- zwnw(48j6YoHaV6!nFgnn2k$X%f}MC>mbQz2*q6SCmBf=1-}II^%OFq=nM4i}R|)Hn{~&>PM#{AC^Vtx4EO;>vxddKcEZ$^%|NeA9WKYz-$;+{Nm@jqlseJY*<$dkg->G{`X7H!d=&d;aoga z(`UBy3v)%stK-Q-@NuZHkr9>M#uEdJ{?zv2Y-uYyyY}UM$5w2CWXdINty4K;qZ;&} zVJ6mSMRHmP^Dk`ja5paH8Il-ybV1Cp-XlijBc5f>W^gl+lO1i{k>@Cd?cawy2WY!U zmN_^)ti3|cmg*E%R8*9hcH)3Drex*iSI8Gn!=#A+>-WLS;I$|9)SVtae1T*!|bz+25M; zfBgVY;{VQ1MuC3ee)pdnb-wjanG}_e{rmW*fd=)THeTYWc94kwef&q*`_JTp?-1e_ zxU=~GJt923;kzi-`QMNKz1}|;lDzZ(+D{<$(`fQ{P!e`f1Xe=336}_}OW=PVDJD7c zX!_D}gt>@=pvywz+^J5YVr|9Qw$<~$lwr+bvpZTrbC z`5mg)?0+7x(Hf#5b*4uNn@eqo^mm*8^91+@tTP$BP7pjN-~Qi|nb2)2|6l_pi(ZEQ zpRXX8O(sOW0#AsCXcU!p{pZ1uq0Ia#--sP_oijSTP=Ed3Cdt)Va)0A#GLV7O7wih| z{~x!o-1|3a;7Pv6_I)wq5%#19Y5ndUo8)9OeJD;M=`uqFG#>RfR*AJ2`O91== z84eM*O1e`839I6G-1WLCj&?p1%UmDFvQbG2fj|I_#k5o_ zA~I6Q6emXqx_@z{rlDa{ss%!FYwDg+BA(RsJi-p7uz2L;J{_B3??>O}Wx}m#c2pS- zODBy^n1iokam^Zl zKSLk9ed}>LTV-cCU+1RhHm(fr?2zcxr_p;YV=NHvk4`KfFIoUNo zTtlrk#He~U1sWh;z2Ln~it7lr)WsD)mHYXd)9`9bGeyK>_tToDu5R!7@wSln5fiAd z2g2bL_VtJ=Rh%mK-MMZ#jz&pA3XB%(N);`wE(L*kNoVJSPixi2tr+0x$jNQ=7KFRY ze)}Vr)sLF7Z)V=2*3qL;iDCH7hxN>Wj7Fam+y{q@Y(a4*+iKILhST%mogu(S?@aDj` z4l9fO?79|p1MOz3O5G7UMNQ{hXw~SAe%5;njedSl>FLc|#NC8noQdNwDlw7)Z`lRj z0?slNTkt*XZ@PS@gkxW~$pGlzg2T+WDJ87dU!|RovvYF7>x3+qD!u*T z*NMr!usEBw;#qNiBPoD)-mNy38*L6H?eX;<>_56z+~%_!fU6Gl!(-38zxDL?dab2c z0=;kJgJPhV9AX^?8p)#ECah*bPsA zKI-c3CLME*UJ+;kw&Dd6*{;66mD$B>)6BV z7Z}qzANxe##>4?Q)ZNqbb9w*Q;o03gw|1sVgNax)j$+(N2F^3duG+YNEgDvl|0bv+ zM|4(`qx;RqoS%F9Uu_!_+`Z#is|Or#WMM&3Iy~<4XPQKIec_Ga#|bhaV0B^>6Nv#_ zY1KNfGLORHqo=2y!otGfEo>K?(hmW7ji%KCbPVjmEd9p8fl*vMBRU$Z!GHq<5ip1F z5hV-}gc(rE<4OZ={6X1%dV1PZG-I@Av{1MDV8*6+czpaNFr~+F;b0S#o}Qi(E!Nve zSota+SkrKJh2;kYi~WP(gL{S*5|u+crBkbQ6=g62gf zu<1SX>0OQf!zdoeF7Proi05wY`c%0kF6bp{Xb=UrV^EwV z=7W5#CHSZ5RPz7lu>1}SeKy67Qi2o=%*>HHJGLMU0Mpo6Y|gBx;034@_-$GV!f!v< zl_B;r@CQ(HF)MG#dbodfHP#)hZWqI>YgnH4v{|0#zIk4l;O@w3yu`-N1bHRm2L7`u(kQh*B zU^cEE9-}ieuauSX9vS-XlTLm`xpGgB=h3kAg}>oQlfIQm`wM(dl9< z;Pnfh%h&*ME)NHx<{>9Q>7Obye-LK;kepl&$id>7xXsNl{d)IO=hdEPi2Cpg@=pZ? z(R?-&MkE+cPELBR!!KVL#Hk{*-Y_lRBwPc}W_S*rZVrHgV^~-dWbWjT_e7KOplks! z6g@q81B1sv+O*V9{B1vb=?`tbLO5K!I{`<}uf`7!N4r6V5>VYG+(dA0xY1|A0UyMC z{iDpm@L9@UfHMldzM>FJ+{Y{6BlDjM`+LFO6IzwlL?DiRt*If2YX4c?d}YVY%?&~M z(sZ30%b@5X*5b|e$;FI8y*nEy1uRdMn)>zHkw`VOEN87lK%)XIKE6fYV?J~i!2oP* zE5G;vM1ykkUgDzKwNxJBTB!BK~ zul1*W%gfuCoapAlF+Y)D#I)tW{1LELY9iiy-PQTdA%CjY$f$N`t^b_FoiU{zm9fOnVc|kuG z#v(Xz{T!)!ak97G&6xS6swx&>1?Y1bsA1inCq#l z{7=1;GnDjQlA(W!X=kjmy1HA3X(++P7_hea>S!=G&lj6&s+F+Km=-&;)~ueq&`xUA z--Gq%D5P;>1%r7_Whtt;6)5qfWotbD+xPD#VEI{ft89CaF!25;G}zqLab^hC?-)Ma zP5k(=6j&DU%Z;5KQB%F({>{yQIq8DeIwc6Gk&%(U7qg4IB1mt*lu)h+uJs!Lqu4e; zg*dbh?@aCwd#4f|hdv@7DB`4UGFgGYrSx5V00A;M9ruW088k{hB%i&R>&to(?s>W2 z2|A}lmK`vTVQ=jg8d7BFeu7Z}wwt!xl*<%W81cf?FPBlJubWl=|Bwhj)KSLero zPy?fKoteW3ekOkU>o&lN4swT;pa<*_Z}yS%=|O)fCPEW1jVQ8dsTceE8e;=+Q!xJ& z6SZC6yjgia?A^!&_$UyAPNcv|!vM-wPOUmuW?uPoGs(be7y6lctcatgRYzrzLxLs`+`=BM~Gb_N+`L zrt3J>qlNm_iNE5FKtp2#d+V9Q8?>vHE&$!z68VVems;inSj(FA7ypMNZ#$||MHM?w-WPNJsu7Dl)+{k@{*NChM zJ{G7*Q&3k=;kCm5{#`{y<(2n2bAg6#|Gvy>s!h=kTmJ0tPtnlOP;i#_{S^TE)zwu` zP`7#vU|LFD{o|zRZZ`~Re!Ml_`-j2S%#04O?D5ezV7X*py+Zj7#LUcWtfAXxDOO~6 zXtdI1GS+Fi0}Z7HHIG(V=wu*w=V#+{!7q*)_6!}kp6t$R6>5OpYfRqc*tP_sxo(c2 ztE*2p`c#Yi4rYi^hYKEK9r1RjM?NO&iYUH?fXy7B#c{8z7Dv3EPGC@cQ}C#Nf` zkDFpc9el51uGi8<7?m>2ZmzEY1bXTxLTA-3;2%Cns;JCjfj=59GgVqs8RSb6hXf00xRK@SKNWWeNOgWe&@IFcv>)N1OBklSpI9O!~ zj1hgO(-|={oq1JKQW8I3?*W4?i!mjqrx(U~_$rIh&;+p*H{iGAa;q%*1ja$HlK~6$ zKHgGa=Z5o*SH_F59m7Y4e2OQQOp*vnnh7yDP1^1@)}FSsNJzzyp?|6l+feX}vx8p# zx!oB@<*>hcCv_K2GimVrE;Ty_!5GHJ)Sz66+Vpy+q=X4vuqPh8S5(+_0}?oH@$x0T z2%|3U9pQlye4{L2+MmWUKB0lw+gUy+-V6S2AIG>LZkdBA4f_pP!ks6qtbLAU9*iO) zuu$b1!c0pfgd?T-@$W8=p-I1$xmp(p7KPxDIUI?x2KMQ>Qhb1{#s|gOqV;B|mv*MFLrld38IOz7 z3B#1CtIPfyx$p2Ap%vgXYSwWa7UkN5^{Bmm{Mv&-K)J%=*&NEEefI1}-uK30wv$eg zdhK$HeSmuhAYCD~e+54)Q?TPt6Tbo02<#6N^hYp8C`_Lg2*i~&t8OD>5$kZTWqRt`O{PlxwL{%2qfh>60qUct__b6fsddQC-$ z_|=grFzjSb0qc-nBclIrA+0qF+}ZG({Hi7F`NxKLd;eVEUIMs1g@-@;ZTXo12cPk_gGq0 z|ACNA_xgvh1)oX`wk$ZrJ9FdPw{Ky;XWTUPD+jauJF5x`ST%|b6eJ`d9*ce+>Aj8< zdaIJ7YU_lxNc`t_ow&48X&iUGGK$cg<3`8m{LVF%vcG?q8||&Ft@SS403{>vEiRtc3ZI*!0*LfL{MWb8Z&3b?` zfcI=3soHX0lFsn%B|r#zf?Zbqw7|(pO=699lQlJhG_FHAwkRQA8D{nU+#Gi;B*@R=n(%Lr~X4&lbq&85j-@dO7M52TQXK&FDLPY{0BJ zYMsk$CfSjDi%PkQ={10Ho`R$T#BoZ)fb3?kbwvq@Km+1RmlTm}TUEOzFvh^E-}z!K zVEVM>1aqTFxPm}WRYFoyC-~I-kqrkT)Y$MmzVN?2W!VR0GR#k(js%25XKT260&Iry zdt`0Ib9vo__AP}VAnS?lwB*tGHNKzxkdm?=luC|LLsS&?LPJ8Bp7w)1?Eg6<;19U@ z+chiO0L1gCGMAQ?E*EeW7+_hrmWACmmc&t^#;swS^GVnwoPk3_ul+Cgr5pLJoBgjE zu4B*VZm+DY#DDk@GHtsCfON80;Br`P^7(+yme5zO-A0|@#Mg=~k0T74e1&GK9T*uI z!|mtmoPg^$s=VjWUpVuz%`Yml01BITC|>8fN|SYwGuUOy<(;0-J?fAe5;8XYCGj`A z;(BZRTD$aRYrfp`Ag9dqJ-El8|FJ9LZWuP@D|`DQ@hFG@TE>dwaX2l+^pw)E+Q$88tORAU(kr zw+r+sJnL%iqqd>-lE~nH4tC6M+u3Ey|F&6udR9OWgsP9 z)R&wvvb7XeFMJnh#l2qr+I+T!AOE-uR7=^hVadkk3e4 z4qF~(Zu?z>H^mTN;&{iCQ|q1vm(EGM z`^ci_8GcCZt9oLy_s&aOCYh?hC2E&rMNWah(A_OGcy_qBy-Ej21ea;Ym=JCNpfZQ> zk%tO?z5!qxVl1o6>5hK=YmTZYeZ^lR&|F@|^~ExWMRD=#Q&XUwB_t$-F|;r$q_%yL zg&pmwD9*VIsHXLIfT4hf8gd8;x7l4~Wo2)PZ_ERwFa`w^REnCIxV7%r$^Drx7!lcg z0@270r16>Ts;a}79kVOuHqnxRUzypUh{=H4nDkfA|R7lcxlmf9jy?O#FE z@CgX!C%(9^?UmZC_IxBHB;<5nk?{r$bVa|I{|lVAepYjGblJ%MqZwd zhX=-EIp7GejhJ1pYg7q}-2zk$kEBh@{?xCT5%cq&f=%;pxKo%|Syy06;?I-`*ZNYH z-O@FS^u7ta%uWGeIfE+0-nGKq+Cev#gzI_0^65L4q9;$D1Ojo8WJ1BmWiA~+Y0K4Y zXl(C+K%vO>%2%ir2NA$%(8z0mYXm+Q#BDRd>UY7%dn0Dmy=n#!hy98aK!HT@%U!|3 z-!<9anF4DqEg^zl zEt$4$IG)h$OBYE3VG3BUUhJO0f@ij2=gH5X&rzm9`0_W<;{W`AY`u9r)P45{jEYL7 z6=h2cO31!bX}2e2SF$gYeHmkv&|;}n_B~`5#?B~YH-s7M*kbJaKA7js^}Fx;`Q5+g z>5uC*UG$yraz5vC&U-oEvNp&y?gnb!hpMg4jTz43_Ildq{;C^qhpj(K%(zaVdNRVK>7o#QUCT;x&)-GHM6%@?KfbgoRVN%T6V4My499EW+lCsom z8UHal`h7+QRGk`3PsF>Wi;|LHOJJTP`Nhd2Po6#7ScL+0lMo3i-+iW&?TMTldfAPZ zCJVIG0tMPHMRS6YI*v&#oLI?qMkIr*B{@#O>=w)duWjEobL)B0vNjv>LXqt-| zD0fEywtpM`9eI6j45DfT(A-ro>@e=fT=mO+AV>*oXt>X#9yjY)ssB*g`k-{$LGIU9 z>C@9|cC{YY7PnALjbque(fY09$1=VW_8f$HT+m@tKFp z%`e)jK7D$GdUF3hADTiQO3x`0fnRHC=5J_d*q=~QL8t8>6SD%u+sQL$K&DXN*eZ{R zfaB6WeLC{pW=^aPDn(80RhKZH!GOl+764nY%eXwD1OwGz0dN-0?Yl+JvO>NR_OIZs zx|hq%ZTJTSBxdZTxYoy4tn%8Q!Z!3?3*l013*_>lT2nJJsNc_{7IPo!k3I6auav_X z@AgPmH37jrc30ub{xlyN){@pd?Vpih(^nKsBf`heUth`&Q^%)jZYkAl0xuHKZDR(H z4zTf0k=6?g>2MVqQfP(n_V(*ZNl8-fg6~&XwF0*8+%4)Pi)@USBqm%>pg`Xm-3FzL zl=JqHvzBe9TH0l9bMG=TsO_`FA#G9Fg`X~CB7+AyLOEoA1Hk~;WP9-x>{9xq;1Bq$ zujM>t>_b@q$#+LzTe&=!a-&%*JLU+RM9XD$zgLA$kLE>CfNg4EcY2`jfK{=$_~M_W z9*|d776sVNdm#US<3hJYxhmcZ<#cxT#u19M%U%8Y=2$s7ski4%w~aYqI&fJZA|tIM zBw+h*Z*PxsateX|v!-Il-tmU5TB}xpyZ#(Qy~QB4DMnKfA=X&@qb3#T& zQ?A)O1DAJu7IXks^Sk(XdvD<;N}Zdu5pv5}t+Z$STU8Zh4~fsx+t;&zfCt|YA#66C zWi2#bTL3L3Pz*PrDQb0&(y(ZWcsi*CEp$5uXu&v1L>#fZqtLn&8t)6z(vjMk zI>Hb=q2w%lZMo0}&D7MCU4PNhJDRN0PT!307V4bFtSCd50XrTi&SdS-k)p4*+$I~8 z-z6J1s)82MQ2vd!Cn|l_3x>CC===%Iz=8&;Jyv zuze6x9_$Om!>`5))>~RsRCrExbaV(L#dL+oXuUputMIuGLwoQ~XQ7wQ#iY`*Uw`Lq zF=${9X8Vhow6)K|#!4+fqMvBmUeFq`uUW$#@IL?&2G$8}jVHeE9`?T}>Um6fuMF>I zjo&`g2zqbF(&$@DJ3Ck&9@KK=ZV>y=Sogsxk%bTK#{uKI@p7e< zw6@k|$X7=5uCnoRSnq8&H3_~vB+kKYAstn&tF5hJx)#1J39%m2__?2Vh8Ia?0xWTH z2M#!`I2nCS%eXpzW;~&5BD&G;*&q9`lBHBOD*t7J`BUm_`A}K8H{X>J>H@(P$Gu?q z%@~}#y7#Ley-B|q;f3{EVR#Po@}KxZqK}Df9*XP+U^FaQm+7vzk)oEsFX(AZ?)W9COA$pU>@_tTrQ^pQsWA$jPD%m+f`-cBUg_TN-)H+O z-y4;?cjuU?mQtQ!D(~WL!ObmF%;Gjmc##)yZ=^M>OP zr79p;x^w3a^#t^E!@3Y-n?No1UklI(>m0n!VK6L8j$<;s=SdfA%@F1{Pg5JDo zC;RqeY+1_PO0V#Wi?b|%!{u%e>&TzknBuSZ1{_<$U{^*BIkD3dxsH+lS=rWO-i^wc z-P6u}ctI#`pmk=+?7n;d{&gsGz9ELH1gEG=8z8wG<2zf1L?5z!_$oBs-%?XWV0BX2 z@%bvUL(OJF!g(wjcH>yyDu;how;QZ(AXL3pk^$or53(iXZ~%n9vpE(D$?&>O7hm|U zj)4$5q_h>KX8mS@h}ivCec3$M*BtNM1ib-Dv-tta8yq30{%FzekB~M---ES)`mc zuS0=Lu+-MmYn;+b)9_WOM3S{BhM3;f1)e*Ok@#m4$u#zK`-HE+CVk9>TrfH|+Ee7p zUmwb$gy}uP;z@p_rRf_d@0CDP6L{3Q)R6&cavkc&OSSc#RVd`Mq~xiA(t`f+NL8NG z2^CpE6$6Gf!JBVS@oLyh&|PDesr~)vLp-hzV|$2^aSU&OxSV5PpCIhnFL63Snbc;? zc52(%~Ns2GZ{*i4~m?$8Tqfpnysg!!)%hJe;}g?Gxl5f>975v2wRCu z6a!o7sjeRvV+Rft-Bfg7$A_?qZ|UgiJ=jin(MWKQCni*b;6x27QLR*!M5X#;E|XTd z_HlruTkBon{>i=n30=EW^;Gwn@Ec_xA4MONa-Wac%X8e>T%t-reAePwxwvrnYy+we zMk1|3MOF1cduZCy(h{{Mgc$6OED~>SYFd_72X%uQNDcsq6k9DnfZ3(B6&Kifn(3J^ zn&WxhJ_0{rm}^`)(59rEwuU5mcq{tsNP%1)cx}Li;K{i6lZ{K)FNp%SiZX{Ndye!y}`)H1ne|7gl1we9t}nIdT{Y{*W|&epJS;KymYxyAsz2wSzoItwdE zZIX50>7|yvjtkJrvD-$M8ssqZ*>$EKeV61hfY_Cukl2t;;f_LL*DTp2Ew`{eP};uy zilT0owI(20=-$Uc?RTj99$PP1R;cAhUckvAsr-VLQVmMY!PFH}$pn)+Cj93U2e`P3 z`GP9qKBycfG432^n3Jlv5W(ME=ZdHFIUp={FE|u~d}dJ+z61EEf~zX9N)& zj8zW(kRXc3_qUro+i6tyd6mQm8*b{I&!^Ch(svGW-?r7TWZ>$HPQ(~Sv*T^<_TTGO z?1}c!`N804v&Vh`(e_fx9sT`kI&$MxhEr>V@alALC#vjR--AUcWT70p#kJQeIYhH= z@qVZBz6}7xKAnrO9N8QM1r1B8p&F+#B>r-B1DatPb=tnK@Bx>xhDJ58A2j4TrfT@7 zEpR%9dxaBDfXCzDvm8C{Cz1W5+epc?y2B_B5G+9gJ779o{gUt9EmPC;kOJ)n%eoi8 zS^$*FCh4&M`^qzwW-_!bPTQ;2sLdZ{^$kt=l65I-_T%dMd5U&Dkd^^;T9y^seb67p zA@zbrTYIYKM>1hpdNZC5UQBb`dil)pFs0=->F!e$$rXg{e$oFG*^wwit<9+i>%>GrUz1K0M&%XKnvXi z=nPt32;-DBZtmnHVw$VE5P|>Ef_&H?H8+Gc!F84y-)B|umNFeW*7t*97%W5s%3iDOtZCfqG1Gc#+`xuueo^m*F`pleWiQEvp+effW_gXXcAKZZbBK@%6m zA&XDDQQsKG+gs|K##tNYH2P3m8yc?t)nNP@6XrX(Hy60q9>>O^=wpbmzP$o*wQqg6 zq?|>GeanlfJ=;LC*!*t*n*+_Pc%NlU#Lw4c8x?#QP#V8V~zdh`CL z+0oUqZD~ool%#}WR#$D{fcjMAiU?dhsBM5&E3#*!HrKL)c~5I1q#Q3K-wmeLv4E2q zqt>(`nJ7cDgZI7w(??|(5+~A@?$DCNPVuM=L$}6-+}LY)xsNNKL-_QYXV6F4z`ge zd8V|~ga$9LfP^xGX@xVrbm_IAQP~Sv8${HGQ6*waz@SLO*jSB_V>H!YoJ%lwo52Ue z#_hN|sY&It0l*3FwZr@Q0#tNCPR?*av7S&!6D?ss3TO?We(~iCRsFdYc3IwtDOkpU zO2^0}LqK5DVIMU)X$3DD)5NX}b)-B|^OkpjQXI}*59=e(uah+ld=V961fVTq$W_W z(n}nk9k;OX35Z*P;(=cvQ)mQ<&MI}^NdaLhv*NP1 zv*plv``*13kdVUMB=vX&loYi3P?IFV=ZMycD4t{5(9Rp?@>Ee<8MstsfU1CnPjg=& z?x&}BS{%L!kQ*SFY>0{r zqoDB6G&F1hhVT{u#SN{k-H68|DmLZy546|`SG5Hg%s~ME;i?vegbbXjB)^W;&(+5P z9%YQ26AzuDzUAWz@6q`Peh_zjhI(@Mr5OM!uua8&J|!u*E`3Myv_sXF1@vOc zCP*XC@h_*(oN-+K`(U?ESr+fXBlD+ypT|H@mSE$i!s67Vt1#HcGR&_;d25^l{Gb~!&(Zrk|% z=Va5{b@n+BAW;!&!1z0g5heg~tUA278_H>9iCz)d>cO*)*XpiG|7TI!A9W#|BmJf+ z%^>g)Y@!MHqOMWdd7C$~`Mq|6=#ZO2+SR>|t+6?X);G4RRTY%3rKgR*y;DHV#uMn5KnC()9|dvH3f z&{YINxXZY{`~3Mdti(6(-;d>#&u2J$)krLkmE*U zJnQJOu}l6AW~=|etpuPUwIl=O(ua>9A3S-&sz}+w4H9olaWP^_O5c5r zKm4xo`N41d#3d`%(+lmN7#lnEr0Scf_AR)z5dfT?^o)#)1Dq21JtN}+=omq(M7TV6 z6qd18A3kGU)eJXYE36JZs4A3kd2k&vE^l_p8_94TfG4ejVlq6r`=Cp)5H;t3-tagx zGvp5tC47e8GQ;SDr)3xVXP=9XKkJ>?bI2YN*S3-<5d|6*g%ov@{&uvx6QT@YL7H2Oqmr?EL;0%`k#x)2J| zsH%fR(nyM-+PS8F#OrNRtSqsq5ZnK_=`BM4m$W(1UIQ+js@oU>u@X6FB%Xe?(razh zQjr{~UQZ4%h7|<0U9(lwt`0wM$jmrS!l7k(=o99(lT&((R#ZmJW*Iv=zSSybLH%0{ zD=dbo_{!L1Ow|WAGes9-(a)bhL8**QfGY5N#%{_EBx|ilk6!iKSwNktAZ|a=RIDhCu8wJp!G(u40B zukBnuH})UpK%GUw**5RrrxJyqOblR4B~%b*Z-~`1s|^9q2aT z3cy+U%d8Lho&16V2woSc5sX#kL677Fw;a&>x1pf~GM&wReRXVqe1+Zps$zQAFK67h zNVp;=Lp56=-nideUIU;$rfv|YSy)bSZ~&B1(JXi7&QjU2K74-q)x-Mw-BN#Q9>+P{ zs`wHH=S-E0b!W1`{p2JxOJ{#Rg_M?d9NiCpzjW!6*h6WU>G9mc0-All#^-;??_CLs zX_7#d0(eF}?@&(p3eKTjqx#=4QGd5!qEvQGzDRskYKVQj z)-%pY?ZmBv9r|bKCNaE11O_XN-z?YT$GI<^(XS?|=<$_lwwwL!pxOWakK>g;`zAU4NDel!vJ##1 z_qFFxUnrp9eg-5{jGX7E>FH@615ZG|kHXdqQDF(~AytT>nS8gj>OtmirVM?t?Y^lT z+J%71Sf-P=S^oFIxnI9X1w$Zaez-L0XqV!-X{C&-@VM%^&@o`TNO-HOcaU4ZIDU85 z5-bg}f~t4YL%0U^cl^Xil(=x zG}h5hM*hb~KRJ#COH#?D({~)FkUxrEdLBw*{C_W%`bms8O#a50w1-1(?EE=7f=z5@ zMiaa(mFK53_iK2kA;#8|O3l?j3a&ZPEA?&S#ask_4a4)_$2h2I@~(Tji=oV{)tO1P zNR}R1PLef(qyro$-O#r)kdt%sx1 zsSGQ4NpBT9OM)1Fm^QJlWkv-kLSAh+jsUr+1mykxK5~b?E_0&hzh_wHACnr4Ib} zV|0`jmG)V>?BP(5&iC$BYid$P5i^%uygX9kJ&Vu;yu{XPP7Nw>&`84HEt)=GVL_hp zKOX)ADyGNX7E(oY0b^&nIK#T5QU{JcbqI`_%=qVP^e6v2>`G#$#M^DB1Qaw!-hKCPEkMTit36o~u+c+_WxtZ^$^k-(ND=eHP!IBQb0@Z~!c?1}>1#93C%w0jKo0|9$%ojxeS4*=VB<#r0FN zkABnD)=Mwa?obfP2l_c0cE`LIBeyQt;+vxij@c4*>{!;5biya6R1)PiZXut&Ev41! ze@XN0+c%I=Gl8<&NfU2$(9yGrpRfAa;q&LKXOGk94$^nTMmsS?U3w!(>+;{RX&7=k zvpZunb;_+i)o(5JwI)DNFsG+GBY3*WCaJGDhGsiP+WAR^hp;JAjBc!Pi2g@yl1pmQ zzC)94xt#ao710V*A#hku=J8urPAiA=_Uq^I@tnQ`*PbkOp#A5SH}mPtUaeA~pJUhf z|19^~@l=UlqsMt2kHpyyt!;;7$UiYFfOkD)w-zN)r+Pq6p*Aq62+*lx3H7!=oiSyv z-&KZcdd?n=e?_7xVnn9*D26tTA!yeBInk)U?yz7)=REWc$_Mt)?z#rlyjH(5_*z(k9JXPDkR9c?Xp%*j(6-QW17JQhuXym&g< zTp_Y6_j0L&=37e2$IqW@VUN%Ct;`+zsf$4yA(bCXpAND-V{hC*=w{$;!gs?$NgbEK(9Pgg}dVGrAo#lqEt%B^j z|FPfKOJ9wirrA*Z|A`Vc6|cMj)kQnrauFc4k!X_hKmIE@$}FSum*^OXy-A~ zv9>;Rk11t&X&L zJS~4er%UX>tdya3U({QO)6{M66D(C~Yf)-5jDtE(6`J9Q@;nx}Y$!smdn^v$jV(T& z5Yf)_{IUG#V{`}5Hp-{BL5=W!)~pn^93%@>QKP{xep~~j+`27)#+10x{g_2 za;B}L{y=v_doU<;IZBNUAu!N?Y33>akB!W@xH#ga6~qG>x9NxXt@wCDJm(QrKlbmZ zck1pQD;;fmdHYVC#*+wK>KbLNx=LQP%FfaHaE^6RrSvP(IeWce{Oj@>tVHy?-mLCh z?k4XCH24kG$IQ9kbzP#CE`n#EJ{hYIrFOUggHHBg_@QMnPJ;sYTUwg)M9bNvuZ13s-xa$f21EJ+}AnE#_x@FYK(vjd@9;;-3uU`KnPqhVwK&f&^ zZ2%VhsV7(HCQ4Szhp*Ef%14yi z%V=4)(3uiKxSp)8$FrGN&EJODo7rMKh+uolYV0y{D|vtWnL8trLV~r=4w){5%5E;8 zzfO*gmT!#yjF&%D-GmD-K-Pby7gB$7H_=qF2wzdWzwM`kdn<+zqA4FFs`ggv_+Zc9 za_X7uD`;zP0bNgJ)2|2!hzGIBdx@#bubl?qKVSszPVtaWG*y%!xWXpub`7*47ZMW_ zRm+G(cquf~Y_A!X3A*9tJ4^|=`j~eBXV3s+-vrQ=(De3yA}nd^tW5%ezQfj5JW1w= z?hQ;g{*B$?Lx&DsGc5UV(~q9EeQB%Fw^DI+*)Q@lSJSs0Q=Xzf4_|G&7UjBIpQ10# zu2YpnF!<4jCYX_O6w-?IvV)6eGjpocC~`0IY>#8j(sEqpZE`!DUZ4+~t1->&Ed8wr zH-x}s!*1mhS6seDsJOgepuJ&k?*G)#MTJ4eb&CFmp*Pc^1QU8@0i!9`or?v*gQAxF zd&oBsP5Ps-mA_O~l|Z{+ZEF6}Tfxx4f3=Ct-g79&pjEyAeXKgfeyBVMyY#jHtn*wj zO~raWNy^IuUHP?>hwn|#u~-_i&)U!O+`WQR5OXa`XhvKGBi?Q`K21 zFke?-%|mC+nGuK#xzE18b>MQy?Pz~eIPCf0OH;fLAGdgU-*pAC8{ES9ThFrm_k@|f zY9&!Ca}yDul@qf%4tX7Kixk6bVSOs}$WFu(pQA`O`?_a`tp1Fz&vvU*V%(Pb%8Mv8 z=YKkP{PoV3p1)#bB;Lu^1aF1WQN>`|wF9F_f;js#H7-11jh=b+sRQFD@?gb01?x~M z+5w0nzz;z#0uRd%1m*yjfIi0~_8!P*0K@<^^(zc<4@JF)$xd3paQgPz@m#-toNDMk z#x7O;=EOxXfC_e6<8zEMheAQVx(LkYsWWHp07I_0I|V#-0|-07nVH4Vjs@37O(l^k z&H*$Y^byYhXZSll4hoV?-Q4vnz781uHRO$g-YkDNUNHBwSXicJLu6QVi0T(}{(ejp#&_}qeeYIaCqvz{W^yKMt35)29 zw^+MV_Q7M!oAB^SvA_mpe{<*Jx5^y!T{Xxs%`O#ObHC% z`T6PI zv^<2`;28TIY}W9B8&dW0JQF4q_)jZV|0oM?onm3B-`QG$SvF!vasglhVcpY?q&tEr zf**gLT6-k*rJgt(P7ANb{c`r|(#z zrIX9{A8((lx_dN%VcqMnbIbmBO_^I$3=9n|xx+-^SdYKk`z7pps^Q)lJU%XeA)kXu zVfm6NT55$*y!ZTjcH)%ci-VFxCs`WlUcDXUQaMd+t=r!!2F?SfHDy8%dhO9~B%zX= z`Xe5aBU^m+>K0Qm&6ZPit9^) ztE0qTfWcWgmrFEg&)ox+^bfRbxz5xybc{`QlOC4Uxz^iYoD_K9{}o`{8YxFiUt`%v ze{8&rjrRmw|Dl4qTli9y5caiF9QNm+9*R2}v zzf!s-?Yhj$RYAU*l5%-ljHe*dHn-eA@nTLY>hTd8k_hg_-$ey{j^2otv2>1Q^suQ@ zKJKH>D4$98UJ#@I0f#h4W8H$@mi7@{QLBc7Wp!%_lecKo{;20IW1Fuu;If@L1SRJ~ za`pF}H(g*GG&){MR4t_zXTM(Tfw&W$DQP=z1;%@-Dw1k}0+|jC)ei&noB&yKLhcrW zX$`c|t$-Te1AMRQn!p^i22?xd+PPuZ-YQf%_aLxEpvNIW3`1rC<1Uku#<>@f?!cQI z8RPI9&&Y5B)tk(|$q?)ama?1sw8R3Ga5U6{LU7A-y6X!3v<6J4Yb+-#)?Us_c>@;d zP>cgVR3q#&@sypkz2zHvdZh%5o@|{=g$hu;`T|=QzLlBr5a?tULBsYy@J_}9LS7QP z0Q;@S;!g%WVAZH9hCnP}PuuUA=Ti*|ERKR>`!{UvvBquqpM=-#{G z4;nN+14gn6f{DDl+f4Msf0r(LwR`=YbbKAi7JX{Ar<9*V*8RY+-EZr7x=F>eG7sbL zg4H8Os31Q-sSP4?dV0xa!5Up{DPa(G*;nEDrj^e+_4QZcvS-h5G@sc$S-OR{-f<%e z4Je!zjck=uMAHtAB1=?|Gk;C|AFs5Vv7 zJv`TUZ)KE!q2u?|PlLxU*LE3>jZ7G%Ep2SDe2B{LoI{93s>o4(u?fzcJ<$CxPYB{Ayw3wMd4Cd5~tIqTf zq| z$5XnOB(heaecGSQ>G3&T)WXv+@E&Ez*=smIsUjvL53C=b6182pB=rx~P!tJZ3< zGIe{q#1KAYWc=0kb!b5Db9%z5s(egs?lG z?s0n7<|*_k?}u7Gz}g3Ei=8)dI`i-H?DmSt>dPFNdpPaD z(6}g1L;?Up4>KO;E8DyBx?SX{-8<%+K6j(bXv_ zc5m$<6hMqinvgl_Ikq$6Wz3k12P_tNUAB#w@-A*6QSvdELx)G(UshIZ;N$s(3KSRN zoh`8@yAx-Ci~|{cX?33 z+UXLL+@h~fNIB>gw!nUO1k)rcBGQ1vNe(a!0u4^Jisx+z_$*XzS?Ym}|1RUcP)8umG9QH776` z%px7eLXfL?a_vJYuxJ zw4b>z4}7dO3jiHt8IQ?>O9#Xl(Rbc6PmSqj>(@~QOCngsy`@m9fEqk`A0r|fpifk+ zypujWJWNla|IeN*7E>quC`TMO-{T_d5M@_PaC(t*NKX-p(~IK$*wlV;!sY!U?zazK z?$(}dX?*rXh2fSNk7-Dxuec>gw`Ew~mzYHvCawP4bh(?AoN|<1%lc`D0e2i3IiXUr z<+e*+h)1=2pg=sX_KHAgrWklLsaS{-43VeU2)T}Wfibhr70aW!N0{vF#b2&})D7;m z4Y9P09Uo_j!`lY?$)B%U#9_yna;wzs>e~Pq67iVid*o)n@4VQxm}nj%ZI9oM(C#{= zp-sm2$=*A4${mdt*T)bgXTo}0I7GoVeNT$N0cSQ6kG6e6=uA^v-ZL?NIxi|j(=Lz` z*l*3&d9fg^@cWj>=$yxN4^x>Np9Fm#$M&t=*!99>oiV`P-o-AzQdVOv|7@t3*>4`@ssy?qJ-imHbIWJF!P*t(Mkl$mRL zed29GRyHWKZJ|OVDrIdh2fX8cBS=CH#z;yUSFRxRY-6?;l!&Ddwo|`;{P^_A!UC2O z2cr`_RdNsX$C|`}oOqmS;2R5_GrF)g+2IEx41!@sjNgY3A9$Vs$@i~)b+dWY{+lzJ zv|e5Mhwr5`7~{Ez(Va8y8%(3~dpAEn)?NBFpZ)EO(fO{E)wLz_hW+XM!s0Jo00Vv; zyC+%1m@c?-y?)?^X|4&~V!3+gQr$dz{MX7Q-%9)(xF~mx5hgBE%qEsmujeZb=_bKg zvN7c2pB9IaB<-~e#f>5ss_qW)GthkqcaQ6SK(XFAQ+4Ety$(G0moM$9?L!EMv?*&m z)Kd1?QL~)b1T-9&A5bbb{rm%lOOu%>nEOno z?hC#5m=Z$I>Xyd=>@#;#j^MrC@hqp(=fb;@753iHi9*ikxCRoSYE8{4&SPl3NbxJrSFGu%B_-VByXQEwq3Nw>uA93$Cy0z>t4 zk+W6Nw)%IMS1S{fl7k5$t-BXY)Iyewf8@;N{6i3fZcP|^**yT$W@WCuGcR%yz7E-nnXlq)^cw%;*Td-(7jL2_eo3wwgwF#fpJ!MJ_YhdK53 zqPN%RL4w=#?;y^~x7M;BBz8^iWH%&DuVQ~pc<=K~nW^0GQXZPLY-4N^JMX**MizH2 zF{=+IGjsgW-S4tPicep?%0F;S(Zy8gN_p5>x#yQ)0efBN7>+$4B=N9-9G+Zw>fRK} zzjD1n6zl0fc8_U!Ej+$J(G?seUpUidw6&Z$UKnH=YCZXYn^2vp$f=of!DU~OqAw8m zO0&JnF)R@~=GWrjIJkxjnObQhdBkugl$E{n^}Uf~CgY*ve08^^-tlru-Rr=6$61e0 z3b&4DrIMY^?47^#*-VNvSO_#2v)Sp&;}3`TjlyPrdoU(ijzP+2z(e)asZ&Z19=v@D zJaDHW-9TGs$(VXDf;8+1p!Lxq(17JIw9~@$ph=JoatAvPE6VowjDNw>uHt_UzE5fU z`NBksgaeUaC6P(S7ztWoKUi-+Y`U*P31el|eFLUlx3x`xyI@=hz4d-*hUedF?9FfU zB~}gB$uNRZPsIddmx(R#cqs@#P4@T-8yf5hsDEwLCvXY5W9w5 znzfdQlUJp1lPQDiO{jW!b5))Da)mb+hSO?*z&1(4#LX3 zUg)M6>cxFNp0EcC1s$58{)fRwNuazK~X(GF9g8ICj<#Rm0egad9SYPRWO`F@TPlxfLV%CXV}p1s9}(bAL=K|I=keg&&HsiAT0SJ`)~(O^>c8 z`uPSAJfG09n$_Vg#`0pXBXP2Q@$t>@ak*uEp~q$Y$iwJkM~}q?9*8`|l%EF)9Ghl; zY}`EMZ=57PzfLbGneVyav$y=Z;GkVp#P_Yt{cx3^mvjqXgt@AR5>v0XR}4LG4H5;;F;i zo`c43+l^8usl~4?PADzElApOeHh5x&qj4sFCo0*rTMa5;SHo zJ$pU%NRHh=$w$>_31JAG9OZ+5`^5+od6;3((EFm~6=zS>g4)B3%z>8Hg2E)m3gmfz zbv5>p?vDhT!)Ld~UDZf!d7LNKJyS6)=LU5{D_@4h28rMI*`Dm&SzaOwMKXvaCO&Pg zYWXyJVQ(AX9MNi#Gb#C@_NLNQywvNE*ty-)^z=nfi3pQ%0(K{zNbv0Nr+X&bV|&$g zvd6zANJ}-}0rDFt^gue^n2Gklr&(X+w<)K6VTdbcsc7(LJP^mTBE{4pwW_0dIy;~^ z@U@SQ*hY3y$*Lc8^P|hqyccP!DToE)SXRc&ZYUNzgb8du;&kFN!%N!z zM{6T)aM!(Vi9bQCQGOjBskWPC7R%*!K|uAUvg}^|;^zmk4;xJC!^}gve>{>E9z1=9 zq7E zhbgt`fGkbJY`I3OdLNj1XFFUyJl+6Un8jl$0R3$N#L|Zljf#p&a&A+k?Ck5)=0WbR zJ_Chb7sT161My_wOiDnZ{2ef0*D{CFZ&vo654-?iUGo?6z6q+`KLB8)P^)FQ7jJWr zb!T*~;HWnC_T3OgAC`u8Ve~-wrC6t?E88%e=JXsEh!ta_-p9o~FQz3Z3W`1U%Y$PM-AtAD|(1jp_S?aC-+6V@mC z8KH(NZzsu;?!}Yee=3RP6{;|1?&lmf?1l>e}HPHp$21R_;zYRXs& zpAIs9`u4Ftv?B>85Ilk0j#&r8v4(2pXG)4?b6~Or_Ze z8V-QPXDaUQo|sA4xVOHQlZDJ)`*JqNoAWSQ(!@ zm}#24z7qH;6t!H?Av4H^@3w9vDW1Ww$GhUCGgu`PbqPWO{4;CpvIV$|oN)gk){s5U9q^JF>Npn|{ChGsY}d)a-Na4#(#bNI;34KdKTxqD zH5$P4b257I#B4MeRHxTF>rPc!qbWZ2}_~kUgWp)-imN=k+$~~pAz`KRoEdkK~?M- zIs`Ky^~+qW#jwyO4+5kvLyB=0`CX5Tmh;R95?KMFF1r(Vjk!eNpW#;{TELDM8%@`rtPy|zOZI*&Une=OG>Ra`ud5?+KEC{rdbLr)xUGpKe;^f zjI8o;&65~Ty7T^>MEtWzx$!|6^Xc?YmlPwrHs;F>5LLZN@q3#LWveyapT4Q1Cf=8g zP#)j2m1Ry!G1o1Ww_bjnjoOPGRg;@o=7JrON}Oq8G4on6hBA1kBsYYjGo)w9S;}zeT4P825>y# z51Z+y_N^#<<3;a^%CFWeJp8n0xDi9_!x&+8AC@3Q*r3Ggh)B)o#qBkmFSSx8z(d>6nkaIps8Z1w0p}^(ofw?RX z%v#xC46=f`3+KRW54?@bdavcoZ?+X7q!@JTgJ4duv9{K9b}k4KhTET*e`LSMPF-0U@nAw19ShAG~eCobN# z0>c7|i0Aw#JWmU5_M^BJMWtz!$MD_V)}XKQVYt60C7wauFK`Iir z{L5E~Snlu|Y3p1YNFDTY(0U)&UueKqywDxD+ZeReS$`By$W?f7@96#SWo2cZT%2q8 zFWQu>O61V2(*UKMV$g@BaD93;{mE8wt#q=dMo~Xqa>(xECHcLci(W(0B5iiQ|dB$pIqv` za1qWfps>b6OBo?&9b@i>p5--bp*=e1Q#`F(=5iAgBz#Wfd4$96vSi`5dgf|zI3?-S zko27|okPjOXQuEmSd+CGtA6RU+-pWz230Ph5JKx@#qUd})c$bU#A|4E&O|AUsZ=8S zkV%W)BsSSXjH7ZfsU-V{v7(`8JhSo2gR^EXH7pB%qAV%jF}6CkxHw61^J$k@iIvK$ zs@WV1F`cU9Lm&@a{@`Z^^1K{w4%_X^`+VL@CUQG+vaZMmLPS5i@W4{3^%f$Ugcb z8s_FHSNZwNIb)~*qH2`b11L$Rmr&(VXv=z88GM*?nX@-A!%;G>HpL6FE|cwQ{3|e} zHuume9;;ukf5~{CHKV3N=pmC6mi~#6;o(LPd7?D$Ddo-rMs9M(wp>3<`v8(K1*ZFL zJn#@apgo!L_9UigLDSYLRE+~2qs9^M;9lZLCZ1P8o97C~C|r=yF)|t?W%sN5=swLR z`|J#FB-5aNb`xw&t=o-Ja6?yXb4B*;k>^X5B!{Y0KDo>@2z7AT#&=~N*egew8~C|Z z6d7G4p2*r&m@5>$bYSKS#dJlIvFxt9H)4z6Qm>0W<=>Rd|J&B(S^{x1TrtxGyLZn0 z*V{W-cLl`UP%Z;{an8zqYkBP6%xH5?lk7T{Yxg73V;2*I%C)m?uWYW$Qm4!ae0qf| z7@oFuZW}BhsiNliB{w|cFxah>5QXh0sKr+acSx(97S`L=16-LW1GeyljlU+-G+6D%hP(X4#nu#ke#wdTHu9^a(q+}l@ z+uWq>Y`+HffjVWW7#3k5db`%L%r*CNJXQ^DOg8+z;1ByjSGH{-rifWA$C@-#X1#>z z!#|04p7j@3pNgX(ZHwm(j%50*M0`b$@%L^04ymX&(08-$H7cI&2t-G0Y{nB5(#U(e zYT~3V`9UHvCtRZ9yO8&UnHQ=)voeZwQE~63&vyI6U9%x#Mg5EIyWVN;jYE|Atx*})2?QIcSNaQ24yTP+zZ>33vJ_I!Z)Lyzm>7I2xXIkBYjJ9hq z|Knm;^R^|Qw>M=RUZk`sOu0e5XahXg(Ka=IW*@O=;4xHeS z&hh?C)Kqu`O{*?kR%JdWF(HNamQuj6&ZXqv(@<^~TH+ikx0~?COwLR7{Aya7eYafP zjGAF9PXBf(@zd?MS(s%xe%tJzte}rs;x`YJ38xEk-+bWp_@ zF(2OBKj)k=u0N46NK1o|Tw7bCRx+!*z`*`9QMvXk?LYT#SmQY61&$!HX_}FptzB2> zzR|l@f9$Y+zT{jpHo)DM%qcFmdoy=FrxQYuY{!X^Y?Bu6LdckIDD#BfF|n*Hb`!5m zG*U&ZZtlb)W~I*GT!qZVJdmmw|8>I1#+s;Idp1!rzrTdUx$x|UouS-ph>jdDg`S4} zDM*!8yR@dlT`RkmZ~o82l*+#&Fd*BkCh}`--|2jqNp3r<=~vF#qZAf+H2jkIoWQl1 z6gm#6RUkV!@{mUrEnZ)8?GeP*ANKz3rf^Lv%6%(X&Ba}gh6dpduPN&gvb87h{?Czz z^9W<{C#6Z-Vs`17nPHc-k4#4&N7Yup{Pay8QK{3uIWaMz5Xs<6B+n?%TzU|{8IHU6 z)6InX1dVOX(@U+piDrdp`Fc_aFE2J?C1^_qxt~t{btv!fLkcIk~dW zFQM6}=BWqbhaJ!?=tjP6=tz-mXwUTieFOH-)W7zj_}%{x>kgi2FiW|WfOFkCOUy=h z(PL+q8cIsw2hy|ELlh@x7P#r4_FGeT*0TClu@It56RB*M8|e~;#?fN;<9zIrXC{8t z23G&t8-X79D>VJ~FPAr~a4L;cx$j;R{~>Cm3yV3yiM=JC^Lg8D;p-6q9dPU zDcLjFghBt-DBvCVnC3RFy#zv}OYI$#3f|Z^|H*!))OSsp>m;r93LRpuPL4xl^)t}O z{Rp$ny(n+7kgbdPu_J5Nk$OIZ=lnmCiWPRb;#n(SaxCor2lEn<<{+};Cs6r5b{0&* zgdpT%&EbHZGb-C)iu%iy#I~DjYv%SCy>=`4gBts*8K#mMkm;6JmUUANJKs>kiCk#P z)~NlT3d6v*_Clc8nv<}wa8wUaa2Uw#*%M;<@zin60NV@msX5=xmQd^(cxaejhZ!xJeZ+)Vp?5!L}xO*_UYCyR@+6BMV-UZ)jAj2!U^l*cKR6oL4T{*E zeb@oHH@*WWMtfIkTxEaRY#lL9uCUA_XfGDZnvai;iGx@1BB+E*#XaH93Anuyd3&ZE{!l&RyA40PTj7zw9&#i=K!H{E5^Z5& zKsQmV5o==y@hRY5*U*9eXZ53)LHQb=wcaaA6_bpUfe5wk?(l{2v9WVSRv?gT|H-Cu z=_4c3Le6LiGw%a3IMB1fy~SHIpNO@lCkH=FjEocj3;TCJlDxTtQ$Wa?NN{uZx)(9S z2PO(0U%>e!l0rlrUNRi;I`R~A+ETRvwMwv*^JuiBv+wx>^Y^aoqQFqBex0haL7-KA zC9&=&{umQT0VuuCQ8xw3!W___HxGfYVk;^uM=R_r?QCre0f&&NVG3d*V!Ji4TNVoQ zvMGZ2oYVX1W)sw*uFAJZmkjBMazy)dMuiR(cbxUydi6bfXZ#aru4WfF<3hhs-p*Tt zs6Lylw|#YFM?><#N<;Lf8)V5im0!b7ZH0S+-b(yBE2f~0p}~|ArynSk~-phZ3aZ-vC5#fw#Z{; zOUpPlMf1)4g}mw_cK>c-HKjhhuD-64NOUFo`)|hHrs{XV^<&<^sj%0mTMZgYIZ!E3 znjMaDZ>($>8b-e18ae##FAe`@Lfwj^O+jYn<2@{70XUq2Iae3$jltdouaGCpl>Y$! zbR8y7L5csnx)jxs6miqB+J}4T<7~?ZxYeyjp}zkbOah>Qd?bO#u?4{WV-$08BSdJY)Q2>O1HQREu@OABY*}&z5`;t1&yis;gB3P*sB-hl- ztB2oWi0e)sE=!9X=M?WeOJ;esYy?4n+#$bk-%fGr^}|qjakAo7-Z}$XN9f4NL7|QXLkZ+# z9&fJjqWE>>RnLDPv;tpu*n~WJ)uIk$i`v=!V!4_I*^j>3Mwqd`{#1zX(>?uo*V%M>*Xe?TZu3e}eP95syi;5Pk2T0s-ONsy<$MnE1RLePFI4wi5Y z-kC)CQVXkzP&acat}lnm2VyoEzfc$VESS@D^~dq1cS)4rhZ};6(N;qX%dEqO*1 zqR-4>Gpqf9jJ7jHJBrpPF!i^%kR7hHue}wqXRCrXz36pu4*0q)PD0l8fokKgjVCNl=kJpVBOyGjJzV8(4M{U@9 zTjvKm-lH5*wEQmQlto}}ncAC}@>AIPw;6>k94*$qDjSjX9sY{J?o%3-`7z(rY#RS; z%(B5U4G*({GGq)!B?#A=D6ZS(}7ZlH}|=R8!J@dtCk6{I3DCX)g&2_R3vW z)!E`@&%n(=hFVu*(2ORHaa{k`a|&aiy#W05I;c4ZG2Ti(U8@s&Uz6prUy2< zXKl(;yy>NCg$sL6_Enl27jt3r5D>@|^EhweMu2z(`sss?EDaW!qAf#J2PB2LMjGse zAiVzZ8X~#IDR~Jf4L{Am1bV&-7cB7MX4o`efT>8jg-M*2P#a%L>eG$CPBE+qy;Rf% z4axaqK)+)nB}7DAN}&4Yifmz!Cu;ncpIrkZ)feQK4FCb_p!dO(Aw@JFoQWe11$5Yixm zW^$gyejuxxo1vIwzht>AINgM|QTLRyzOvNGM{Nml{S3i}={7hBG;dDQ|Hc+FRiWGAOpSr~)2249^i5EpMJ%Y@CGhD{s6 zB=Rh1XBB^@q+|TfJWk?hs+IFyWaXtQQ4`VN2x^sH1I=q%KO|ft4p&8sqsCw|!w>NU zEg-zuy;Au_Q#>tmQr1H<#S=g3Jkl4Qta6rC4%p^TF6!LgSXXS*i-tA^i+V)EZ=CtE zdeyf7w#jTvjwZ~D=ETkaFK!a5xiZGvG1kW}rl)IF;p#JDswAt945w0Re5ajqQ59Xr z{n@46U&q?VLe$!-qN^f_QGu^ncXZ#Cg&t9-q%7kPceE-_Jp)hK{Kq8P$z1dSqd;)l zoCFVU$Eq7Tv0RWI%Rl0-(kS3g8()cS_nTq4dtyT9HA#WjpH*f&bv7@|aiv>1s(cz% znGEU4sY!8JUe`YN61A+$+eKe3n6iru@FafhHgM&IMip`OO#aO+)W@^#Da@9r3uM=0 z?0zQ>fsvW(#rn=y<$+{R3>K#A+8YJf%tzFy9`EsA5hIJ`*tP6Pn?;at87_MdvVHe) z&B@Q3!=Okju(1T!Ty1f0ni34^kJ#B$A^PR!4*x(ri~$SpxcgZs0|>LkWv{|}z@ zZs{3v-(X?g7*-V5Q<`7Br#s8&J28J~Hy~u09pA35J=1wU1bA}weaT~bacACeA9SJy z$2*2a$-w+<$W5Q5VShRKxkRq< z>lpzgjMmToBUb<4!{{%T0?PEnYnHgt1(FWrRBUCCV#_VREanRV4eo?tj%Z acV8gw`Q#-xQfNB;*e^Y4uS literal 118701 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%0AbQPN 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 Date: Thu, 29 Oct 2020 13:55:50 -0700 Subject: [PATCH 51/80] [Metrics UI] Add endpoint for Metrics API (#81693) * [Metrics UI] Add endpoint for Metrics API * Adding the ability to caculate the interval based on a module * fixing types Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../infra/common/http_api/metrics_api.ts | 1 + x-pack/plugins/infra/server/infra_server.ts | 2 + .../plugins/infra/server/lib/metrics/index.ts | 14 +++++- .../lib/metrics/lib/calculate_interval.ts | 34 +++++++++++++ .../infra/server/routes/metrics_api/index.ts | 50 +++++++++++++++++++ 5 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugins/infra/server/lib/metrics/lib/calculate_interval.ts create mode 100644 x-pack/plugins/infra/server/routes/metrics_api/index.ts diff --git a/x-pack/plugins/infra/common/http_api/metrics_api.ts b/x-pack/plugins/infra/common/http_api/metrics_api.ts index 41657fdce2153..14b7c24e57694 100644 --- a/x-pack/plugins/infra/common/http_api/metrics_api.ts +++ b/x-pack/plugins/infra/common/http_api/metrics_api.ts @@ -30,6 +30,7 @@ export const MetricsAPIRequestRT = rt.intersection([ }), rt.partial({ groupBy: rt.array(groupByRT), + modules: rt.array(rt.string), afterKey: rt.union([rt.null, afterKeyObjectRT]), limit: rt.union([rt.number, rt.null, rt.undefined]), filters: rt.array(rt.object), diff --git a/x-pack/plugins/infra/server/infra_server.ts b/x-pack/plugins/infra/server/infra_server.ts index 1d89b7be43296..49fe55e3dee01 100644 --- a/x-pack/plugins/infra/server/infra_server.ts +++ b/x-pack/plugins/infra/server/infra_server.ts @@ -25,6 +25,7 @@ import { import { initGetK8sAnomaliesRoute } from './routes/infra_ml'; import { initGetHostsAnomaliesRoute } from './routes/infra_ml'; import { initMetricExplorerRoute } from './routes/metrics_explorer'; +import { initMetricsAPIRoute } from './routes/metrics_api'; import { initMetadataRoute } from './routes/metadata'; import { initSnapshotRoute } from './routes/snapshot'; import { initNodeDetailsRoute } from './routes/node_details'; @@ -74,6 +75,7 @@ export const initInfraServer = (libs: InfraBackendLibs) => { initLogEntriesSummaryHighlightsRoute(libs); initLogEntriesItemRoute(libs); initMetricExplorerRoute(libs); + initMetricsAPIRoute(libs); initMetadataRoute(libs); initInventoryMetaRoute(libs); initLogSourceConfigurationRoutes(libs); diff --git a/x-pack/plugins/infra/server/lib/metrics/index.ts b/x-pack/plugins/infra/server/lib/metrics/index.ts index 183254a0486a2..9401d34ca62fc 100644 --- a/x-pack/plugins/infra/server/lib/metrics/index.ts +++ b/x-pack/plugins/infra/server/lib/metrics/index.ts @@ -17,11 +17,20 @@ import { EMPTY_RESPONSE } from './constants'; import { createAggregations } from './lib/create_aggregations'; import { convertHistogramBucketsToTimeseries } from './lib/convert_histogram_buckets_to_timeseries'; import { calculateBucketSize } from './lib/calculate_bucket_size'; +import { calculatedInterval } from './lib/calculate_interval'; export const query = async ( search: ESSearchClient, - options: MetricsAPIRequest + rawOptions: MetricsAPIRequest ): Promise => { + const interval = await calculatedInterval(search, rawOptions); + const options = { + ...rawOptions, + timerange: { + ...rawOptions.timerange, + interval, + }, + }; const hasGroupBy = Array.isArray(options.groupBy) && options.groupBy.length > 0; const filter: Array> = [ { @@ -35,6 +44,7 @@ export const query = async ( }, ...(options.groupBy?.map((field) => ({ exists: { field } })) ?? []), ]; + const params = { allowNoIndices: true, ignoreUnavailable: true, @@ -70,7 +80,7 @@ export const query = async ( throw new Error('Aggregations should be present.'); } - const { bucketSize } = calculateBucketSize(options.timerange); + const { bucketSize } = calculateBucketSize({ ...options.timerange, interval }); if (hasGroupBy && GroupingResponseRT.is(response.aggregations)) { const { groupings } = response.aggregations; diff --git a/x-pack/plugins/infra/server/lib/metrics/lib/calculate_interval.ts b/x-pack/plugins/infra/server/lib/metrics/lib/calculate_interval.ts new file mode 100644 index 0000000000000..46682e2213a3c --- /dev/null +++ b/x-pack/plugins/infra/server/lib/metrics/lib/calculate_interval.ts @@ -0,0 +1,34 @@ +/* + * 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 { isArray, isNumber } from 'lodash'; +import { MetricsAPIRequest } from '../../../../common/http_api'; +import { ESSearchClient } from '../types'; +import { calculateMetricInterval } from '../../../utils/calculate_metric_interval'; + +export const calculatedInterval = async (search: ESSearchClient, options: MetricsAPIRequest) => { + const useModuleInterval = + options.timerange.interval === 'modules' && + isArray(options.modules) && + options.modules.length > 0; + + const calcualatedInterval = useModuleInterval + ? await calculateMetricInterval( + search, + { + indexPattern: options.indexPattern, + timestampField: options.timerange.field, + timerange: { from: options.timerange.from, to: options.timerange.to }, + }, + options.modules + ) + : false; + + const defaultInterval = + options.timerange.interval === 'modules' ? 'auto' : options.timerange.interval; + + return isNumber(calcualatedInterval) ? `>=${calcualatedInterval}s` : defaultInterval; +}; diff --git a/x-pack/plugins/infra/server/routes/metrics_api/index.ts b/x-pack/plugins/infra/server/routes/metrics_api/index.ts new file mode 100644 index 0000000000000..f3dcdeeb70cc1 --- /dev/null +++ b/x-pack/plugins/infra/server/routes/metrics_api/index.ts @@ -0,0 +1,50 @@ +/* + * 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 Boom from 'boom'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { fold } from 'fp-ts/lib/Either'; +import { identity } from 'fp-ts/lib/function'; +import { schema } from '@kbn/config-schema'; +import { InfraBackendLibs } from '../../lib/infra_types'; +import { throwErrors } from '../../../common/runtime_types'; +import { createSearchClient } from '../../lib/create_search_client'; +import { query } from '../../lib/metrics'; +import { MetricsAPIRequestRT, MetricsAPIResponseRT } from '../../../common/http_api'; + +const escapeHatch = schema.object({}, { unknowns: 'allow' }); + +export const initMetricsAPIRoute = (libs: InfraBackendLibs) => { + const { framework } = libs; + framework.registerRoute( + { + method: 'post', + path: '/api/infra/metrics_api', + validate: { + body: escapeHatch, + }, + }, + async (requestContext, request, response) => { + try { + const options = pipe( + MetricsAPIRequestRT.decode(request.body), + fold(throwErrors(Boom.badRequest), identity) + ); + + const client = createSearchClient(requestContext, framework); + const metricsApiResponse = await query(client, options); + + return response.ok({ + body: MetricsAPIResponseRT.encode(metricsApiResponse), + }); + } catch (error) { + return response.internalError({ + body: error.message, + }); + } + } + ); +}; From dc56b562013bea5b103dbd0e20ebeeebedcc1595 Mon Sep 17 00:00:00 2001 From: Luke Elmers Date: Thu, 29 Oct 2020 17:01:33 -0600 Subject: [PATCH 52/80] [docs] Add missing App Arch READMEs. (#82080) --- docs/developer/plugin-list.asciidoc | 4 ++-- examples/bfetch_explorer/README.md | 11 +++++++++ examples/embeddable_examples/README.md | 4 ++++ examples/embeddable_explorer/README.md | 10 ++++++++ examples/state_containers_examples/README.md | 8 +++++++ x-pack/plugins/data_enhanced/README.md | 25 ++++++++++++++++++++ 6 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 examples/bfetch_explorer/README.md create mode 100644 examples/embeddable_examples/README.md create mode 100644 examples/embeddable_explorer/README.md create mode 100644 examples/state_containers_examples/README.md create mode 100644 x-pack/plugins/data_enhanced/README.md diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index dee6e4777884c..4387e168f412d 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -323,8 +323,8 @@ Failure to have auth enabled in Kibana will make for a broken UI. UI-based error |The deprecated dashboard only mode. -|{kib-repo}blob/{branch}/x-pack/plugins/data_enhanced[dataEnhanced] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/x-pack/plugins/data_enhanced/README.md[dataEnhanced] +|The data_enhanced plugin is the x-pack counterpart to the OSS data plugin. |{kib-repo}blob/{branch}/x-pack/plugins/discover_enhanced/README.md[discoverEnhanced] diff --git a/examples/bfetch_explorer/README.md b/examples/bfetch_explorer/README.md new file mode 100644 index 0000000000000..33723e7cabe07 --- /dev/null +++ b/examples/bfetch_explorer/README.md @@ -0,0 +1,11 @@ +## bfetch explorer + +bfetch is a service that allows you to batch HTTP requests and stream responses +back. + +This example app demonstrates: + - How you can create a streaming response route and consume it from the + client + - How you can create a batch processing route and consume it from the client + +To run this example, use the command `yarn start --run-examples`. diff --git a/examples/embeddable_examples/README.md b/examples/embeddable_examples/README.md new file mode 100644 index 0000000000000..d05c315d31817 --- /dev/null +++ b/examples/embeddable_examples/README.md @@ -0,0 +1,4 @@ +## Embeddable examples + +This example plugin exists to support the `embeddable_explorer` app. + diff --git a/examples/embeddable_explorer/README.md b/examples/embeddable_explorer/README.md new file mode 100644 index 0000000000000..0425790f07487 --- /dev/null +++ b/examples/embeddable_explorer/README.md @@ -0,0 +1,10 @@ +## Embeddable explorer + +This example app shows how to: + - Create a basic "hello world" embeddable + - Create embeddables that accept inputs and use an EmbeddableRenderer + - Nest embeddables inside a container + - Dynamically add children to embeddable containers + - Work with the EmbeddablePanel component + +To run this example, use the command `yarn start --run-examples`. diff --git a/examples/state_containers_examples/README.md b/examples/state_containers_examples/README.md new file mode 100644 index 0000000000000..c4c6642789bd9 --- /dev/null +++ b/examples/state_containers_examples/README.md @@ -0,0 +1,8 @@ +## State containers examples + +This example app shows how to: + - Use state containers to manage your application state + - Integrate with browser history and hash history routing + - Sync your state container with the URL + +To run this example, use the command `yarn start --run-examples`. diff --git a/x-pack/plugins/data_enhanced/README.md b/x-pack/plugins/data_enhanced/README.md new file mode 100644 index 0000000000000..8f3ae7ac3cd13 --- /dev/null +++ b/x-pack/plugins/data_enhanced/README.md @@ -0,0 +1,25 @@ +# data_enhanced + +The `data_enhanced` plugin is the x-pack counterpart to the OSS `data` plugin. + +It exists to provide Elastic-licensed services, or parts of services, which +enhance existing OSS functionality from `data`. + +Currently the `data_enhanced` plugin doesn't return any APIs which you can +consume directly, however it is possible that you are indirectly relying on the +enhanced functionality that it provides via the OSS `data` plugin. + +Here is the functionality it adds: + +## KQL Autocomplete + +The OSS autocomplete service provides suggestions for field names and values +based on suggestion providers which are registered to the service. This plugin +registers the autocomplete provider for KQL to the OSS service. + +## Async, Rollup, and EQL Search Strategies + +This plugin enhances the OSS search service with an ES search strategy that +uses async search (or rollups) behind the scenes. It also registers an EQL +search strategy. + From f095ec366343b5efe10f9621fd9f47483f539b63 Mon Sep 17 00:00:00 2001 From: Oliver Gupte Date: Thu, 29 Oct 2020 16:16:32 -0700 Subject: [PATCH 53/80] Closes #80629, with proper timeout messaging and docs for user to work around the scalability issue. (#82083) --- docs/settings/apm-settings.asciidoc | 6 +++ x-pack/plugins/apm/common/service_map.ts | 2 + .../components/app/ServiceMap/index.tsx | 18 ++++++- .../app/ServiceMap/timeout_prompt.tsx | 53 +++++++++++++++++++ .../plugins/apm/public/hooks/useFetcher.tsx | 2 +- .../lib/service_map/get_trace_sample_ids.ts | 46 +++++++++------- 6 files changed, 105 insertions(+), 22 deletions(-) create mode 100644 x-pack/plugins/apm/public/components/app/ServiceMap/timeout_prompt.tsx diff --git a/docs/settings/apm-settings.asciidoc b/docs/settings/apm-settings.asciidoc index 9054a97c90496..aa680720fc8ff 100644 --- a/docs/settings/apm-settings.asciidoc +++ b/docs/settings/apm-settings.asciidoc @@ -43,6 +43,12 @@ Changing these settings may disable features of the APM App. | `xpack.apm.enabled` | Set to `false` to disable the APM app. Defaults to `true`. +| `xpack.apm.serviceMapFingerprintBucketSize` + | Maximum number of unique transaction combinations sampled for generating service map focused on a specific service. Defaults to `100`. + +| `xpack.apm.serviceMapFingerprintGlobalBucketSize` + | Maximum number of unique transaction combinations sampled for generating the global service map. Defaults to `100`. + | `xpack.apm.ui.enabled` {ess-icon} | Set to `false` to hide the APM app from the main menu. Defaults to `true`. diff --git a/x-pack/plugins/apm/common/service_map.ts b/x-pack/plugins/apm/common/service_map.ts index 02456f9b2050f..6edf56fb9a1ae 100644 --- a/x-pack/plugins/apm/common/service_map.ts +++ b/x-pack/plugins/apm/common/service_map.ts @@ -91,3 +91,5 @@ export function isSpanGroupingSupported(type?: string, subtype?: string) { nongroupedSubType === 'all' || nongroupedSubType === subtype ); } + +export const SERVICE_MAP_TIMEOUT_ERROR = 'ServiceMapTimeoutError'; diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/index.tsx b/x-pack/plugins/apm/public/components/app/ServiceMap/index.tsx index d167b6a9a0565..752f9b7fda243 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/index.tsx @@ -10,6 +10,7 @@ import { useTrackPageview } from '../../../../../observability/public'; import { invalidLicenseMessage, isActivePlatinumLicense, + SERVICE_MAP_TIMEOUT_ERROR, } from '../../../../common/service_map'; import { FETCH_STATUS, useFetcher } from '../../../hooks/useFetcher'; import { useLicense } from '../../../hooks/useLicense'; @@ -22,6 +23,7 @@ import { Cytoscape } from './Cytoscape'; import { getCytoscapeDivStyle } from './cytoscape_options'; import { EmptyBanner } from './EmptyBanner'; import { EmptyPrompt } from './empty_prompt'; +import { TimeoutPrompt } from './timeout_prompt'; import { Popover } from './Popover'; import { useRefDimensions } from './useRefDimensions'; @@ -61,7 +63,7 @@ export function ServiceMap({ serviceName }: ServiceMapProps) { const license = useLicense(); const { urlParams } = useUrlParams(); - const { data = { elements: [] }, status } = useFetcher(() => { + const { data = { elements: [] }, status, error } = useFetcher(() => { // When we don't have a license or a valid license, don't make the request. if (!license || !isActivePlatinumLicense(license)) { return; @@ -109,6 +111,20 @@ export function ServiceMap({ serviceName }: ServiceMapProps) { ); } + if ( + status === FETCH_STATUS.FAILURE && + error && + 'body' in error && + error.body.statusCode === 500 && + error.body.message === SERVICE_MAP_TIMEOUT_ERROR + ) { + return ( + + + + ); + } + return (
+ {i18n.translate('xpack.apm.serviceMap.timeoutPromptTitle', { + defaultMessage: 'Service map timeout', + })} + + } + body={ +

+ {i18n.translate('xpack.apm.serviceMap.timeoutPromptDescription', { + defaultMessage: `Timed out while fetching data for service map. Limit the scope by selecting a smaller time range, or use configuration setting '{configName}' with a reduced value.`, + values: { + configName: isGlobalServiceMap + ? 'xpack.apm.serviceMapFingerprintGlobalBucketSize' + : 'xpack.apm.serviceMapFingerprintBucketSize', + }, + })} +

+ } + actions={} + /> + ); +} + +function ApmSettingsDocLink() { + return ( + + {i18n.translate('xpack.apm.serviceMap.timeoutPrompt.docsLink', { + defaultMessage: 'Learn more about APM settings in the docs', + })} + + ); +} diff --git a/x-pack/plugins/apm/public/hooks/useFetcher.tsx b/x-pack/plugins/apm/public/hooks/useFetcher.tsx index 5d65424844c5a..6add0e8a2b480 100644 --- a/x-pack/plugins/apm/public/hooks/useFetcher.tsx +++ b/x-pack/plugins/apm/public/hooks/useFetcher.tsx @@ -21,7 +21,7 @@ export enum FETCH_STATUS { export interface FetcherResult { data?: Data; status: FETCH_STATUS; - error?: Error; + error?: IHttpFetchError; } // fetcher functions can return undefined OR a promise. Previously we had a more simple type 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 dfc4e02c25a7f..524b9bfdc7891 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 @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { uniq, take, sortBy } from 'lodash'; +import Boom from 'boom'; import { ProcessorEvent } from '../../../common/processor_event'; import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { rangeFilter } from '../../../common/utils/range_filter'; @@ -15,6 +16,7 @@ import { SPAN_DESTINATION_SERVICE_RESOURCE, } from '../../../common/elasticsearch_fieldnames'; import { getEnvironmentUiFilterES } from '../helpers/convert_ui_filters/get_environment_ui_filter_es'; +import { SERVICE_MAP_TIMEOUT_ERROR } from '../../../common/service_map'; const MAX_TRACES_TO_INSPECT = 1000; @@ -122,26 +124,30 @@ export async function getTraceSampleIds({ }, }; - const tracesSampleResponse = await apmEventClient.search(params); + try { + const tracesSampleResponse = await apmEventClient.search(params); + // make sure at least one trace per composite/connection bucket + // is queried + const traceIdsWithPriority = + tracesSampleResponse.aggregations?.connections.buckets.flatMap((bucket) => + bucket.sample.trace_ids.buckets.map((sampleDocBucket, index) => ({ + traceId: sampleDocBucket.key as string, + priority: index, + })) + ) || []; - // make sure at least one trace per composite/connection bucket - // is queried - const traceIdsWithPriority = - tracesSampleResponse.aggregations?.connections.buckets.flatMap((bucket) => - bucket.sample.trace_ids.buckets.map((sampleDocBucket, index) => ({ - traceId: sampleDocBucket.key as string, - priority: index, - })) - ) || []; + const traceIds = take( + uniq( + sortBy(traceIdsWithPriority, 'priority').map(({ traceId }) => traceId) + ), + MAX_TRACES_TO_INSPECT + ); - const traceIds = take( - uniq( - sortBy(traceIdsWithPriority, 'priority').map(({ traceId }) => traceId) - ), - MAX_TRACES_TO_INSPECT - ); - - return { - traceIds, - }; + return { traceIds }; + } catch (error) { + if ('displayName' in error && error.displayName === 'RequestTimeout') { + throw Boom.internal(SERVICE_MAP_TIMEOUT_ERROR); + } + throw error; + } } From 4f717708b415a86aca8c56d06a8f43ea998ec834 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Fri, 30 Oct 2020 05:34:20 +0300 Subject: [PATCH 54/80] [Telemetry] [Schema] remove number type and support all es number types (#81774) --- packages/kbn-telemetry-tools/GUIDELINE.md | 9 +-------- .../src/tools/__fixture__/mock_schema.json | 12 ++++++------ ...dexed_interface_with_not_matching_schema.ts | 2 +- ...ed_schema_defined_with_spreads_collector.ts | 2 +- .../__fixture__/parsed_working_collector.ts | 12 ++++++------ .../extract_collectors.test.ts.snap | 14 +++++++------- .../tools/check_collector__integrity.test.ts | 6 +++--- .../src/tools/manage_schema.ts | 18 ++++++++---------- .../schema_defined_with_spreads_collector.ts | 2 +- .../telemetry_collectors/working_collector.ts | 12 ++++++------ .../data/server/search/collectors/register.ts | 6 +++--- src/plugins/telemetry/schema/oss_plugins.json | 6 +++--- src/plugins/usage_collection/README.md | 6 +++--- .../server/collector/collector.ts | 11 +++-------- .../usage_collection/server/collector/index.ts | 1 + .../security_usage_collector.ts | 2 +- .../schema/xpack_plugins.json | 2 +- 17 files changed, 55 insertions(+), 68 deletions(-) diff --git a/packages/kbn-telemetry-tools/GUIDELINE.md b/packages/kbn-telemetry-tools/GUIDELINE.md index e7d09babbf9e2..a22196bb5dc74 100644 --- a/packages/kbn-telemetry-tools/GUIDELINE.md +++ b/packages/kbn-telemetry-tools/GUIDELINE.md @@ -148,14 +148,7 @@ usageCollection.makeUsageCollector({ Any field property in the schema accepts a `type` field. By default the type is `object` which accepts nested properties under it. Currently we accept the following property types: ``` -AllowedSchemaTypes = - | 'keyword' - | 'text' - | 'number' - | 'boolean' - | 'long' - | 'date' - | 'float'; +'long', 'integer', 'short', 'byte', 'double', 'float', 'keyword', 'text', 'boolean', 'date' ``` diff --git a/packages/kbn-telemetry-tools/src/tools/__fixture__/mock_schema.json b/packages/kbn-telemetry-tools/src/tools/__fixture__/mock_schema.json index 51e5df9bf7dc0..a385cd6798365 100644 --- a/packages/kbn-telemetry-tools/src/tools/__fixture__/mock_schema.json +++ b/packages/kbn-telemetry-tools/src/tools/__fixture__/mock_schema.json @@ -8,16 +8,16 @@ "my_index_signature_prop": { "properties": { "avg": { - "type": "number" + "type": "float" }, "count": { - "type": "number" + "type": "long" }, "max": { - "type": "number" + "type": "long" }, "min": { - "type": "number" + "type": "long" } } }, @@ -27,7 +27,7 @@ "my_objects": { "properties": { "total": { - "type": "number" + "type": "long" }, "type": { "type": "boolean" @@ -39,7 +39,7 @@ "items": { "properties": { "total": { - "type": "number" + "type": "long" }, "type": { "type": "boolean" diff --git a/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_indexed_interface_with_not_matching_schema.ts b/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_indexed_interface_with_not_matching_schema.ts index 83866a2b6afec..109fc045b6ee0 100644 --- a/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_indexed_interface_with_not_matching_schema.ts +++ b/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_indexed_interface_with_not_matching_schema.ts @@ -28,7 +28,7 @@ export const parsedIndexedInterfaceWithNoMatchingSchema: ParsedUsageCollection = value: { something: { count_1: { - type: 'number', + type: 'long', }, }, }, diff --git a/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_schema_defined_with_spreads_collector.ts b/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_schema_defined_with_spreads_collector.ts index 833344fa368b0..4a1a622e23f36 100644 --- a/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_schema_defined_with_spreads_collector.ts +++ b/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_schema_defined_with_spreads_collector.ts @@ -34,7 +34,7 @@ export const parsedSchemaDefinedWithSpreadsCollector: ParsedUsageCollection = [ }, my_objects: { total: { - type: 'number', + type: 'long', }, type: { type: 'boolean', diff --git a/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_working_collector.ts b/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_working_collector.ts index acf984b7d10ee..ef6227cf35c37 100644 --- a/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_working_collector.ts +++ b/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_working_collector.ts @@ -34,21 +34,21 @@ export const parsedWorkingCollector: ParsedUsageCollection = [ }, my_index_signature_prop: { avg: { - type: 'number', + type: 'float', }, count: { - type: 'number', + type: 'long', }, max: { - type: 'number', + type: 'long', }, min: { - type: 'number', + type: 'long', }, }, my_objects: { total: { - type: 'number', + type: 'long', }, type: { type: 'boolean', @@ -58,7 +58,7 @@ export const parsedWorkingCollector: ParsedUsageCollection = [ type: 'array', items: { total: { - type: 'number', + type: 'long', }, type: { type: 'boolean' }, }, diff --git a/packages/kbn-telemetry-tools/src/tools/__snapshots__/extract_collectors.test.ts.snap b/packages/kbn-telemetry-tools/src/tools/__snapshots__/extract_collectors.test.ts.snap index 4725be77533af..fe589be7993d0 100644 --- a/packages/kbn-telemetry-tools/src/tools/__snapshots__/extract_collectors.test.ts.snap +++ b/packages/kbn-telemetry-tools/src/tools/__snapshots__/extract_collectors.test.ts.snap @@ -176,7 +176,7 @@ Array [ }, "my_objects": Object { "total": Object { - "type": "number", + "type": "long", }, "type": Object { "type": "boolean", @@ -248,7 +248,7 @@ Array [ "my_array": Object { "items": Object { "total": Object { - "type": "number", + "type": "long", }, "type": Object { "type": "boolean", @@ -258,21 +258,21 @@ Array [ }, "my_index_signature_prop": Object { "avg": Object { - "type": "number", + "type": "float", }, "count": Object { - "type": "number", + "type": "long", }, "max": Object { - "type": "number", + "type": "long", }, "min": Object { - "type": "number", + "type": "long", }, }, "my_objects": Object { "total": Object { - "type": "number", + "type": "long", }, "type": Object { "type": "boolean", diff --git a/packages/kbn-telemetry-tools/src/tools/check_collector__integrity.test.ts b/packages/kbn-telemetry-tools/src/tools/check_collector__integrity.test.ts index a101210185a63..b6ea9d49cf6d0 100644 --- a/packages/kbn-telemetry-tools/src/tools/check_collector__integrity.test.ts +++ b/packages/kbn-telemetry-tools/src/tools/check_collector__integrity.test.ts @@ -44,7 +44,7 @@ describe('checkMatchingMapping', () => { it('returns diff on mismatching parsedCollections and stored mapping', async () => { const mockSchema = await parseJsonFile('mock_schema.json'); const malformedParsedCollector = cloneDeep(parsedWorkingCollector); - const fieldMapping = { type: 'number' }; + const fieldMapping = { type: 'long' }; malformedParsedCollector[1].schema.value.flat = fieldMapping; const diffs = checkMatchingMapping([malformedParsedCollector], mockSchema); @@ -61,9 +61,9 @@ describe('checkMatchingMapping', () => { const mockSchema = await parseJsonFile('mock_schema.json'); const malformedParsedCollector = cloneDeep(parsedWorkingCollector); const collectorName = 'New Collector in town!'; - const collectorMapping = { some_usage: { type: 'number' } }; + const collectorMapping = { some_usage: { type: 'long' } }; malformedParsedCollector[1].collectorName = collectorName; - malformedParsedCollector[1].schema.value = { some_usage: { type: 'number' } }; + malformedParsedCollector[1].schema.value = { some_usage: { type: 'long' } }; const diffs = checkMatchingMapping([malformedParsedCollector], mockSchema); expect(diffs).toEqual({ diff --git a/packages/kbn-telemetry-tools/src/tools/manage_schema.ts b/packages/kbn-telemetry-tools/src/tools/manage_schema.ts index 7721492fdb691..e2bfca34a6487 100644 --- a/packages/kbn-telemetry-tools/src/tools/manage_schema.ts +++ b/packages/kbn-telemetry-tools/src/tools/manage_schema.ts @@ -19,14 +19,9 @@ import { ParsedUsageCollection } from './ts_parser'; -export type AllowedSchemaTypes = - | 'keyword' - | 'text' - | 'number' - | 'boolean' - | 'long' - | 'date' - | 'float'; +export type AllowedSchemaNumberTypes = 'long' | 'integer' | 'short' | 'byte' | 'double' | 'float'; + +export type AllowedSchemaTypes = AllowedSchemaNumberTypes | 'keyword' | 'text' | 'boolean' | 'date'; export function compatibleSchemaTypes(type: AllowedSchemaTypes | 'array') { switch (type) { @@ -36,9 +31,12 @@ export function compatibleSchemaTypes(type: AllowedSchemaTypes | 'array') { return 'string'; case 'boolean': return 'boolean'; - case 'number': - case 'float': case 'long': + case 'integer': + case 'short': + case 'byte': + case 'double': + case 'float': return 'number'; case 'array': return 'array'; diff --git a/src/fixtures/telemetry_collectors/schema_defined_with_spreads_collector.ts b/src/fixtures/telemetry_collectors/schema_defined_with_spreads_collector.ts index af9fef0bbd297..791c366199d74 100644 --- a/src/fixtures/telemetry_collectors/schema_defined_with_spreads_collector.ts +++ b/src/fixtures/telemetry_collectors/schema_defined_with_spreads_collector.ts @@ -49,7 +49,7 @@ const someSchema: MakeSchemaFrom> = { const someOtherSchema: MakeSchemaFrom> = { my_objects: { total: { - type: 'number', + type: 'long', }, type: { type: 'boolean' }, }, diff --git a/src/fixtures/telemetry_collectors/working_collector.ts b/src/fixtures/telemetry_collectors/working_collector.ts index 0a3bf49638a7b..f9cb3bb568673 100644 --- a/src/fixtures/telemetry_collectors/working_collector.ts +++ b/src/fixtures/telemetry_collectors/working_collector.ts @@ -85,7 +85,7 @@ export const myCollector = makeUsageCollector({ }, my_objects: { total: { - type: 'number', + type: 'long', }, type: { type: 'boolean' }, }, @@ -93,17 +93,17 @@ export const myCollector = makeUsageCollector({ type: 'array', items: { total: { - type: 'number', + type: 'long', }, type: { type: 'boolean' }, }, }, my_str_array: { type: 'array', items: { type: 'keyword' } }, my_index_signature_prop: { - count: { type: 'number' }, - avg: { type: 'number' }, - max: { type: 'number' }, - min: { type: 'number' }, + count: { type: 'long' }, + avg: { type: 'float' }, + max: { type: 'long' }, + min: { type: 'long' }, }, }, }); diff --git a/src/plugins/data/server/search/collectors/register.ts b/src/plugins/data/server/search/collectors/register.ts index ab0ea93edd49e..5db4f52169350 100644 --- a/src/plugins/data/server/search/collectors/register.ts +++ b/src/plugins/data/server/search/collectors/register.ts @@ -37,9 +37,9 @@ export async function registerUsageCollector( isReady: () => true, fetch: fetchProvider(context.config.legacy.globalConfig$), schema: { - successCount: { type: 'number' }, - errorCount: { type: 'number' }, - averageDuration: { type: 'long' }, + successCount: { type: 'long' }, + errorCount: { type: 'long' }, + averageDuration: { type: 'float' }, }, }); usageCollection.registerCollector(collector); diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 160e99a40790c..c840cbe8fc94d 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -16,13 +16,13 @@ "search": { "properties": { "successCount": { - "type": "number" + "type": "long" }, "errorCount": { - "type": "number" + "type": "long" }, "averageDuration": { - "type": "long" + "type": "float" } } }, diff --git a/src/plugins/usage_collection/README.md b/src/plugins/usage_collection/README.md index 430241cbe0a05..5a853972d34a8 100644 --- a/src/plugins/usage_collection/README.md +++ b/src/plugins/usage_collection/README.md @@ -138,7 +138,7 @@ The `schema` field is a proscribed data model assists with detecting changes in The `AllowedSchemaTypes` is the list of allowed schema types for the usage fields getting reported: ``` -'keyword', 'text', 'number', 'boolean', 'long', 'date', 'float' +'long', 'integer', 'short', 'byte', 'double', 'float', 'keyword', 'text', 'boolean', 'date' ``` ### Arrays @@ -171,7 +171,7 @@ export const myCollector = makeUsageCollector({ }, some_obj: { total: { - type: 'number', + type: 'long', }, }, some_array: { @@ -182,7 +182,7 @@ export const myCollector = makeUsageCollector({ type: 'array', items: { total: { - type: 'number', + type: 'long', }, }, }, diff --git a/src/plugins/usage_collection/server/collector/collector.ts b/src/plugins/usage_collection/server/collector/collector.ts index 951418d448cbd..73febc0183fc5 100644 --- a/src/plugins/usage_collection/server/collector/collector.ts +++ b/src/plugins/usage_collection/server/collector/collector.ts @@ -27,14 +27,9 @@ import { export type CollectorFormatForBulkUpload = (result: T) => { type: string; payload: U }; -export type AllowedSchemaTypes = - | 'keyword' - | 'text' - | 'number' - | 'boolean' - | 'long' - | 'date' - | 'float'; +export type AllowedSchemaNumberTypes = 'long' | 'integer' | 'short' | 'byte' | 'double' | 'float'; + +export type AllowedSchemaTypes = AllowedSchemaNumberTypes | 'keyword' | 'text' | 'boolean' | 'date'; export interface SchemaField { type: string; diff --git a/src/plugins/usage_collection/server/collector/index.ts b/src/plugins/usage_collection/server/collector/index.ts index da85f9ab181c9..2f8be884a8a7b 100644 --- a/src/plugins/usage_collection/server/collector/index.ts +++ b/src/plugins/usage_collection/server/collector/index.ts @@ -21,6 +21,7 @@ export { CollectorSet } from './collector_set'; export { Collector, AllowedSchemaTypes, + AllowedSchemaNumberTypes, SchemaField, MakeSchemaFrom, CollectorOptions, diff --git a/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts b/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts index 90483d7c0a4d5..cf3c787e6b0db 100644 --- a/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts +++ b/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts @@ -59,7 +59,7 @@ export function registerSecurityUsageCollector({ usageCollection, config, licens type: 'boolean', }, authProviderCount: { - type: 'number', + type: 'long', }, enabledAuthProviders: { type: 'array', diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json index 2b3ff6c8a0aef..c965623ebfc17 100644 --- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json +++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @@ -3250,7 +3250,7 @@ "type": "boolean" }, "authProviderCount": { - "type": "number" + "type": "long" }, "enabledAuthProviders": { "type": "array", From 076bb734c76d8f34b9986b49f1ccaeea8e69de89 Mon Sep 17 00:00:00 2001 From: Peter Pisljar Date: Fri, 30 Oct 2020 06:01:45 +0100 Subject: [PATCH 55/80] Expressions/migrations2 (#81281) --- ...gin-plugins-expressions-public.executor.md | 2 + ...ins-expressions-public.executor.migrate.md | 23 ++++++++++++ ...essions-public.executor.migratetolatest.md | 23 ++++++++++++ ...s-expressions-public.expressionfunction.md | 1 + ...ns-public.expressionfunction.migrations.md | 13 +++++++ ...s-expressions-public.expressionsservice.md | 2 + ...sions-public.expressionsservice.migrate.md | 13 +++++++ ...blic.expressionsservice.migratetolatest.md | 13 +++++++ ...gin-plugins-expressions-server.executor.md | 2 + ...ins-expressions-server.executor.migrate.md | 23 ++++++++++++ ...essions-server.executor.migratetolatest.md | 23 ++++++++++++ ...s-expressions-server.expressionfunction.md | 1 + ...ns-server.expressionfunction.migrations.md | 13 +++++++ .../common/executor/executor.test.ts | 31 ++++++++++++++++ .../expressions/common/executor/executor.ts | 37 ++++++++++++++++++- .../expression_function.ts | 7 +++- .../common/service/expressions_services.ts | 22 ++++++++++- src/plugins/expressions/public/public.api.md | 13 ++++++- src/plugins/expressions/server/server.api.md | 11 +++++- .../common/persistable_state/index.ts | 30 ++++++++++++++- 20 files changed, 296 insertions(+), 7 deletions(-) create mode 100644 docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.migrate.md create mode 100644 docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.migratetolatest.md create mode 100644 docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md create mode 100644 docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.migrate.md create mode 100644 docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.migratetolatest.md create mode 100644 docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.migrate.md create mode 100644 docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.migratetolatest.md create mode 100644 docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.md index aefd04112dc1c..3cc38a0cbdc0f 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.md @@ -39,6 +39,8 @@ export declare class Executor = Record + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [migrate](./kibana-plugin-plugins-expressions-public.executor.migrate.md) + +## Executor.migrate() method + +Signature: + +```typescript +migrate(ast: SerializableState, version: string): ExpressionAstExpression; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | SerializableState | | +| version | string | | + +Returns: + +`ExpressionAstExpression` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.migratetolatest.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.migratetolatest.md new file mode 100644 index 0000000000000..23b7e6035a0ae --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.migratetolatest.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [migrateToLatest](./kibana-plugin-plugins-expressions-public.executor.migratetolatest.md) + +## Executor.migrateToLatest() method + +Signature: + +```typescript +migrateToLatest(ast: unknown, version: string): ExpressionAstExpression; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | unknown | | +| version | string | | + +Returns: + +`ExpressionAstExpression` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.md index 1815d63d804b1..3e75e9ab3ef6f 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.md @@ -29,6 +29,7 @@ export declare class ExpressionFunction implements PersistableStatestring | A short help text. | | [inject](./kibana-plugin-plugins-expressions-public.expressionfunction.inject.md) | | (state: ExpressionAstFunction['arguments'], references: SavedObjectReference[]) => ExpressionAstFunction['arguments'] | | | [inputTypes](./kibana-plugin-plugins-expressions-public.expressionfunction.inputtypes.md) | | string[] | undefined | Type of inputs that this function supports. | +| [migrations](./kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md) | | {
[key: string]: (state: SerializableState) => SerializableState;
} | | | [name](./kibana-plugin-plugins-expressions-public.expressionfunction.name.md) | | string | Name of function | | [telemetry](./kibana-plugin-plugins-expressions-public.expressionfunction.telemetry.md) | | (state: ExpressionAstFunction['arguments'], telemetryData: Record<string, any>) => Record<string, any> | | | [type](./kibana-plugin-plugins-expressions-public.expressionfunction.type.md) | | string | Return type of function. This SHOULD be supplied. We use it for UI and autocomplete hinting. We may also use it for optimizations in the future. | diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md new file mode 100644 index 0000000000000..28d521f4b3fe1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) > [migrations](./kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md) + +## ExpressionFunction.migrations property + +Signature: + +```typescript +migrations: { + [key: string]: (state: SerializableState) => SerializableState; + }; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.md index 041d66b22dd50..307fc73ec6e9c 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.md @@ -39,6 +39,8 @@ export declare class ExpressionsService implements PersistableStateExpressionsServiceStart['getType'] | | | [getTypes](./kibana-plugin-plugins-expressions-public.expressionsservice.gettypes.md) | | () => ReturnType<Executor['getTypes']> | Returns POJO map of all registered expression types, where keys are names of the types and values are ExpressionType instances. | | [inject](./kibana-plugin-plugins-expressions-public.expressionsservice.inject.md) | | (state: ExpressionAstExpression, references: SavedObjectReference[]) => ExpressionAstExpression | Injects saved object references into expression AST | +| [migrate](./kibana-plugin-plugins-expressions-public.expressionsservice.migrate.md) | | (state: SerializableState, version: string) => ExpressionAstExpression | Injects saved object references into expression AST | +| [migrateToLatest](./kibana-plugin-plugins-expressions-public.expressionsservice.migratetolatest.md) | | (state: unknown, version: string) => ExpressionAstExpression | Injects saved object references into expression AST | | [registerFunction](./kibana-plugin-plugins-expressions-public.expressionsservice.registerfunction.md) | | (functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)) => void | Register an expression function, which will be possible to execute as part of the expression pipeline.Below we register a function which simply sleeps for given number of milliseconds to delay the execution and outputs its input as-is. ```ts expressions.registerFunction({ diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.migrate.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.migrate.md new file mode 100644 index 0000000000000..88a6bda4ee3f5 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.migrate.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [migrate](./kibana-plugin-plugins-expressions-public.expressionsservice.migrate.md) + +## ExpressionsService.migrate property + +Injects saved object references into expression AST + +Signature: + +```typescript +readonly migrate: (state: SerializableState, version: string) => ExpressionAstExpression; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.migratetolatest.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.migratetolatest.md new file mode 100644 index 0000000000000..e6860df19fd3f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.migratetolatest.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [migrateToLatest](./kibana-plugin-plugins-expressions-public.expressionsservice.migratetolatest.md) + +## ExpressionsService.migrateToLatest property + +Injects saved object references into expression AST + +Signature: + +```typescript +readonly migrateToLatest: (state: unknown, version: string) => ExpressionAstExpression; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.md index 97bb3ac895084..da20ae4aa892e 100644 --- a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.md +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.md @@ -39,6 +39,8 @@ export declare class Executor = Record + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [migrate](./kibana-plugin-plugins-expressions-server.executor.migrate.md) + +## Executor.migrate() method + +Signature: + +```typescript +migrate(ast: SerializableState, version: string): ExpressionAstExpression; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | SerializableState | | +| version | string | | + +Returns: + +`ExpressionAstExpression` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.migratetolatest.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.migratetolatest.md new file mode 100644 index 0000000000000..72e3f8d8b7edc --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.migratetolatest.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [migrateToLatest](./kibana-plugin-plugins-expressions-server.executor.migratetolatest.md) + +## Executor.migrateToLatest() method + +Signature: + +```typescript +migrateToLatest(ast: unknown, version: string): ExpressionAstExpression; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | unknown | | +| version | string | | + +Returns: + +`ExpressionAstExpression` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.md index 7fcda94968d13..00c8aa63bfbd8 100644 --- a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.md +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.md @@ -29,6 +29,7 @@ export declare class ExpressionFunction implements PersistableStatestring | A short help text. | | [inject](./kibana-plugin-plugins-expressions-server.expressionfunction.inject.md) | | (state: ExpressionAstFunction['arguments'], references: SavedObjectReference[]) => ExpressionAstFunction['arguments'] | | | [inputTypes](./kibana-plugin-plugins-expressions-server.expressionfunction.inputtypes.md) | | string[] | undefined | Type of inputs that this function supports. | +| [migrations](./kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md) | | {
[key: string]: (state: SerializableState) => SerializableState;
} | | | [name](./kibana-plugin-plugins-expressions-server.expressionfunction.name.md) | | string | Name of function | | [telemetry](./kibana-plugin-plugins-expressions-server.expressionfunction.telemetry.md) | | (state: ExpressionAstFunction['arguments'], telemetryData: Record<string, any>) => Record<string, any> | | | [type](./kibana-plugin-plugins-expressions-server.expressionfunction.type.md) | | string | Return type of function. This SHOULD be supplied. We use it for UI and autocomplete hinting. We may also use it for optimizations in the future. | diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md new file mode 100644 index 0000000000000..29031a9306b2f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) > [migrations](./kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md) + +## ExpressionFunction.migrations property + +Signature: + +```typescript +migrations: { + [key: string]: (state: SerializableState) => SerializableState; + }; +``` diff --git a/src/plugins/expressions/common/executor/executor.test.ts b/src/plugins/expressions/common/executor/executor.test.ts index a658d3457407c..308d6f7e71814 100644 --- a/src/plugins/expressions/common/executor/executor.test.ts +++ b/src/plugins/expressions/common/executor/executor.test.ts @@ -22,6 +22,7 @@ import * as expressionTypes from '../expression_types'; import * as expressionFunctions from '../expression_functions'; import { Execution } from '../execution'; import { ExpressionAstFunction, parseExpression } from '../ast'; +import { MigrateFunction } from '../../../kibana_utils/common/persistable_state'; describe('Executor', () => { test('can instantiate', () => { @@ -158,6 +159,7 @@ describe('Executor', () => { const injectFn = jest.fn().mockImplementation((args, references) => args); const extractFn = jest.fn().mockReturnValue({ args: {}, references: [] }); + const migrateFn = jest.fn().mockImplementation((args) => args); const fooFn = { name: 'foo', @@ -174,6 +176,14 @@ describe('Executor', () => { inject: (state: ExpressionAstFunction['arguments']) => { return injectFn(state); }, + migrations: { + '7.10.0': (((state: ExpressionAstFunction, version: string): ExpressionAstFunction => { + return migrateFn(state, version); + }) as any) as MigrateFunction, + '7.10.1': (((state: ExpressionAstFunction, version: string): ExpressionAstFunction => { + return migrateFn(state, version); + }) as any) as MigrateFunction, + }, fn: jest.fn(), }; executor.registerFunction(fooFn); @@ -194,5 +204,26 @@ describe('Executor', () => { expect(extractFn).toBeCalledTimes(5); }); }); + + describe('.migrate', () => { + test('calls migrate function for every expression function in expression', () => { + executor.migrate( + parseExpression('foo bar="baz" | foo bar={foo bar="baz" | foo bar={foo bar="baz"}}'), + '7.10.0' + ); + expect(migrateFn).toBeCalledTimes(5); + }); + }); + + describe('.migrateToLatest', () => { + test('calls extract function for every expression function in expression', () => { + migrateFn.mockClear(); + executor.migrateToLatest( + parseExpression('foo bar="baz" | foo bar={foo bar="baz" | foo bar={foo bar="baz"}}'), + '7.10.0' + ); + expect(migrateFn).toBeCalledTimes(10); + }); + }); }); }); diff --git a/src/plugins/expressions/common/executor/executor.ts b/src/plugins/expressions/common/executor/executor.ts index 85b5589b593af..19fc4cf5a14a2 100644 --- a/src/plugins/expressions/common/executor/executor.ts +++ b/src/plugins/expressions/common/executor/executor.ts @@ -32,7 +32,7 @@ import { typeSpecs } from '../expression_types/specs'; import { functionSpecs } from '../expression_functions/specs'; import { getByAlias } from '../util'; import { SavedObjectReference } from '../../../../core/types'; -import { PersistableState } from '../../../kibana_utils/common'; +import { PersistableState, SerializableState } from '../../../kibana_utils/common'; import { ExpressionExecutionParams } from '../service'; export interface ExpressionExecOptions { @@ -88,6 +88,20 @@ export class FunctionsRegistry implements IRegistry { } } +const semverGte = (semver1: string, semver2: string) => { + const regex = /^([0-9]+)\.([0-9]+)\.([0-9]+)$/; + const matches1 = regex.exec(semver1) as RegExpMatchArray; + const matches2 = regex.exec(semver2) as RegExpMatchArray; + + const [, major1, minor1, patch1] = matches1; + const [, major2, minor2, patch2] = matches2; + + return ( + major1 > major2 || + (major1 === major2 && (minor1 > minor2 || (minor1 === minor2 && patch1 >= patch2))) + ); +}; + export class Executor = Record> implements PersistableState { static createWithDefaults = Record>( @@ -249,6 +263,27 @@ export class Executor = Record { + if (!fn.migrations[version]) return link; + const updatedAst = fn.migrations[version](link) as ExpressionAstFunction; + link.arguments = updatedAst.arguments; + link.type = updatedAst.type; + }); + } + + public migrateToLatest(ast: unknown, version: string) { + return this.walkAst(cloneDeep(ast) as ExpressionAstExpression, (fn, link) => { + for (const key of Object.keys(fn.migrations)) { + if (semverGte(key, version)) { + const updatedAst = fn.migrations[key](link) as ExpressionAstFunction; + link.arguments = updatedAst.arguments; + link.type = updatedAst.type; + } + } + }); + } + public fork(): Executor { const initialState = this.state.get(); const fork = new Executor(initialState); diff --git a/src/plugins/expressions/common/expression_functions/expression_function.ts b/src/plugins/expressions/common/expression_functions/expression_function.ts index 0b56d3c169ff4..2879cc8e3632c 100644 --- a/src/plugins/expressions/common/expression_functions/expression_function.ts +++ b/src/plugins/expressions/common/expression_functions/expression_function.ts @@ -24,7 +24,7 @@ import { ExpressionValue } from '../expression_types/types'; import { ExecutionContext } from '../execution'; import { ExpressionAstFunction } from '../ast'; import { SavedObjectReference } from '../../../../core/types'; -import { PersistableState } from '../../../kibana_utils/common'; +import { PersistableState, SerializableState } from '../../../kibana_utils/common'; export class ExpressionFunction implements PersistableState { /** @@ -76,6 +76,9 @@ export class ExpressionFunction implements PersistableState ExpressionAstFunction['arguments']; + migrations: { + [key: string]: (state: SerializableState) => SerializableState; + }; constructor(functionDefinition: AnyExpressionFunctionDefinition) { const { @@ -91,6 +94,7 @@ export class ExpressionFunction implements PersistableState c); this.inject = inject || identity; this.extract = extract || ((s) => ({ state: s, references: [] })); + this.migrations = migrations || {}; for (const [key, arg] of Object.entries(args || {})) { this.args[key] = new ExpressionFunctionParameter(key, arg); diff --git a/src/plugins/expressions/common/service/expressions_services.ts b/src/plugins/expressions/common/service/expressions_services.ts index abbba433ab3ca..0f898563c3d0e 100644 --- a/src/plugins/expressions/common/service/expressions_services.ts +++ b/src/plugins/expressions/common/service/expressions_services.ts @@ -24,7 +24,7 @@ import { ExecutionContract } from '../execution/execution_contract'; import { AnyExpressionTypeDefinition } from '../expression_types'; import { AnyExpressionFunctionDefinition } from '../expression_functions'; import { SavedObjectReference } from '../../../../core/types'; -import { PersistableState } from '../../../kibana_utils/common'; +import { PersistableState, SerializableState } from '../../../kibana_utils/common'; import { Adapters } from '../../../inspector/common/adapters'; import { ExecutionContextSearch } from '../execution'; @@ -303,6 +303,26 @@ export class ExpressionsService implements PersistableState { + return this.executor.migrate(state, version); + }; + + /** + * Migrates expression to the latest version + * @param state expression AST to update + * @param version the version of kibana in which expression was created + * @returns migrated expression AST + */ + public readonly migrateToLatest = (state: unknown, version: string) => { + return this.executor.migrateToLatest(state, version); + }; + /** * Returns Kibana Platform *setup* life-cycle contract. Useful to return the * same contract on server-side and browser-side. diff --git a/src/plugins/expressions/public/public.api.md b/src/plugins/expressions/public/public.api.md index 68a3507bbf166..5ca085ebb0d1d 100644 --- a/src/plugins/expressions/public/public.api.md +++ b/src/plugins/expressions/public/public.api.md @@ -222,6 +222,12 @@ export class Executor = Record AnyExpressionFunctionDefinition)): void; // (undocumented) @@ -342,6 +348,10 @@ export class ExpressionFunction implements PersistableState ExpressionAstFunction['arguments']; inputTypes: string[] | undefined; + // (undocumented) + migrations: { + [key: string]: (state: SerializableState) => SerializableState; + }; name: string; // (undocumented) telemetry: (state: ExpressionAstFunction['arguments'], telemetryData: Record) => Record; @@ -586,6 +596,8 @@ export class ExpressionsService implements PersistableState ReturnType; readonly inject: (state: ExpressionAstExpression, references: SavedObjectReference[]) => ExpressionAstExpression; + readonly migrate: (state: SerializableState, version: string) => ExpressionAstExpression; + readonly migrateToLatest: (state: unknown, version: string) => ExpressionAstExpression; readonly registerFunction: (functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)) => void; // (undocumented) readonly registerRenderer: (definition: AnyExpressionRenderDefinition | (() => AnyExpressionRenderDefinition)) => void; @@ -1149,7 +1161,6 @@ export type UnmappedTypeStrings = 'date' | 'filter'; // // src/plugins/expressions/common/ast/types.ts:40:3 - (ae-forgotten-export) The symbol "ExpressionAstFunctionDebug" needs to be exported by the entry point index.d.ts // src/plugins/expressions/common/expression_types/specs/error.ts:31:5 - (ae-forgotten-export) The symbol "ErrorLike" needs to be exported by the entry point index.d.ts -// src/plugins/expressions/common/expression_types/specs/error.ts:32:5 - (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/plugins/expressions/server/server.api.md b/src/plugins/expressions/server/server.api.md index d6925a027358c..c8d5464929033 100644 --- a/src/plugins/expressions/server/server.api.md +++ b/src/plugins/expressions/server/server.api.md @@ -204,6 +204,12 @@ export class Executor = Record AnyExpressionFunctionDefinition)): void; // (undocumented) @@ -314,6 +320,10 @@ export class ExpressionFunction implements PersistableState ExpressionAstFunction['arguments']; inputTypes: string[] | undefined; + // (undocumented) + migrations: { + [key: string]: (state: SerializableState) => SerializableState; + }; name: string; // (undocumented) telemetry: (state: ExpressionAstFunction['arguments'], telemetryData: Record) => Record; @@ -939,7 +949,6 @@ export type UnmappedTypeStrings = 'date' | 'filter'; // // src/plugins/expressions/common/ast/types.ts:40:3 - (ae-forgotten-export) The symbol "ExpressionAstFunctionDebug" needs to be exported by the entry point index.d.ts // src/plugins/expressions/common/expression_types/specs/error.ts:31:5 - (ae-forgotten-export) The symbol "ErrorLike" needs to be exported by the entry point index.d.ts -// src/plugins/expressions/common/expression_types/specs/error.ts:32:5 - (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/plugins/kibana_utils/common/persistable_state/index.ts b/src/plugins/kibana_utils/common/persistable_state/index.ts index ae5e3d514554c..40feea3f24f28 100644 --- a/src/plugins/kibana_utils/common/persistable_state/index.ts +++ b/src/plugins/kibana_utils/common/persistable_state/index.ts @@ -27,6 +27,11 @@ export type SerializableState = { [key: string]: Serializable; }; +export type MigrateFunction< + FromVersion extends SerializableState = SerializableState, + ToVersion extends SerializableState = SerializableState +> = (state: FromVersion) => ToVersion; + export interface PersistableState

{ /** * function to extract telemetry information @@ -47,8 +52,29 @@ export interface PersistableState

{ state: P; references: SavedObjectReference[] }; + + /** + * migrateToLatest function receives state of older version and should migrate to the latest version + * @param state + * @param version + */ + migrateToLatest?: (state: SerializableState, version: string) => P; + + /** + * migrate function runs the specified migration + * @param state + * @param version + */ + migrate?: (state: SerializableState, version: string) => SerializableState; } export type PersistableStateDefinition

= Partial< - PersistableState

->; + Omit, 'migrate'> +> & { + /** + * list of all migrations per semver + */ + migrations?: { + [key: string]: MigrateFunction; + }; +}; From 534f4e85386b0e208f460c354730bd9367f025e4 Mon Sep 17 00:00:00 2001 From: DB Date: Fri, 30 Oct 2020 16:52:30 +0900 Subject: [PATCH 56/80] [TSVB] Renamed 'positive rate' to 'counter rate' (#80939) * Renamed 'positive rate' label text to 'counter rate' * Removed translations(ja-JP, zh-CN) where the labels were updated Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- src/plugins/vis_type_timeseries/common/agg_lookup.js | 2 +- src/plugins/vis_type_timeseries/common/calculate_label.js | 2 +- .../public/application/components/aggs/agg_select.test.tsx | 4 ++-- .../public/application/components/aggs/agg_select.tsx | 2 +- x-pack/plugins/translations/translations/ja-JP.json | 3 --- x-pack/plugins/translations/translations/zh-CN.json | 3 --- 6 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/plugins/vis_type_timeseries/common/agg_lookup.js b/src/plugins/vis_type_timeseries/common/agg_lookup.js index 432da03e3d45d..0a71ab34082f8 100644 --- a/src/plugins/vis_type_timeseries/common/agg_lookup.js +++ b/src/plugins/vis_type_timeseries/common/agg_lookup.js @@ -98,7 +98,7 @@ export const lookup = { }), top_hit: i18n.translate('visTypeTimeseries.aggLookup.topHitLabel', { defaultMessage: 'Top Hit' }), positive_rate: i18n.translate('visTypeTimeseries.aggLookup.positiveRateLabel', { - defaultMessage: 'Positive Rate', + defaultMessage: 'Counter Rate', }), }; diff --git a/src/plugins/vis_type_timeseries/common/calculate_label.js b/src/plugins/vis_type_timeseries/common/calculate_label.js index 9f3030eeb6eae..96e9fa0825b25 100644 --- a/src/plugins/vis_type_timeseries/common/calculate_label.js +++ b/src/plugins/vis_type_timeseries/common/calculate_label.js @@ -72,7 +72,7 @@ export function calculateLabel(metric, metrics) { } if (metric.type === 'positive_rate') { return i18n.translate('visTypeTimeseries.calculateLabel.positiveRateLabel', { - defaultMessage: 'Positive Rate of {field}', + defaultMessage: 'Counter Rate of {field}', values: { field: metric.field }, }); } diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_select.test.tsx b/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_select.test.tsx index 968fa5384e1d8..6c75e081429de 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_select.test.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_select.test.tsx @@ -63,7 +63,7 @@ describe('TSVB AggSelect', () => { "value": "count", }, Object { - "label": "Positive Rate", + "label": "Counter Rate", "value": "positive_rate", }, Object { @@ -131,7 +131,7 @@ describe('TSVB AggSelect', () => { "value": "filter_ratio", }, Object { - "label": "Positive Rate", + "label": "Counter Rate", "value": "positive_rate", }, Object { diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_select.tsx b/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_select.tsx index 7701d351e5478..5c8049e363694 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_select.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_select.tsx @@ -54,7 +54,7 @@ const metricAggs: AggSelectOption[] = [ }, { label: i18n.translate('visTypeTimeseries.aggSelect.metricsAggs.positiveRateLabel', { - defaultMessage: 'Positive Rate', + defaultMessage: 'Counter Rate', }), value: 'positive_rate', }, diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 1492c8a03906a..cd090b0c264ef 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -3801,7 +3801,6 @@ "visTypeTimeseries.aggLookup.percentileLabel": "パーセンタイル", "visTypeTimeseries.aggLookup.percentileRankLabel": "パーセンタイルランク", "visTypeTimeseries.aggLookup.positiveOnlyLabel": "プラスのみ", - "visTypeTimeseries.aggLookup.positiveRateLabel": "正の割合", "visTypeTimeseries.aggLookup.serialDifferenceLabel": "連続差", "visTypeTimeseries.aggLookup.seriesAggLabel": "数列集約", "visTypeTimeseries.aggLookup.staticValueLabel": "不動値", @@ -3824,7 +3823,6 @@ "visTypeTimeseries.aggSelect.metricsAggs.minLabel": "最低", "visTypeTimeseries.aggSelect.metricsAggs.percentileLabel": "パーセンタイル", "visTypeTimeseries.aggSelect.metricsAggs.percentileRankLabel": "パーセンタイルランク", - "visTypeTimeseries.aggSelect.metricsAggs.positiveRateLabel": "正の割合", "visTypeTimeseries.aggSelect.metricsAggs.staticValueLabel": "不動値", "visTypeTimeseries.aggSelect.metricsAggs.stdDeviationLabel": "標準偏差", "visTypeTimeseries.aggSelect.metricsAggs.sumLabel": "合計", @@ -3868,7 +3866,6 @@ "visTypeTimeseries.calculateLabel.lookupMetricTypeOfTargetLabel": "{targetLabel} 中 {lookupMetricType}", "visTypeTimeseries.calculateLabel.lookupMetricTypeOfTargetWithAdditionalLabel": "{targetLabel} ({additionalLabel}) 中 {lookupMetricType}", "visTypeTimeseries.calculateLabel.mathLabel": "数学処理", - "visTypeTimeseries.calculateLabel.positiveRateLabel": "{field}の正の割合", "visTypeTimeseries.calculateLabel.seriesAggLabel": "数列集約 ({metricFunction})", "visTypeTimeseries.calculateLabel.staticValueLabel": "{metricValue} の不動値", "visTypeTimeseries.calculateLabel.unknownLabel": "不明", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index be5bcd3cf0543..18403d85d5ff7 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -3802,7 +3802,6 @@ "visTypeTimeseries.aggLookup.percentileLabel": "百分位数", "visTypeTimeseries.aggLookup.percentileRankLabel": "百分位数排名", "visTypeTimeseries.aggLookup.positiveOnlyLabel": "仅正数", - "visTypeTimeseries.aggLookup.positiveRateLabel": "正比率", "visTypeTimeseries.aggLookup.serialDifferenceLabel": "串行差分", "visTypeTimeseries.aggLookup.seriesAggLabel": "序列聚合", "visTypeTimeseries.aggLookup.staticValueLabel": "静态值", @@ -3825,7 +3824,6 @@ "visTypeTimeseries.aggSelect.metricsAggs.minLabel": "最小值", "visTypeTimeseries.aggSelect.metricsAggs.percentileLabel": "百分位数", "visTypeTimeseries.aggSelect.metricsAggs.percentileRankLabel": "百分位数排名", - "visTypeTimeseries.aggSelect.metricsAggs.positiveRateLabel": "正比率", "visTypeTimeseries.aggSelect.metricsAggs.staticValueLabel": "静态值", "visTypeTimeseries.aggSelect.metricsAggs.stdDeviationLabel": "标准偏差", "visTypeTimeseries.aggSelect.metricsAggs.sumLabel": "和", @@ -3869,7 +3867,6 @@ "visTypeTimeseries.calculateLabel.lookupMetricTypeOfTargetLabel": "{targetLabel} 的 {lookupMetricType}", "visTypeTimeseries.calculateLabel.lookupMetricTypeOfTargetWithAdditionalLabel": "{targetLabel} ({additionalLabel}) 的 {lookupMetricType}", "visTypeTimeseries.calculateLabel.mathLabel": "数学", - "visTypeTimeseries.calculateLabel.positiveRateLabel": "{field} 的正比率", "visTypeTimeseries.calculateLabel.seriesAggLabel": "序列聚合 ({metricFunction})", "visTypeTimeseries.calculateLabel.staticValueLabel": "{metricValue} 的静态值", "visTypeTimeseries.calculateLabel.unknownLabel": "未知", From e01fc2f09bff7eb3e7fba255ed16e69355c50673 Mon Sep 17 00:00:00 2001 From: Luke Elmers Date: Fri, 30 Oct 2020 03:24:03 -0600 Subject: [PATCH 57/80] Remove legacy app arch items from codeowners. (#82084) --- .github/CODEOWNERS | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 28380549c751c..36e9f4220b35c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -39,7 +39,10 @@ #CC# /src/legacy/core_plugins/vis_type_vislib/ @elastic/kibana-app #CC# /src/legacy/server/url_shortening/ @elastic/kibana-app #CC# /src/legacy/ui/public/state_management @elastic/kibana-app +#CC# /src/plugins/advanced_settings/ @elastic/kibana-app +#CC# /src/plugins/charts/ @elastic/kibana-app #CC# /src/plugins/index_pattern_management/public @elastic/kibana-app +#CC# /src/plugins/vis_default_editor @elastic/kibana-app # App Architecture /examples/bfetch_explorer/ @elastic/kibana-app-arch @@ -70,23 +73,10 @@ /x-pack/plugins/data_enhanced/ @elastic/kibana-app-arch /x-pack/plugins/embeddable_enhanced/ @elastic/kibana-app-arch /x-pack/plugins/ui_actions_enhanced/ @elastic/kibana-app-arch -#CC# /src/legacy/core_plugins/kibana/public/management/ @elastic/kibana-app-arch -#CC# /src/legacy/core_plugins/kibana/server/routes/api/management/ @elastic/kibana-app-arch -#CC# /src/legacy/core_plugins/embeddable_api/ @elastic/kibana-app-arch -#CC# /src/legacy/core_plugins/interpreter/ @elastic/kibana-app-arch -#CC# /src/legacy/core_plugins/kibana_react/ @elastic/kibana-app-arch -#CC# /src/legacy/core_plugins/status_page/public @elastic/kibana-app-arch -#CC# /src/legacy/server/index_patterns/ @elastic/kibana-app-arch -#CC# /src/legacy/ui/public/field_editor @elastic/kibana-app-arch -#CC# /src/legacy/ui/public/management @elastic/kibana-app-arch -#CC# /src/plugins/advanced_settings/ @elastic/kibana-app-arch #CC# /src/plugins/bfetch/ @elastic/kibana-app-arch -#CC# /src/plugins/charts/ @elastic/kibana-app-arch #CC# /src/plugins/index_pattern_management/public/service @elastic/kibana-app-arch #CC# /src/plugins/inspector/ @elastic/kibana-app-arch -#CC# /src/plugins/saved_objects/ @elastic/kibana-app-arch #CC# /src/plugins/share/ @elastic/kibana-app-arch -#CC# /src/plugins/vis_default_editor @elastic/kibana-app-arch #CC# /x-pack/plugins/advanced_ui_actions/ @elastic/kibana-app-arch #CC# /x-pack/plugins/drilldowns/ @elastic/kibana-app-arch #CC# /packages/kbn-interpreter/ @elastic/kibana-app-arch @@ -243,6 +233,7 @@ #CC# /src/legacy/ui/public/documentation_links @elastic/kibana-platform #CC# /src/legacy/ui/public/autoload @elastic/kibana-platform #CC# /src/plugins/legacy_export/ @elastic/kibana-platform +#CC# /src/plugins/saved_objects/ @elastic/kibana-platform #CC# /src/plugins/status_page/ @elastic/kibana-platform #CC# /src/plugins/testbed/server/ @elastic/kibana-platform #CC# /x-pack/legacy/plugins/xpack_main/server/ @elastic/kibana-platform From b0a223ebcbac7e404e8ae6da23b2cc6a4b509ff1 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Fri, 30 Oct 2020 10:40:23 +0100 Subject: [PATCH 58/80] [ML] Data Frame Analytics: Fix feature importance cell value and decision path chart (#82011) Fixes a regression that caused data grid cells for feature importance to be empty and clicking on the button to show the decision path chart popover to render the whole page empty. --- .../ml/common/types/feature_importance.ts | 5 +- .../components/data_grid/common.test.ts | 2 +- .../components/data_grid/common.ts | 95 +++++++++++++++++++ .../components/data_grid/data_grid.tsx | 27 ++++-- .../data_frame_analytics/common/fields.ts | 8 ++ .../common/get_index_data.ts | 2 +- .../exploration_results_table.tsx | 2 +- 7 files changed, 131 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/ml/common/types/feature_importance.ts b/x-pack/plugins/ml/common/types/feature_importance.ts index 4f5619cf3ab7b..1ae4c7832390c 100644 --- a/x-pack/plugins/ml/common/types/feature_importance.ts +++ b/x-pack/plugins/ml/common/types/feature_importance.ts @@ -8,10 +8,13 @@ export interface ClassFeatureImportance { class_name: string | boolean; importance: number; } + +// TODO We should separate the interface because classes/importance +// isn't both optional but either/or. export interface FeatureImportance { feature_name: string; - importance?: number; classes?: ClassFeatureImportance[]; + importance?: number; } export interface TopClass { diff --git a/x-pack/plugins/ml/public/application/components/data_grid/common.test.ts b/x-pack/plugins/ml/public/application/components/data_grid/common.test.ts index 4bb670ad02dfc..aaf6f90b00f4d 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/common.test.ts +++ b/x-pack/plugins/ml/public/application/components/data_grid/common.test.ts @@ -8,7 +8,7 @@ import { EuiDataGridSorting } from '@elastic/eui'; import { multiColumnSortFactory } from './common'; -describe('Transform: Define Pivot Common', () => { +describe('Data Frame Analytics: Data Grid Common', () => { test('multiColumnSortFactory()', () => { const data = [ { s: 'a', n: 1 }, diff --git a/x-pack/plugins/ml/public/application/components/data_grid/common.ts b/x-pack/plugins/ml/public/application/components/data_grid/common.ts index 642d0ae564b85..48a0a0c9ab126 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/common.ts +++ b/x-pack/plugins/ml/public/application/components/data_grid/common.ts @@ -24,7 +24,9 @@ import { KBN_FIELD_TYPES, } from '../../../../../../../src/plugins/data/public'; +import { DEFAULT_RESULTS_FIELD } from '../../../../common/constants/data_frame_analytics'; import { extractErrorMessage } from '../../../../common/util/errors'; +import { FeatureImportance, TopClasses } from '../../../../common/types/feature_importance'; import { BASIC_NUMERICAL_TYPES, @@ -158,6 +160,90 @@ export const getDataGridSchemaFromKibanaFieldType = ( return schema; }; +const getClassName = (className: string, isClassTypeBoolean: boolean) => { + if (isClassTypeBoolean) { + return className === 'true'; + } + + return className; +}; +/** + * Helper to transform feature importance flattened fields with arrays back to object structure + * + * @param row - EUI data grid data row + * @param mlResultsField - Data frame analytics results field + * @returns nested object structure of feature importance values + */ +export const getFeatureImportance = ( + row: Record, + mlResultsField: string, + isClassTypeBoolean = false +): FeatureImportance[] => { + const featureNames: string[] | undefined = + row[`${mlResultsField}.feature_importance.feature_name`]; + const classNames: string[] | undefined = + row[`${mlResultsField}.feature_importance.classes.class_name`]; + const classImportance: number[] | undefined = + row[`${mlResultsField}.feature_importance.classes.importance`]; + + if (featureNames === undefined) { + return []; + } + + // return object structure for classification job + if (classNames !== undefined && classImportance !== undefined) { + const overallClassNames = classNames?.slice(0, classNames.length / featureNames.length); + + return featureNames.map((fName, index) => { + const offset = overallClassNames.length * index; + const featureClassImportance = classImportance.slice( + offset, + offset + overallClassNames.length + ); + return { + feature_name: fName, + classes: overallClassNames.map((fClassName, fIndex) => { + return { + class_name: getClassName(fClassName, isClassTypeBoolean), + importance: featureClassImportance[fIndex], + }; + }), + }; + }); + } + + // return object structure for regression job + const importance: number[] = row[`${mlResultsField}.feature_importance.importance`]; + return featureNames.map((fName, index) => ({ + feature_name: fName, + importance: importance[index], + })); +}; + +/** + * Helper to transforms top classes flattened fields with arrays back to object structure + * + * @param row - EUI data grid data row + * @param mlResultsField - Data frame analytics results field + * @returns nested object structure of feature importance values + */ +export const getTopClasses = (row: Record, mlResultsField: string): TopClasses => { + const classNames: string[] | undefined = row[`${mlResultsField}.top_classes.class_name`]; + const classProbabilities: number[] | undefined = + row[`${mlResultsField}.top_classes.class_probability`]; + const classScores: number[] | undefined = row[`${mlResultsField}.top_classes.class_score`]; + + if (classNames === undefined || classProbabilities === undefined || classScores === undefined) { + return []; + } + + return classNames.map((className, index) => ({ + class_name: className, + class_probability: classProbabilities[index], + class_score: classScores[index], + })); +}; + export const useRenderCellValue = ( indexPattern: IndexPattern | undefined, pagination: IndexPagination, @@ -207,6 +293,15 @@ export const useRenderCellValue = ( return item[cId]; } + // For classification and regression results, we need to treat some fields with a custom transform. + if (cId === `${resultsField}.feature_importance`) { + return getFeatureImportance(fullItem, resultsField ?? DEFAULT_RESULTS_FIELD); + } + + if (cId === `${resultsField}.top_classes`) { + return getTopClasses(fullItem, resultsField ?? DEFAULT_RESULTS_FIELD); + } + // Try if the field name is available as a nested field. return getNestedProperty(tableItems[adjustedRowIndex], cId, null); } diff --git a/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx b/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx index fad2439f5d5ee..50e9cabc99c35 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx +++ b/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx @@ -27,10 +27,15 @@ import { DEFAULT_SAMPLER_SHARD_SIZE } from '../../../../common/constants/field_h import { ANALYSIS_CONFIG_TYPE, INDEX_STATUS } from '../../data_frame_analytics/common'; -import { euiDataGridStyle, euiDataGridToolbarSettings } from './common'; +import { + euiDataGridStyle, + euiDataGridToolbarSettings, + getFeatureImportance, + getTopClasses, +} from './common'; import { UseIndexDataReturnType } from './types'; import { DecisionPathPopover } from './feature_importance/decision_path_popover'; -import { TopClasses } from '../../../../common/types/feature_importance'; +import { FeatureImportance, TopClasses } from '../../../../common/types/feature_importance'; import { DEFAULT_RESULTS_FIELD } from '../../../../common/constants/data_frame_analytics'; import { DataFrameAnalysisConfigType } from '../../../../common/types/data_frame_analytics'; @@ -118,18 +123,28 @@ export const DataGrid: FC = memo( if (!row) return

; // if resultsField for some reason is not available then use ml const mlResultsField = resultsField ?? DEFAULT_RESULTS_FIELD; - const parsedFIArray = row[mlResultsField].feature_importance; let predictedValue: string | number | undefined; let topClasses: TopClasses = []; if ( predictionFieldName !== undefined && row && - row[mlResultsField][predictionFieldName] !== undefined + row[`${mlResultsField}.${predictionFieldName}`] !== undefined ) { - predictedValue = row[mlResultsField][predictionFieldName]; - topClasses = row[mlResultsField].top_classes; + predictedValue = row[`${mlResultsField}.${predictionFieldName}`]; + topClasses = getTopClasses(row, mlResultsField); } + const isClassTypeBoolean = topClasses.reduce( + (p, c) => typeof c.class_name === 'boolean' || p, + false + ); + + const parsedFIArray: FeatureImportance[] = getFeatureImportance( + row, + mlResultsField, + isClassTypeBoolean + ); + return ( !field.name.includes(`${resultsField}.${FEATURE_IMPORTANCE}.`) + ); } if ((numTopClasses ?? 0) > 0) { @@ -221,6 +225,10 @@ export const getDefaultFieldsFromJobCaps = ( name: `${resultsField}.${TOP_CLASSES}`, type: KBN_FIELD_TYPES.UNKNOWN, }); + // remove flattened top classes fields + fields = fields.filter( + (field: any) => !field.name.includes(`${resultsField}.${TOP_CLASSES}.`) + ); } // Only need to add these fields if we didn't use dest index pattern to get the fields diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_data.ts index 8e50aab0914db..85f222109d408 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_data.ts @@ -53,7 +53,7 @@ export const getIndexData = async ( index: jobConfig.dest.index, body: { fields: ['*'], - _source: [], + _source: false, query: searchQuery, from: pageIndex * pageSize, size: pageSize, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx index a6e95269b3633..10e2ad5b5eb53 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx @@ -29,7 +29,7 @@ interface Props { } export const ExplorationResultsTable: FC = React.memo( - ({ indexPattern, jobConfig, jobStatus, needsDestIndexPattern, searchQuery }) => { + ({ indexPattern, jobConfig, needsDestIndexPattern, searchQuery }) => { const { services: { mlServices: { mlApiServices }, From 512c35e70b88f28d0df914873f9ff4ff96ccf6a4 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Fri, 30 Oct 2020 11:20:54 +0100 Subject: [PATCH 59/80] fix Lens heading structure (#81752) --- .../workspace_panel/workspace_panel_wrapper.tsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx index fa63cd3c6f1e0..5cfc269dbb97b 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx @@ -15,6 +15,7 @@ import { EuiPageContentHeader, EuiFlexGroup, EuiFlexItem, + EuiScreenReaderOnly, } from '@elastic/eui'; import { Datasource, FramePublicAPI, Visualization } from '../../../types'; import { NativeRenderer } from '../../../native_renderer'; @@ -104,18 +105,25 @@ export function WorkspacePanelWrapper({
- {(!emptyExpression || title) && ( + {!emptyExpression || title ? ( - +

{title || i18n.translate('xpack.lens.chartTitle.unsaved', { defaultMessage: 'Unsaved' })} - +

+ ) : ( + +

+ {title || + i18n.translate('xpack.lens.chartTitle.unsaved', { defaultMessage: 'Unsaved' })} +

+
)} {children} From aa620bcbb0a26a3a5a5d18b8c81226f7a9f4ad61 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Fri, 30 Oct 2020 11:43:34 +0100 Subject: [PATCH 60/80] [Search] Add "restore" to session service (#81924) --- ...plugin-plugins-data-public.isearchsetup.md | 2 +- ...lugins-data-public.isearchsetup.session.md | 2 +- ...plugin-plugins-data-public.isearchstart.md | 2 +- ...lugins-data-public.isearchstart.session.md | 2 +- ...ugins-data-public.isessionservice.clear.md | 13 +++++++++++ ...data-public.isessionservice.getsession_.md | 13 +++++++++++ ...ata-public.isessionservice.getsessionid.md | 13 +++++++++++ ...gin-plugins-data-public.isessionservice.md | 22 +++++++++++++++++++ ...ins-data-public.isessionservice.restore.md | 13 +++++++++++ ...ugins-data-public.isessionservice.start.md | 13 +++++++++++ .../kibana-plugin-plugins-data-public.md | 1 + .../data/common/search/session/mocks.ts | 1 + .../data/common/search/session/types.ts | 6 +++++ src/plugins/data/public/index.ts | 2 +- src/plugins/data/public/public.api.md | 14 +++++++++--- src/plugins/data/public/search/index.ts | 1 + .../public/search/session_service.test.ts | 16 ++++++++++++++ .../data/public/search/session_service.ts | 22 +++++++++++-------- 18 files changed, 141 insertions(+), 17 deletions(-) create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.clear.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.getsession_.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.getsessionid.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.restore.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.start.md diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchsetup.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchsetup.md index bbf856480aedd..b2f8e83d8e654 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchsetup.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchsetup.md @@ -17,6 +17,6 @@ export interface ISearchSetup | Property | Type | Description | | --- | --- | --- | | [aggs](./kibana-plugin-plugins-data-public.isearchsetup.aggs.md) | AggsSetup | | -| [session](./kibana-plugin-plugins-data-public.isearchsetup.session.md) | ISessionService | session management | +| [session](./kibana-plugin-plugins-data-public.isearchsetup.session.md) | ISessionService | session management [ISessionService](./kibana-plugin-plugins-data-public.isessionservice.md) | | [usageCollector](./kibana-plugin-plugins-data-public.isearchsetup.usagecollector.md) | SearchUsageCollector | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchsetup.session.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchsetup.session.md index 7f39d9714a3a3..739fdfdeb5fc3 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchsetup.session.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchsetup.session.md @@ -4,7 +4,7 @@ ## ISearchSetup.session property -session management +session management [ISessionService](./kibana-plugin-plugins-data-public.isessionservice.md) Signature: diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchstart.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchstart.md index 4a69e94dd6f58..dba60c7bdf147 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchstart.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchstart.md @@ -19,6 +19,6 @@ export interface ISearchStart | [aggs](./kibana-plugin-plugins-data-public.isearchstart.aggs.md) | AggsStart | agg config sub service [AggsStart](./kibana-plugin-plugins-data-public.aggsstart.md) | | [search](./kibana-plugin-plugins-data-public.isearchstart.search.md) | ISearchGeneric | low level search [ISearchGeneric](./kibana-plugin-plugins-data-public.isearchgeneric.md) | | [searchSource](./kibana-plugin-plugins-data-public.isearchstart.searchsource.md) | ISearchStartSearchSource | high level search [ISearchStartSearchSource](./kibana-plugin-plugins-data-public.isearchstartsearchsource.md) | -| [session](./kibana-plugin-plugins-data-public.isearchstart.session.md) | ISessionService | session management | +| [session](./kibana-plugin-plugins-data-public.isearchstart.session.md) | ISessionService | session management [ISessionService](./kibana-plugin-plugins-data-public.isessionservice.md) | | [showError](./kibana-plugin-plugins-data-public.isearchstart.showerror.md) | (e: Error) => void | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchstart.session.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchstart.session.md index de25cccd6d27a..1ad194a9bec86 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchstart.session.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchstart.session.md @@ -4,7 +4,7 @@ ## ISearchStart.session property -session management +session management [ISessionService](./kibana-plugin-plugins-data-public.isessionservice.md) Signature: diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.clear.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.clear.md new file mode 100644 index 0000000000000..fc3d214eb4cad --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.clear.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISessionService](./kibana-plugin-plugins-data-public.isessionservice.md) > [clear](./kibana-plugin-plugins-data-public.isessionservice.clear.md) + +## ISessionService.clear property + +Clears the active session. + +Signature: + +```typescript +clear: () => void; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.getsession_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.getsession_.md new file mode 100644 index 0000000000000..e30c89fb1a9fd --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.getsession_.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISessionService](./kibana-plugin-plugins-data-public.isessionservice.md) > [getSession$](./kibana-plugin-plugins-data-public.isessionservice.getsession_.md) + +## ISessionService.getSession$ property + +Returns the observable that emits an update every time the session ID changes + +Signature: + +```typescript +getSession$: () => Observable; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.getsessionid.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.getsessionid.md new file mode 100644 index 0000000000000..838023ff1d8b9 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.getsessionid.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISessionService](./kibana-plugin-plugins-data-public.isessionservice.md) > [getSessionId](./kibana-plugin-plugins-data-public.isessionservice.getsessionid.md) + +## ISessionService.getSessionId property + +Returns the active session ID + +Signature: + +```typescript +getSessionId: () => string | undefined; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.md new file mode 100644 index 0000000000000..174f9dbe66bf4 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISessionService](./kibana-plugin-plugins-data-public.isessionservice.md) + +## ISessionService interface + +Signature: + +```typescript +export interface ISessionService +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [clear](./kibana-plugin-plugins-data-public.isessionservice.clear.md) | () => void | Clears the active session. | +| [getSession$](./kibana-plugin-plugins-data-public.isessionservice.getsession_.md) | () => Observable<string | undefined> | Returns the observable that emits an update every time the session ID changes | +| [getSessionId](./kibana-plugin-plugins-data-public.isessionservice.getsessionid.md) | () => string | undefined | Returns the active session ID | +| [restore](./kibana-plugin-plugins-data-public.isessionservice.restore.md) | (sessionId: string) => void | Restores existing session | +| [start](./kibana-plugin-plugins-data-public.isessionservice.start.md) | () => string | Starts a new session | + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.restore.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.restore.md new file mode 100644 index 0000000000000..857e85bbd30eb --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.restore.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISessionService](./kibana-plugin-plugins-data-public.isessionservice.md) > [restore](./kibana-plugin-plugins-data-public.isessionservice.restore.md) + +## ISessionService.restore property + +Restores existing session + +Signature: + +```typescript +restore: (sessionId: string) => void; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.start.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.start.md new file mode 100644 index 0000000000000..9e14c5ed26765 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isessionservice.start.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISessionService](./kibana-plugin-plugins-data-public.isessionservice.md) > [start](./kibana-plugin-plugins-data-public.isessionservice.start.md) + +## ISessionService.start property + +Starts a new session + +Signature: + +```typescript +start: () => string; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md index 6a3c437305cc8..ac6923fd12f96 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md @@ -74,6 +74,7 @@ | [ISearchSetup](./kibana-plugin-plugins-data-public.isearchsetup.md) | The setup contract exposed by the Search plugin exposes the search strategy extension point. | | [ISearchStart](./kibana-plugin-plugins-data-public.isearchstart.md) | search service | | [ISearchStartSearchSource](./kibana-plugin-plugins-data-public.isearchstartsearchsource.md) | high level search service | +| [ISessionService](./kibana-plugin-plugins-data-public.isessionservice.md) | | | [KueryNode](./kibana-plugin-plugins-data-public.kuerynode.md) | | | [OptionedValueProp](./kibana-plugin-plugins-data-public.optionedvalueprop.md) | | | [QueryState](./kibana-plugin-plugins-data-public.querystate.md) | All query state service state | diff --git a/src/plugins/data/common/search/session/mocks.ts b/src/plugins/data/common/search/session/mocks.ts index 7d5cd75b57534..2b64bbbd27565 100644 --- a/src/plugins/data/common/search/session/mocks.ts +++ b/src/plugins/data/common/search/session/mocks.ts @@ -23,6 +23,7 @@ export function getSessionServiceMock(): jest.Mocked { return { clear: jest.fn(), start: jest.fn(), + restore: jest.fn(), getSessionId: jest.fn(), getSession$: jest.fn(), }; diff --git a/src/plugins/data/common/search/session/types.ts b/src/plugins/data/common/search/session/types.ts index 80ab74f1aa14d..6660b8395547f 100644 --- a/src/plugins/data/common/search/session/types.ts +++ b/src/plugins/data/common/search/session/types.ts @@ -34,6 +34,12 @@ export interface ISessionService { * Starts a new session */ start: () => string; + + /** + * Restores existing session + */ + restore: (sessionId: string) => void; + /** * Clears the active session. */ diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index c041511745be2..c54cb36142cbd 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -380,7 +380,7 @@ export { PainlessError, } from './search'; -export type { SearchSource } from './search'; +export type { SearchSource, ISessionService } from './search'; export { ISearchOptions, isErrorResponse, isCompleteResponse, isPartialResponse } from '../common'; diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 7ee21236c1c79..b072407a5fe10 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -1415,8 +1415,6 @@ export interface ISearchSetup { // // (undocumented) aggs: AggsSetup; - // Warning: (ae-forgotten-export) The symbol "ISessionService" needs to be exported by the entry point index.d.ts - // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ISessionService" session: ISessionService; // Warning: (ae-forgotten-export) The symbol "SearchUsageCollector" needs to be exported by the entry point index.d.ts // @@ -1432,7 +1430,6 @@ export interface ISearchStart { aggs: AggsStart; search: ISearchGeneric; searchSource: ISearchStartSearchSource; - // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ISessionService" session: ISessionService; // (undocumented) showError: (e: Error) => void; @@ -1449,6 +1446,17 @@ export interface ISearchStartSearchSource { // @public (undocumented) export const isErrorResponse: (response?: IKibanaSearchResponse | undefined) => boolean | undefined; +// Warning: (ae-missing-release-tag) "ISessionService" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ISessionService { + clear: () => void; + getSession$: () => Observable; + getSessionId: () => string | undefined; + restore: (sessionId: string) => void; + start: () => string; +} + // Warning: (ae-missing-release-tag) "isFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) diff --git a/src/plugins/data/public/search/index.ts b/src/plugins/data/public/search/index.ts index 86804a819cb0e..1abf3192a4846 100644 --- a/src/plugins/data/public/search/index.ts +++ b/src/plugins/data/public/search/index.ts @@ -41,6 +41,7 @@ export { SearchSourceDependencies, SearchSourceFields, SortDirection, + ISessionService, } from '../../common/search'; export { getEsPreference } from './es_search'; diff --git a/src/plugins/data/public/search/session_service.test.ts b/src/plugins/data/public/search/session_service.test.ts index dd64d187f47d6..bcfd06944d983 100644 --- a/src/plugins/data/public/search/session_service.test.ts +++ b/src/plugins/data/public/search/session_service.test.ts @@ -20,6 +20,7 @@ import { SessionService } from './session_service'; import { ISessionService } from '../../common'; import { coreMock } from '../../../../core/public/mocks'; +import { take, toArray } from 'rxjs/operators'; describe('Session service', () => { let sessionService: ISessionService; @@ -39,5 +40,20 @@ describe('Session service', () => { sessionService.clear(); expect(sessionService.getSessionId()).toBeUndefined(); }); + + it('Restores a session', async () => { + const sessionId = 'sessionId'; + sessionService.restore(sessionId); + expect(sessionService.getSessionId()).toBe(sessionId); + }); + + it('sessionId$ observable emits current value', async () => { + sessionService.restore('1'); + const emittedValues = sessionService.getSession$().pipe(take(3), toArray()).toPromise(); + sessionService.restore('2'); + sessionService.clear(); + + expect(await emittedValues).toEqual(['1', '2', undefined]); + }); }); }); diff --git a/src/plugins/data/public/search/session_service.ts b/src/plugins/data/public/search/session_service.ts index 31524434af302..a172738812937 100644 --- a/src/plugins/data/public/search/session_service.ts +++ b/src/plugins/data/public/search/session_service.ts @@ -18,14 +18,16 @@ */ import uuid from 'uuid'; -import { Subject, Subscription } from 'rxjs'; +import { BehaviorSubject, Subscription } from 'rxjs'; import { PluginInitializerContext, StartServicesAccessor } from 'kibana/public'; -import { ISessionService } from '../../common/search'; import { ConfigSchema } from '../../config'; +import { ISessionService } from '../../common/search'; export class SessionService implements ISessionService { - private sessionId?: string; - private session$: Subject = new Subject(); + private session$ = new BehaviorSubject(undefined); + private get sessionId() { + return this.session$.getValue(); + } private appChangeSubscription$?: Subscription; private curApp?: string; @@ -68,13 +70,15 @@ export class SessionService implements ISessionService { } public start() { - this.sessionId = uuid.v4(); - this.session$.next(this.sessionId); - return this.sessionId; + this.session$.next(uuid.v4()); + return this.sessionId!; + } + + public restore(sessionId: string) { + this.session$.next(sessionId); } public clear() { - this.sessionId = undefined; - this.session$.next(this.sessionId); + this.session$.next(undefined); } } From 2aeeb6e5c5959c345f372d2b40db4ceb5e5f4ebc Mon Sep 17 00:00:00 2001 From: Bo Andersen Date: Fri, 30 Oct 2020 12:07:10 +0100 Subject: [PATCH 61/80] Fixed dead links (#78696) Fixed links to 404 page. Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- docs/user/monitoring/beats-details.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/user/monitoring/beats-details.asciidoc b/docs/user/monitoring/beats-details.asciidoc index 3d7a726d2f8a2..dbd9aecd04768 100644 --- a/docs/user/monitoring/beats-details.asciidoc +++ b/docs/user/monitoring/beats-details.asciidoc @@ -9,7 +9,7 @@ If you are monitoring Beats, the *Stack Monitoring* page in {kib} contains a panel for Beats in the cluster overview. [role="screenshot"] -image::user/monitoring/images/monitoring-beats.jpg["Monitoring Beats",link="images/monitoring-beats.jpg"] +image::user/monitoring/images/monitoring-beats.jpg["Monitoring Beats",link="user/monitoring/images/monitoring-beats.jpg"] To view an overview of the Beats data in the cluster, click *Overview*. The overview page has a section for activity in the last day, which is a real-time @@ -24,7 +24,7 @@ cluster. All columns are sortable. Clicking a Beat name takes you to the detail page. For example: [role="screenshot"] -image::user/monitoring/images/monitoring-beats-detail.jpg["Monitoring details for Filebeat",link="images/monitoring-beats-detail.jpg"] +image::user/monitoring/images/monitoring-beats-detail.jpg["Monitoring details for Filebeat",link="user/monitoring/images/monitoring-beats-detail.jpg"] The detail page contains a summary bar and charts. There are more charts on this page than the overview page and they are specific to a single Beat instance. From 21615c16ef40e2d740bb7ff64933e69307785b05 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Fri, 30 Oct 2020 12:59:28 +0100 Subject: [PATCH 62/80] SO management: fix legacy import index pattern selection being reset when switching page (#81621) * fix legacy import index pattern selection being reset when switching pages * update snapshots --- .../__snapshots__/flyout.test.tsx.snap | 10 ++ .../objects_table/components/flyout.tsx | 50 ++++++-- .../apps/management/_import_objects.ts | 43 +++++-- ...rt_objects_missing_all_index_patterns.json | 121 ++++++++++++++++++ .../management/saved_objects_page.ts | 6 + 5 files changed, 204 insertions(+), 26 deletions(-) create mode 100644 test/functional/apps/management/exports/_import_objects_missing_all_index_patterns.json diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap index 3a03c5c01b3c2..ea86ea58faf61 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap @@ -101,8 +101,11 @@ exports[`Flyout conflicts should allow conflict resolution 1`] = ` }, ] } + onTableChange={[Function]} pagination={ Object { + "pageIndex": 0, + "pageSize": 5, "pageSizeOptions": Array [ 5, 10, @@ -246,6 +249,10 @@ exports[`Flyout conflicts should allow conflict resolution 2`] = ` "newIndexPatternId": "2", }, ], + "unmatchedReferencesTablePagination": Object { + "pageIndex": 0, + "pageSize": 5, + }, }, }, ], @@ -403,8 +410,11 @@ exports[`Flyout legacy conflicts should allow conflict resolution 1`] = ` }, ] } + onTableChange={[Function]} pagination={ Object { + "pageIndex": 0, + "pageSize": 5, "pageSizeOptions": Array [ 5, 10, diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx index 3165ea4ca0794..75792becc29d8 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx @@ -88,6 +88,7 @@ export interface FlyoutState { conflictedSavedObjectsLinkedToSavedSearches?: any[]; conflictedSearchDocs?: any[]; unmatchedReferences?: ProcessedImportResponse['unmatchedReferences']; + unmatchedReferencesTablePagination: { pageIndex: number; pageSize: number }; failedImports?: ProcessedImportResponse['failedImports']; successfulImports?: ProcessedImportResponse['successfulImports']; conflictingRecord?: ConflictingRecord; @@ -115,6 +116,10 @@ export class Flyout extends Component { conflictedSavedObjectsLinkedToSavedSearches: undefined, conflictedSearchDocs: undefined, unmatchedReferences: undefined, + unmatchedReferencesTablePagination: { + pageIndex: 0, + pageSize: 5, + }, conflictingRecord: undefined, error: undefined, file: undefined, @@ -467,7 +472,7 @@ export class Flyout extends Component { }; renderUnmatchedReferences() { - const { unmatchedReferences } = this.state; + const { unmatchedReferences, unmatchedReferencesTablePagination: tablePagination } = this.state; if (!unmatchedReferences) { return null; @@ -527,22 +532,28 @@ export class Flyout extends Component { { defaultMessage: 'New index pattern' } ), render: (id: string) => { - const options = this.state.indexPatterns!.map( - (indexPattern) => - ({ - text: indexPattern.title, - value: indexPattern.id, - 'data-test-subj': `indexPatternOption-${indexPattern.title}`, - } as { text: string; value: string; 'data-test-subj'?: string }) - ); - - options.unshift({ - text: '-- Skip Import --', - value: '', - }); + const options = [ + { + text: '-- Skip Import --', + value: '', + }, + ...this.state.indexPatterns!.map( + (indexPattern) => + ({ + text: indexPattern.title, + value: indexPattern.id, + 'data-test-subj': `indexPatternOption-${indexPattern.title}`, + } as { text: string; value: string; 'data-test-subj'?: string }) + ), + ]; + + const selectedValue = + unmatchedReferences?.find((unmatchedRef) => unmatchedRef.existingIndexPatternId === id) + ?.newIndexPatternId ?? ''; return ( this.onIndexChanged(id, e)} options={options} @@ -553,6 +564,7 @@ export class Flyout extends Component { ]; const pagination = { + ...tablePagination, pageSizeOptions: [5, 10, 25], }; @@ -561,6 +573,16 @@ export class Flyout extends Component { items={unmatchedReferences as any[]} columns={columns} pagination={pagination} + onTableChange={({ page }) => { + if (page) { + this.setState({ + unmatchedReferencesTablePagination: { + pageSize: page.size, + pageIndex: page.index, + }, + }); + } + }} /> ); } diff --git a/test/functional/apps/management/_import_objects.ts b/test/functional/apps/management/_import_objects.ts index 0b417d7d23e93..ddabb32bf5909 100644 --- a/test/functional/apps/management/_import_objects.ts +++ b/test/functional/apps/management/_import_objects.ts @@ -421,21 +421,40 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(isSavedObjectImported).to.be(true); }); - it('should import saved objects with index patterns when index patterns does not exists', async () => { - // First, we need to delete the index pattern - await PageObjects.savedObjects.clickCheckboxByTitle('logstash-*'); - await PageObjects.savedObjects.clickDelete(); - - // Then, import the objects + it('should preserve index patterns selection when switching between pages', async () => { await PageObjects.savedObjects.importFile( - path.join(__dirname, 'exports', '_import_objects_with_index_patterns.json') + path.join(__dirname, 'exports', '_import_objects_missing_all_index_patterns.json') ); - await PageObjects.savedObjects.checkImportSucceeded(); - await PageObjects.savedObjects.clickImportDone(); - const objects = await PageObjects.savedObjects.getRowTitles(); - const isSavedObjectImported = objects.includes('saved object imported with index pattern'); - expect(isSavedObjectImported).to.be(true); + await PageObjects.savedObjects.setOverriddenIndexPatternValue( + 'missing-index-pattern-1', + 'index-pattern-test-1' + ); + + await testSubjects.click('pagination-button-next'); + + await PageObjects.savedObjects.setOverriddenIndexPatternValue( + 'missing-index-pattern-7', + 'index-pattern-test-2' + ); + + await testSubjects.click('pagination-button-previous'); + + const selectedIdForMissingIndexPattern1 = await testSubjects.getAttribute( + 'managementChangeIndexSelection-missing-index-pattern-1', + 'value' + ); + + expect(selectedIdForMissingIndexPattern1).to.eql('f1e4c910-a2e6-11e7-bb30-233be9be6a20'); + + await testSubjects.click('pagination-button-next'); + + const selectedIdForMissingIndexPattern7 = await testSubjects.getAttribute( + 'managementChangeIndexSelection-missing-index-pattern-7', + 'value' + ); + + expect(selectedIdForMissingIndexPattern7).to.eql('f1e4c910-a2e6-11e7-bb30-233be9be6a87'); }); }); }); diff --git a/test/functional/apps/management/exports/_import_objects_missing_all_index_patterns.json b/test/functional/apps/management/exports/_import_objects_missing_all_index_patterns.json new file mode 100644 index 0000000000000..45572b0bf34fe --- /dev/null +++ b/test/functional/apps/management/exports/_import_objects_missing_all_index_patterns.json @@ -0,0 +1,121 @@ +[ + { + "_id": "test-vis-1", + "_type": "visualization", + "_source": { + "title": "Test VIS 1", + "visState": "{\"title\":\"test vis 1\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-1\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + }, + { + "_id": "test-vis-2", + "_type": "visualization", + "_source": { + "title": "Test VIS 2", + "visState": "{\"title\":\"test vis 2\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-2\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + }, + { + "_id": "test-vis-3", + "_type": "visualization", + "_source": { + "title": "Test VIS 3", + "visState": "{\"title\":\"test vis 3\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-3\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + }, + { + "_id": "test-vis-4", + "_type": "visualization", + "_source": { + "title": "Test VIS 4", + "visState": "{\"title\":\"test vis 4\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-4\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + }, + { + "_id": "test-vis-5", + "_type": "visualization", + "_source": { + "title": "Test VIS 5", + "visState": "{\"title\":\"test vis 5\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-5\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + }, + { + "_id": "test-vis-6", + "_type": "visualization", + "_source": { + "title": "Test VIS 6", + "visState": "{\"title\":\"test vis 6\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-6\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + }, + { + "_id": "test-vis-7", + "_type": "visualization", + "_source": { + "title": "Test VIS 7", + "visState": "{\"title\":\"test vis 7\",\"type\":\"histogram\"}", + "uiStateJSON": "{}", + "description": "", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"missing-index-pattern-7\",\"query\":{}}" + } + }, + "_meta": { + "savedObjectVersion": 2 + } + } +] diff --git a/test/functional/page_objects/management/saved_objects_page.ts b/test/functional/page_objects/management/saved_objects_page.ts index 8e65b6488836c..0742f14b2eeb4 100644 --- a/test/functional/page_objects/management/saved_objects_page.ts +++ b/test/functional/page_objects/management/saved_objects_page.ts @@ -126,6 +126,12 @@ export function SavedObjectsPageProvider({ getService, getPageObjects }: FtrProv } } + async setOverriddenIndexPatternValue(oldName: string, newName: string) { + const select = await testSubjects.find(`managementChangeIndexSelection-${oldName}`); + const option = await testSubjects.findDescendant(`indexPatternOption-${newName}`, select); + await option.click(); + } + async clickCopyToSpaceByTitle(title: string) { const table = keyBy(await this.getElementsInTable(), 'title'); // should we check if table size > 0 and log error if not? From aaadbe88c5b6e5d08e2ccb1bdda753f84858d94d Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Fri, 30 Oct 2020 13:04:48 +0100 Subject: [PATCH 63/80] Context menu trigger for URL Drilldown (#81158) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 add context menu trigger to URL drilldown * fix: 🐛 translate "Drilldowns" grouping title * feat: 🎸 add dynamic action grouping to dynamic actions * fix: 🐛 add translations to trigger texts * feat: 🎸 enambe ctx menu trigger in both flyouts, move to end * fix: 🐛 show context menu event scope variable sfor ctx menu * test: 💍 add tests * fix: 🐛 use correct namespace for translation keys * docs: ✏️ update autogenerated docs Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- ...able-public.iscontextmenutriggercontext.md | 11 +++++ ...kibana-plugin-plugins-embeddable-public.md | 1 + src/plugins/embeddable/public/index.ts | 1 + .../public/lib/triggers/triggers.ts | 47 +++++++++++++------ src/plugins/embeddable/public/public.api.md | 7 ++- .../drilldowns/actions/drilldown_shared.ts | 5 +- .../flyout_create_drilldown.test.tsx | 2 +- .../flyout_create_drilldown.tsx | 11 +++-- .../flyout_edit_drilldown.tsx | 12 +++-- .../public/lib/url_drilldown.tsx | 13 +++-- .../public/lib/url_drilldown_scope.test.ts | 47 +++++++++++-------- .../public/lib/url_drilldown_scope.ts | 21 +++++++-- .../public/actions/drilldown_grouping.ts | 8 +++- .../embeddable_enhanced/public/index.ts | 2 +- .../dynamic_action_grouping.ts | 23 +++++++++ .../dynamic_action_manager.test.ts | 22 +++++++++ .../dynamic_actions/dynamic_action_manager.ts | 2 + 17 files changed, 181 insertions(+), 54 deletions(-) create mode 100644 docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iscontextmenutriggercontext.md create mode 100644 x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_grouping.ts diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iscontextmenutriggercontext.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iscontextmenutriggercontext.md new file mode 100644 index 0000000000000..62610624655a1 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iscontextmenutriggercontext.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [isContextMenuTriggerContext](./kibana-plugin-plugins-embeddable-public.iscontextmenutriggercontext.md) + +## isContextMenuTriggerContext variable + +Signature: + +```typescript +isContextMenuTriggerContext: (context: unknown) => context is EmbeddableContext +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.md index df67eda5074b9..06f792837e4fe 100644 --- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.md +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.md @@ -77,6 +77,7 @@ | [contextMenuTrigger](./kibana-plugin-plugins-embeddable-public.contextmenutrigger.md) | | | [defaultEmbeddableFactoryProvider](./kibana-plugin-plugins-embeddable-public.defaultembeddablefactoryprovider.md) | | | [EmbeddableRenderer](./kibana-plugin-plugins-embeddable-public.embeddablerenderer.md) | Helper react component to render an embeddable Can be used if you have an embeddable object or an embeddable factory Supports updating input by passing input prop | +| [isContextMenuTriggerContext](./kibana-plugin-plugins-embeddable-public.iscontextmenutriggercontext.md) | | | [isRangeSelectTriggerContext](./kibana-plugin-plugins-embeddable-public.israngeselecttriggercontext.md) | | | [isValueClickTriggerContext](./kibana-plugin-plugins-embeddable-public.isvalueclicktriggercontext.md) | | | [PANEL\_BADGE\_TRIGGER](./kibana-plugin-plugins-embeddable-public.panel_badge_trigger.md) | | diff --git a/src/plugins/embeddable/public/index.ts b/src/plugins/embeddable/public/index.ts index 789353ca4abd7..0d2dcf208f2ef 100644 --- a/src/plugins/embeddable/public/index.ts +++ b/src/plugins/embeddable/public/index.ts @@ -70,6 +70,7 @@ export { isSavedObjectEmbeddableInput, isRangeSelectTriggerContext, isValueClickTriggerContext, + isContextMenuTriggerContext, EmbeddableStateTransfer, EmbeddableEditorState, EmbeddablePackageState, diff --git a/src/plugins/embeddable/public/lib/triggers/triggers.ts b/src/plugins/embeddable/public/lib/triggers/triggers.ts index 54c7a2ecc129d..b2965b55dbdfa 100644 --- a/src/plugins/embeddable/public/lib/triggers/triggers.ts +++ b/src/plugins/embeddable/public/lib/triggers/triggers.ts @@ -17,6 +17,7 @@ * under the License. */ +import { i18n } from '@kbn/i18n'; import { Datatable } from '../../../../expressions'; import { Trigger } from '../../../../ui_actions/public'; import { IEmbeddable } from '..'; @@ -53,31 +54,49 @@ export type ChartActionContext = | ValueClickContext | RangeSelectContext; -export const isValueClickTriggerContext = ( - context: ChartActionContext -): context is ValueClickContext => context.data && 'data' in context.data; - -export const isRangeSelectTriggerContext = ( - context: ChartActionContext -): context is RangeSelectContext => context.data && 'range' in context.data; - export const CONTEXT_MENU_TRIGGER = 'CONTEXT_MENU_TRIGGER'; export const contextMenuTrigger: Trigger<'CONTEXT_MENU_TRIGGER'> = { id: CONTEXT_MENU_TRIGGER, - title: 'Context menu', - description: 'Triggered on top-right corner context-menu select.', + title: i18n.translate('embeddableApi.contextMenuTrigger.title', { + defaultMessage: 'Context menu', + }), + description: i18n.translate('embeddableApi.contextMenuTrigger.description', { + defaultMessage: 'A panel top-right corner context menu click.', + }), }; export const PANEL_BADGE_TRIGGER = 'PANEL_BADGE_TRIGGER'; export const panelBadgeTrigger: Trigger<'PANEL_BADGE_TRIGGER'> = { id: PANEL_BADGE_TRIGGER, - title: 'Panel badges', - description: 'Actions appear in title bar when an embeddable loads in a panel.', + title: i18n.translate('embeddableApi.panelBadgeTrigger.title', { + defaultMessage: 'Panel badges', + }), + description: i18n.translate('embeddableApi.panelBadgeTrigger.description', { + defaultMessage: 'Actions appear in title bar when an embeddable loads in a panel.', + }), }; export const PANEL_NOTIFICATION_TRIGGER = 'PANEL_NOTIFICATION_TRIGGER'; export const panelNotificationTrigger: Trigger<'PANEL_NOTIFICATION_TRIGGER'> = { id: PANEL_NOTIFICATION_TRIGGER, - title: 'Panel notifications', - description: 'Actions appear in top-right corner of a panel.', + title: i18n.translate('embeddableApi.panelNotificationTrigger.title', { + defaultMessage: 'Panel notifications', + }), + description: i18n.translate('embeddableApi.panelNotificationTrigger.description', { + defaultMessage: 'Actions appear in top-right corner of a panel.', + }), }; + +export const isValueClickTriggerContext = ( + context: ChartActionContext +): context is ValueClickContext => context.data && 'data' in context.data; + +export const isRangeSelectTriggerContext = ( + context: ChartActionContext +): context is RangeSelectContext => context.data && 'range' in context.data; + +export const isContextMenuTriggerContext = (context: unknown): context is EmbeddableContext => + !!context && + typeof context === 'object' && + !!(context as EmbeddableContext).embeddable && + typeof (context as EmbeddableContext).embeddable === 'object'; diff --git a/src/plugins/embeddable/public/public.api.md b/src/plugins/embeddable/public/public.api.md index 00971ed37db3a..e84dff1172c2e 100644 --- a/src/plugins/embeddable/public/public.api.md +++ b/src/plugins/embeddable/public/public.api.md @@ -695,6 +695,11 @@ export interface IEmbeddable): void; } +// Warning: (ae-missing-release-tag) "isContextMenuTriggerContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const isContextMenuTriggerContext: (context: unknown) => context is EmbeddableContext; + // Warning: (ae-missing-release-tag) "isErrorEmbeddable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -884,7 +889,7 @@ export const withEmbeddableSubscription: { }); }); - test('not compatible if no triggers intersection', async () => { + test('not compatible if no triggers intersect', async () => { await assertNonCompatibility({ actionFactoriesTriggers: [], }); 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 a2192808c2d40..a417deb47db53 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 @@ -10,9 +10,12 @@ import { ActionByType } from '../../../../../../../../src/plugins/ui_actions/pub import { toMountPoint } from '../../../../../../../../src/plugins/kibana_react/public'; import { isEnhancedEmbeddable, - embeddableEnhancedContextMenuDrilldownGrouping, + embeddableEnhancedDrilldownGrouping, } from '../../../../../../embeddable_enhanced/public'; -import { EmbeddableContext } from '../../../../../../../../src/plugins/embeddable/public'; +import { + CONTEXT_MENU_TRIGGER, + EmbeddableContext, +} from '../../../../../../../../src/plugins/embeddable/public'; import { StartDependencies } from '../../../../plugin'; import { StartServicesGetter } from '../../../../../../../../src/plugins/kibana_utils/public'; import { ensureNestedTriggers } from '../drilldown_shared'; @@ -27,7 +30,7 @@ export class FlyoutCreateDrilldownAction implements ActionByType handle.close()} viewMode={'create'} dynamicActionManager={embeddable.enhancements.dynamicActions} - triggers={ensureNestedTriggers(embeddable.supportedTriggers())} + triggers={[...ensureNestedTriggers(embeddable.supportedTriggers()), CONTEXT_MENU_TRIGGER]} placeContext={{ embeddable }} /> ), 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 56ef25005078b..1f0570445a8fc 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 @@ -10,12 +10,16 @@ import { reactToUiComponent, toMountPoint, } from '../../../../../../../../src/plugins/kibana_react/public'; -import { EmbeddableContext, ViewMode } from '../../../../../../../../src/plugins/embeddable/public'; +import { + EmbeddableContext, + ViewMode, + CONTEXT_MENU_TRIGGER, +} from '../../../../../../../../src/plugins/embeddable/public'; import { txtDisplayName } from './i18n'; import { MenuItem } from './menu_item'; import { isEnhancedEmbeddable, - embeddableEnhancedContextMenuDrilldownGrouping, + embeddableEnhancedDrilldownGrouping, } from '../../../../../../embeddable_enhanced/public'; import { StartDependencies } from '../../../../plugin'; import { StartServicesGetter } from '../../../../../../../../src/plugins/kibana_utils/public'; @@ -31,7 +35,7 @@ export class FlyoutEditDrilldownAction implements ActionByType handle.close()} viewMode={'manage'} dynamicActionManager={embeddable.enhancements.dynamicActions} - triggers={ensureNestedTriggers(embeddable.supportedTriggers())} + triggers={[...ensureNestedTriggers(embeddable.supportedTriggers()), CONTEXT_MENU_TRIGGER]} placeContext={{ embeddable }} /> ), diff --git a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx index 85e92d0827daa..807dfeed21d1f 100644 --- a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx +++ b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx @@ -6,7 +6,11 @@ import React from 'react'; import { reactToUiComponent } from '../../../../../../src/plugins/kibana_react/public'; -import { ChartActionContext, IEmbeddable } from '../../../../../../src/plugins/embeddable/public'; +import { + ChartActionContext, + CONTEXT_MENU_TRIGGER, + IEmbeddable, +} from '../../../../../../src/plugins/embeddable/public'; import { CollectConfigProps as CollectConfigPropsBase } from '../../../../../../src/plugins/kibana_utils/public'; import { SELECT_RANGE_TRIGGER, @@ -34,7 +38,10 @@ interface UrlDrilldownDeps { export type ActionContext = ChartActionContext; export type Config = UrlDrilldownConfig; -export type UrlTrigger = typeof VALUE_CLICK_TRIGGER | typeof SELECT_RANGE_TRIGGER; +export type UrlTrigger = + | typeof CONTEXT_MENU_TRIGGER + | typeof VALUE_CLICK_TRIGGER + | typeof SELECT_RANGE_TRIGGER; export interface ActionFactoryContext extends BaseActionFactoryContext { embeddable?: IEmbeddable; } @@ -58,7 +65,7 @@ export class UrlDrilldown implements Drilldown = ({ diff --git a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.test.ts b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.test.ts index 6989819da2b0b..a93e150deee8f 100644 --- a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.test.ts +++ b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.test.ts @@ -87,25 +87,25 @@ describe('VALUE_CLICK_TRIGGER', () => { ]) as ValueClickTriggerEventScope; expect(mockEventScope.points.length).toBeGreaterThan(3); expect(mockEventScope.points).toMatchInlineSnapshot(` - Array [ - Object { - "key": "event.points.0.key", - "value": "event.points.0.value", - }, - Object { - "key": "event.points.1.key", - "value": "event.points.1.value", - }, - Object { - "key": "event.points.2.key", - "value": "event.points.2.value", - }, - Object { - "key": "event.points.3.key", - "value": "event.points.3.value", - }, - ] - `); + Array [ + Object { + "key": "event.points.0.key", + "value": "event.points.0.value", + }, + Object { + "key": "event.points.1.key", + "value": "event.points.1.value", + }, + Object { + "key": "event.points.2.key", + "value": "event.points.2.value", + }, + Object { + "key": "event.points.3.key", + "value": "event.points.3.value", + }, + ] + `); }); }); @@ -130,3 +130,12 @@ describe('VALUE_CLICK_TRIGGER', () => { }); }); }); + +describe('CONTEXT_MENU_TRIGGER', () => { + test('getMockEventScope() results in empty scope', () => { + const mockEventScope = getMockEventScope([ + 'CONTEXT_MENU_TRIGGER', + ]) as ValueClickTriggerEventScope; + expect(mockEventScope).toEqual({}); + }); +}); diff --git a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.ts b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.ts index 0f66cb144c967..234af380689e9 100644 --- a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.ts +++ b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown_scope.ts @@ -14,11 +14,15 @@ import { IEmbeddable, isRangeSelectTriggerContext, isValueClickTriggerContext, + isContextMenuTriggerContext, RangeSelectContext, ValueClickContext, } from '../../../../../../src/plugins/embeddable/public'; import type { ActionContext, ActionFactoryContext, UrlTrigger } from './url_drilldown'; -import { SELECT_RANGE_TRIGGER } from '../../../../../../src/plugins/ui_actions/public'; +import { + SELECT_RANGE_TRIGGER, + VALUE_CLICK_TRIGGER, +} from '../../../../../../src/plugins/ui_actions/public'; type ContextScopeInput = ActionContext | ActionFactoryContext; @@ -101,7 +105,10 @@ export function getContextScope(contextScopeInput: ContextScopeInput): UrlDrilld * URL drilldown event scope, * available as {{event.$}} */ -export type UrlDrilldownEventScope = ValueClickTriggerEventScope | RangeSelectTriggerEventScope; +export type UrlDrilldownEventScope = + | ValueClickTriggerEventScope + | RangeSelectTriggerEventScope + | ContextMenuTriggerEventScope; export type EventScopeInput = ActionContext; export interface ValueClickTriggerEventScope { key?: string; @@ -115,11 +122,15 @@ export interface RangeSelectTriggerEventScope { to?: string | number; } +export type ContextMenuTriggerEventScope = object; + export function getEventScope(eventScopeInput: EventScopeInput): UrlDrilldownEventScope { if (isRangeSelectTriggerContext(eventScopeInput)) { return getEventScopeFromRangeSelectTriggerContext(eventScopeInput); } else if (isValueClickTriggerContext(eventScopeInput)) { return getEventScopeFromValueClickTriggerContext(eventScopeInput); + } else if (isContextMenuTriggerContext(eventScopeInput)) { + return {}; } else { throw new Error("UrlDrilldown [getEventScope] can't build scope from not supported trigger"); } @@ -169,7 +180,9 @@ export function getMockEventScope([trigger]: UrlTrigger[]): UrlDrilldownEventSco from: new Date(Date.now() - 15 * 60 * 1000).toISOString(), // 15 minutes ago to: new Date().toISOString(), }; - } else { + } + + if (trigger === VALUE_CLICK_TRIGGER) { // number of mock points to generate // should be larger or equal of any possible data points length emitted by VALUE_CLICK_TRIGGER const nPoints = 4; @@ -184,6 +197,8 @@ export function getMockEventScope([trigger]: UrlTrigger[]): UrlDrilldownEventSco points, }; } + + return {}; } type Primitive = string | number | boolean | null; diff --git a/x-pack/plugins/embeddable_enhanced/public/actions/drilldown_grouping.ts b/x-pack/plugins/embeddable_enhanced/public/actions/drilldown_grouping.ts index 5ea8928532c28..0aa1c0e6f08ae 100644 --- a/x-pack/plugins/embeddable_enhanced/public/actions/drilldown_grouping.ts +++ b/x-pack/plugins/embeddable_enhanced/public/actions/drilldown_grouping.ts @@ -4,15 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ +import { i18n } from '@kbn/i18n'; import { IEmbeddable } from '../../../../../src/plugins/embeddable/public'; import { UiActionsPresentableGrouping as PresentableGrouping } from '../../../../../src/plugins/ui_actions/public'; -export const contextMenuDrilldownGrouping: PresentableGrouping<{ +export const drilldownGrouping: PresentableGrouping<{ embeddable?: IEmbeddable; }> = [ { id: 'drilldowns', - getDisplayName: () => 'Drilldowns', + getDisplayName: () => + i18n.translate('xpack.embeddableEnhanced.Drilldowns', { + defaultMessage: 'Drilldowns', + }), getIconType: () => 'symlink', order: 25, }, diff --git a/x-pack/plugins/embeddable_enhanced/public/index.ts b/x-pack/plugins/embeddable_enhanced/public/index.ts index a7916685239df..24f8eb623abe0 100644 --- a/x-pack/plugins/embeddable_enhanced/public/index.ts +++ b/x-pack/plugins/embeddable_enhanced/public/index.ts @@ -20,4 +20,4 @@ export function plugin(context: PluginInitializerContext) { export { EnhancedEmbeddable, EnhancedEmbeddableContext } from './types'; export { isEnhancedEmbeddable } from './embeddables'; -export { contextMenuDrilldownGrouping as embeddableEnhancedContextMenuDrilldownGrouping } from './actions'; +export { drilldownGrouping as embeddableEnhancedDrilldownGrouping } from './actions'; diff --git a/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_grouping.ts b/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_grouping.ts new file mode 100644 index 0000000000000..feda1c93e2511 --- /dev/null +++ b/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_grouping.ts @@ -0,0 +1,23 @@ +/* + * 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'; +import { IEmbeddable } from '../../../../../src/plugins/embeddable/public'; +import { UiActionsPresentableGrouping as PresentableGrouping } from '../../../../../src/plugins/ui_actions/public'; + +export const dynamicActionGrouping: PresentableGrouping<{ + embeddable?: IEmbeddable; +}> = [ + { + id: 'dynamicActions', + getDisplayName: () => + i18n.translate('xpack.uiActionsEnhanced.CustomActions', { + defaultMessage: 'Custom actions', + }), + getIconType: () => 'symlink', + order: 26, + }, +]; diff --git a/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_manager.test.ts b/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_manager.test.ts index cdd357f3560b8..cbc381c911c3d 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_manager.test.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_manager.test.ts @@ -13,6 +13,7 @@ import { UiActionsServiceEnhancements } from '../services'; import { ActionFactoryDefinition } from './action_factory_definition'; import { SerializedAction, SerializedEvent } from './types'; import { licensingMock } from '../../../licensing/public/mocks'; +import { dynamicActionGrouping } from './dynamic_action_grouping'; const actionFactoryDefinition1: ActionFactoryDefinition = { id: 'ACTION_FACTORY_1', @@ -294,6 +295,27 @@ describe('DynamicActionManager', () => { expect(manager.state.get().events.length).toBe(1); }); + test('adds revived actiosn to "dynamic action" grouping', async () => { + const { manager, uiActions, actions } = setup([]); + const action: SerializedAction = { + factoryId: actionFactoryDefinition1.id, + name: 'foo', + config: {}, + }; + + uiActions.registerActionFactory(actionFactoryDefinition1); + + await manager.start(); + + expect(manager.state.get().events.length).toBe(0); + + await manager.createEvent(action, ['VALUE_CLICK_TRIGGER']); + + const createdAction = actions.values().next().value; + + expect(createdAction.grouping).toBe(dynamicActionGrouping); + }); + test('optimistically adds event to UI state', async () => { const { manager, uiActions } = setup([]); const action: SerializedAction = { diff --git a/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_manager.ts b/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_manager.ts index b414296690c9e..f096b17f8a78d 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_manager.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_manager.ts @@ -18,6 +18,7 @@ import { } from '../../../../../src/plugins/kibana_utils/common'; import { StartContract } from '../plugin'; import { SerializedAction, SerializedEvent } from './types'; +import { dynamicActionGrouping } from './dynamic_action_grouping'; const compareEvents = ( a: ReadonlyArray<{ eventId: string }>, @@ -93,6 +94,7 @@ export class DynamicActionManager { uiActions.registerAction({ ...actionDefinition, id: actionId, + grouping: dynamicActionGrouping, isCompatible: async (context) => { if (!(await isCompatible(context))) return false; if (!actionDefinition.isCompatible) return true; From 81c0e126cc02290ac13595a705fb0f90cc992985 Mon Sep 17 00:00:00 2001 From: Sandra Gonzales Date: Fri, 30 Oct 2020 08:28:28 -0400 Subject: [PATCH 64/80] [Fleet] fix duplicate ingest pipeline refs (#82078) * check if pipeline refs for version already exists * use the right version --- .../elasticsearch/ingest_pipeline/install.ts | 17 + .../apis/epm/install_remove_assets.ts | 414 ++++++++++-------- 2 files changed, 254 insertions(+), 177 deletions(-) diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/install.ts index 43c0179c0aa8a..58abdeb0d443d 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/install.ts @@ -14,6 +14,8 @@ import { import * as Registry from '../../registry'; import { CallESAsCurrentUser } from '../../../../types'; import { saveInstalledEsRefs } from '../../packages/install'; +import { getInstallationObject } from '../../packages'; +import { deletePipelineRefs } from './remove'; interface RewriteSubstitution { source: string; @@ -31,6 +33,7 @@ export const installPipelines = async ( // it can be created pointing to the new template, without removing the old one and effecting data // so do not remove the currently installed pipelines here const dataStreams = installablePackage.data_streams; + const { name: pkgName, version: pkgVersion } = installablePackage; if (!dataStreams?.length) return []; const pipelinePaths = paths.filter((path) => isPipeline(path)); // get and save pipeline refs before installing pipelines @@ -50,6 +53,20 @@ export const installPipelines = async ( acc.push(...pipelineObjectRefs); return acc; }, []); + + // check that we don't duplicate the pipeline refs if the user is reinstalling + const installedPkg = await getInstallationObject({ + savedObjectsClient, + pkgName, + }); + if (!installedPkg) throw new Error("integration wasn't found while installing pipelines"); + // remove the current pipeline refs, if any exist, associated with this version before saving new ones so no duplicates occur + await deletePipelineRefs( + savedObjectsClient, + installedPkg.attributes.installed_es, + pkgName, + pkgVersion + ); await saveInstalledEsRefs(savedObjectsClient, installablePackage.name, pipelineRefs); const pipelines = dataStreams.reduce>>((acc, dataStream) => { if (dataStream.ingest_pipeline) { diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts index cc6a384dcaafe..72ea9cb4e7ef3 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts @@ -5,6 +5,8 @@ */ import expect from '@kbn/expect'; +import { sortBy } from 'lodash'; +import { AssetReference } from '../../../../plugins/ingest_manager/common'; import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; import { skipIfNoDockerRegistry } from '../../helpers'; @@ -12,6 +14,8 @@ export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; const kibanaServer = getService('kibanaServer'); const supertest = getService('supertest'); + const dockerServers = getService('dockerServers'); + const server = dockerServers.get('registry'); const es = getService('es'); const pkgName = 'all_assets'; const pkgVersion = '0.1.0'; @@ -33,194 +37,27 @@ export default function (providerContext: FtrProviderContext) { describe('installs all assets when installing a package for the first time', async () => { skipIfNoDockerRegistry(providerContext); before(async () => { + if (!server.enabled) return; await installPackage(pkgKey); }); after(async () => { + if (!server.enabled) return; await uninstallPackage(pkgKey); }); - it('should have installed the ILM policy', async function () { - const resPolicy = await es.transport.request({ - method: 'GET', - path: `/_ilm/policy/all_assets`, - }); - expect(resPolicy.statusCode).equal(200); - }); - it('should have installed the index templates', async function () { - const resLogsTemplate = await es.transport.request({ - method: 'GET', - path: `/_index_template/${logsTemplateName}`, - }); - expect(resLogsTemplate.statusCode).equal(200); - - const resMetricsTemplate = await es.transport.request({ - method: 'GET', - path: `/_index_template/${metricsTemplateName}`, - }); - expect(resMetricsTemplate.statusCode).equal(200); - }); - it('should have installed the pipelines', async function () { - const res = await es.transport.request({ - method: 'GET', - path: `/_ingest/pipeline/${logsTemplateName}-${pkgVersion}`, - }); - expect(res.statusCode).equal(200); - const resPipeline1 = await es.transport.request({ - method: 'GET', - path: `/_ingest/pipeline/${logsTemplateName}-${pkgVersion}-pipeline1`, - }); - expect(resPipeline1.statusCode).equal(200); - const resPipeline2 = await es.transport.request({ - method: 'GET', - path: `/_ingest/pipeline/${logsTemplateName}-${pkgVersion}-pipeline2`, - }); - expect(resPipeline2.statusCode).equal(200); - }); - it('should have installed the template components', async function () { - const res = await es.transport.request({ - method: 'GET', - path: `/_component_template/${logsTemplateName}-mappings`, - }); - expect(res.statusCode).equal(200); - const resSettings = await es.transport.request({ - method: 'GET', - path: `/_component_template/${logsTemplateName}-settings`, - }); - expect(resSettings.statusCode).equal(200); - }); - it('should have installed the transform components', async function () { - const res = await es.transport.request({ - method: 'GET', - path: `/_transform/${pkgName}.test-default-${pkgVersion}`, - }); - expect(res.statusCode).equal(200); - }); - it('should have created the index for the transform', async function () { - // the index is defined in the transform file - const res = await es.transport.request({ - method: 'GET', - path: `/logs-all_assets.test_log_current_default`, - }); - expect(res.statusCode).equal(200); - }); - it('should have installed the kibana assets', async function () { - const resIndexPatternLogs = await kibanaServer.savedObjects.get({ - type: 'index-pattern', - id: 'logs-*', - }); - expect(resIndexPatternLogs.id).equal('logs-*'); - const resIndexPatternMetrics = await kibanaServer.savedObjects.get({ - type: 'index-pattern', - id: 'metrics-*', - }); - expect(resIndexPatternMetrics.id).equal('metrics-*'); - const resDashboard = await kibanaServer.savedObjects.get({ - type: 'dashboard', - id: 'sample_dashboard', - }); - expect(resDashboard.id).equal('sample_dashboard'); - const resDashboard2 = await kibanaServer.savedObjects.get({ - type: 'dashboard', - id: 'sample_dashboard2', - }); - expect(resDashboard2.id).equal('sample_dashboard2'); - const resVis = await kibanaServer.savedObjects.get({ - type: 'visualization', - id: 'sample_visualization', - }); - expect(resVis.id).equal('sample_visualization'); - const resSearch = await kibanaServer.savedObjects.get({ - type: 'search', - id: 'sample_search', - }); - expect(resSearch.id).equal('sample_search'); - }); - it('should create an index pattern with the package fields', async () => { - const resIndexPatternLogs = await kibanaServer.savedObjects.get({ - type: 'index-pattern', - id: 'logs-*', - }); - const fields = JSON.parse(resIndexPatternLogs.attributes.fields); - const exists = fields.find((field: { name: string }) => field.name === 'logs_test_name'); - expect(exists).not.to.be(undefined); - const resIndexPatternMetrics = await kibanaServer.savedObjects.get({ - type: 'index-pattern', - id: 'metrics-*', - }); - const fieldsMetrics = JSON.parse(resIndexPatternMetrics.attributes.fields); - const metricsExists = fieldsMetrics.find( - (field: { name: string }) => field.name === 'metrics_test_name' - ); - expect(metricsExists).not.to.be(undefined); - }); - it('should have created the correct saved object', async function () { - const res = await kibanaServer.savedObjects.get({ - type: 'epm-packages', - id: 'all_assets', - }); - expect(res.attributes).eql({ - installed_kibana: [ - { - id: 'sample_dashboard', - type: 'dashboard', - }, - { - id: 'sample_dashboard2', - type: 'dashboard', - }, - { - id: 'sample_search', - type: 'search', - }, - { - id: 'sample_visualization', - type: 'visualization', - }, - ], - installed_es: [ - { - id: 'logs-all_assets.test_logs-0.1.0', - type: 'ingest_pipeline', - }, - { - id: 'logs-all_assets.test_logs-0.1.0-pipeline1', - type: 'ingest_pipeline', - }, - { - id: 'logs-all_assets.test_logs-0.1.0-pipeline2', - type: 'ingest_pipeline', - }, - { - id: 'logs-all_assets.test_logs', - type: 'index_template', - }, - { - id: 'metrics-all_assets.test_metrics', - type: 'index_template', - }, - { - id: 'all_assets.test-default-0.1.0', - type: 'transform', - }, - ], - es_index_patterns: { - test_logs: 'logs-all_assets.test_logs-*', - test_metrics: 'metrics-all_assets.test_metrics-*', - }, - name: 'all_assets', - version: '0.1.0', - internal: false, - removable: true, - install_version: '0.1.0', - install_status: 'installed', - install_started_at: res.attributes.install_started_at, - install_source: 'registry', - }); + expectAssetsInstalled({ + logsTemplateName, + metricsTemplateName, + pkgVersion, + pkgName, + es, + kibanaServer, }); }); describe('uninstalls all assets when uninstalling a package', async () => { skipIfNoDockerRegistry(providerContext); before(async () => { + if (!server.enabled) return; // these tests ensure that uninstall works properly so make sure that the package gets installed and uninstalled // and then we'll test that not artifacts are left behind. await installPackage(pkgKey); @@ -403,5 +240,228 @@ export default function (providerContext: FtrProviderContext) { expect(res.response.data.statusCode).equal(404); }); }); + + describe('reinstalls all assets', async () => { + skipIfNoDockerRegistry(providerContext); + before(async () => { + if (!server.enabled) return; + await installPackage(pkgKey); + // reinstall + await installPackage(pkgKey); + }); + after(async () => { + if (!server.enabled) return; + await uninstallPackage(pkgKey); + }); + expectAssetsInstalled({ + logsTemplateName, + metricsTemplateName, + pkgVersion, + pkgName, + es, + kibanaServer, + }); + }); }); } + +const expectAssetsInstalled = ({ + logsTemplateName, + metricsTemplateName, + pkgVersion, + pkgName, + es, + kibanaServer, +}: { + logsTemplateName: string; + metricsTemplateName: string; + pkgVersion: string; + pkgName: string; + es: any; + kibanaServer: any; +}) => { + it('should have installed the ILM policy', async function () { + const resPolicy = await es.transport.request({ + method: 'GET', + path: `/_ilm/policy/all_assets`, + }); + expect(resPolicy.statusCode).equal(200); + }); + it('should have installed the index templates', async function () { + const resLogsTemplate = await es.transport.request({ + method: 'GET', + path: `/_index_template/${logsTemplateName}`, + }); + expect(resLogsTemplate.statusCode).equal(200); + + const resMetricsTemplate = await es.transport.request({ + method: 'GET', + path: `/_index_template/${metricsTemplateName}`, + }); + expect(resMetricsTemplate.statusCode).equal(200); + }); + it('should have installed the pipelines', async function () { + const res = await es.transport.request({ + method: 'GET', + path: `/_ingest/pipeline/${logsTemplateName}-${pkgVersion}`, + }); + expect(res.statusCode).equal(200); + const resPipeline1 = await es.transport.request({ + method: 'GET', + path: `/_ingest/pipeline/${logsTemplateName}-${pkgVersion}-pipeline1`, + }); + expect(resPipeline1.statusCode).equal(200); + const resPipeline2 = await es.transport.request({ + method: 'GET', + path: `/_ingest/pipeline/${logsTemplateName}-${pkgVersion}-pipeline2`, + }); + expect(resPipeline2.statusCode).equal(200); + }); + it('should have installed the template components', async function () { + const res = await es.transport.request({ + method: 'GET', + path: `/_component_template/${logsTemplateName}-mappings`, + }); + expect(res.statusCode).equal(200); + const resSettings = await es.transport.request({ + method: 'GET', + path: `/_component_template/${logsTemplateName}-settings`, + }); + expect(resSettings.statusCode).equal(200); + }); + it('should have installed the transform components', async function () { + const res = await es.transport.request({ + method: 'GET', + path: `/_transform/${pkgName}.test-default-${pkgVersion}`, + }); + expect(res.statusCode).equal(200); + }); + it('should have created the index for the transform', async function () { + // the index is defined in the transform file + const res = await es.transport.request({ + method: 'GET', + path: `/logs-all_assets.test_log_current_default`, + }); + expect(res.statusCode).equal(200); + }); + it('should have installed the kibana assets', async function () { + const resIndexPatternLogs = await kibanaServer.savedObjects.get({ + type: 'index-pattern', + id: 'logs-*', + }); + expect(resIndexPatternLogs.id).equal('logs-*'); + const resIndexPatternMetrics = await kibanaServer.savedObjects.get({ + type: 'index-pattern', + id: 'metrics-*', + }); + expect(resIndexPatternMetrics.id).equal('metrics-*'); + const resDashboard = await kibanaServer.savedObjects.get({ + type: 'dashboard', + id: 'sample_dashboard', + }); + expect(resDashboard.id).equal('sample_dashboard'); + const resDashboard2 = await kibanaServer.savedObjects.get({ + type: 'dashboard', + id: 'sample_dashboard2', + }); + expect(resDashboard2.id).equal('sample_dashboard2'); + const resVis = await kibanaServer.savedObjects.get({ + type: 'visualization', + id: 'sample_visualization', + }); + expect(resVis.id).equal('sample_visualization'); + const resSearch = await kibanaServer.savedObjects.get({ + type: 'search', + id: 'sample_search', + }); + expect(resSearch.id).equal('sample_search'); + }); + it('should create an index pattern with the package fields', async () => { + const resIndexPatternLogs = await kibanaServer.savedObjects.get({ + type: 'index-pattern', + id: 'logs-*', + }); + const fields = JSON.parse(resIndexPatternLogs.attributes.fields); + const exists = fields.find((field: { name: string }) => field.name === 'logs_test_name'); + expect(exists).not.to.be(undefined); + const resIndexPatternMetrics = await kibanaServer.savedObjects.get({ + type: 'index-pattern', + id: 'metrics-*', + }); + const fieldsMetrics = JSON.parse(resIndexPatternMetrics.attributes.fields); + const metricsExists = fieldsMetrics.find( + (field: { name: string }) => field.name === 'metrics_test_name' + ); + expect(metricsExists).not.to.be(undefined); + }); + it('should have created the correct saved object', async function () { + const res = await kibanaServer.savedObjects.get({ + type: 'epm-packages', + id: 'all_assets', + }); + // during a reinstall the items can change + const sortedRes = { + ...res.attributes, + installed_kibana: sortBy(res.attributes.installed_kibana, (o: AssetReference) => o.type), + installed_es: sortBy(res.attributes.installed_es, (o: AssetReference) => o.type), + }; + expect(sortedRes).eql({ + installed_kibana: [ + { + id: 'sample_dashboard', + type: 'dashboard', + }, + { + id: 'sample_dashboard2', + type: 'dashboard', + }, + { + id: 'sample_search', + type: 'search', + }, + { + id: 'sample_visualization', + type: 'visualization', + }, + ], + installed_es: [ + { + id: 'logs-all_assets.test_logs', + type: 'index_template', + }, + { + id: 'metrics-all_assets.test_metrics', + type: 'index_template', + }, + { + id: 'logs-all_assets.test_logs-0.1.0', + type: 'ingest_pipeline', + }, + { + id: 'logs-all_assets.test_logs-0.1.0-pipeline1', + type: 'ingest_pipeline', + }, + { + id: 'logs-all_assets.test_logs-0.1.0-pipeline2', + type: 'ingest_pipeline', + }, + { + id: 'all_assets.test-default-0.1.0', + type: 'transform', + }, + ], + es_index_patterns: { + test_logs: 'logs-all_assets.test_logs-*', + test_metrics: 'metrics-all_assets.test_metrics-*', + }, + name: 'all_assets', + version: '0.1.0', + internal: false, + removable: true, + install_version: '0.1.0', + install_status: 'installed', + install_started_at: res.attributes.install_started_at, + install_source: 'registry', + }); + }); +}; From 0bf3d6efb033f79c06707b738882864cdb534a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20C=C3=B4t=C3=A9?= Date: Fri, 30 Oct 2020 08:59:45 -0400 Subject: [PATCH 65/80] Add a link to documentation in the alerts and actions management UI (#81909) * Add a link to documentation in the alerts and actions management UI * Update label * Remove usage of any on registries --- .../public/application/app.tsx | 7 ++- .../context/actions_connectors_context.tsx | 5 +- .../application/context/alerts_context.tsx | 7 ++- .../public/application/home.test.tsx | 45 ++++++++++++++++++ .../public/application/home.tsx | 46 ++++++++++++------- .../action_connector_form.test.tsx | 2 +- .../action_connector_form.tsx | 5 +- .../action_form.test.tsx | 2 +- .../action_connector_form/action_form.tsx | 4 +- .../action_type_menu.test.tsx | 2 +- .../connector_add_flyout.test.tsx | 2 +- .../connector_add_modal.test.tsx | 2 +- .../connector_add_modal.tsx | 10 ++-- .../connector_edit_flyout.test.tsx | 2 +- .../actions_connectors_list.test.tsx | 2 +- .../sections/alert_form/alert_add.test.tsx | 4 +- .../sections/alert_form/alert_edit.test.tsx | 4 +- .../sections/alert_form/alert_form.test.tsx | 12 ++--- .../components/alerts_list.test.tsx | 12 ++--- .../public/application/test_utils/index.ts | 41 +++++++++++++++++ 20 files changed, 158 insertions(+), 58 deletions(-) create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/home.test.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/test_utils/index.ts diff --git a/x-pack/plugins/triggers_actions_ui/public/application/app.tsx b/x-pack/plugins/triggers_actions_ui/public/application/app.tsx index c53dc0c105084..bb9fe65d6bbb8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/app.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/app.tsx @@ -18,8 +18,7 @@ import { } from 'kibana/public'; import { Section, routeToAlertDetails } from './constants'; import { AppContextProvider } from './app_context'; -import { ActionTypeModel, AlertTypeModel } from '../types'; -import { TypeRegistry } from './type_registry'; +import { ActionTypeRegistryContract, AlertTypeRegistryContract } from '../types'; import { ChartsPluginStart } from '../../../../../src/plugins/charts/public'; import { DataPublicPluginStart } from '../../../../../src/plugins/data/public'; import { PluginStartContract as AlertingStart } from '../../../alerts/public'; @@ -42,8 +41,8 @@ export interface AppDeps { uiSettings: IUiSettingsClient; setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void; capabilities: ApplicationStart['capabilities']; - actionTypeRegistry: TypeRegistry; - alertTypeRegistry: TypeRegistry; + actionTypeRegistry: ActionTypeRegistryContract; + alertTypeRegistry: AlertTypeRegistryContract; history: ScopedHistory; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx b/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx index 786fc12380f90..bb0606db2a9b3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx @@ -6,12 +6,11 @@ import React, { createContext, useContext } from 'react'; import { HttpSetup, ApplicationStart, DocLinksStart, ToastsSetup } from 'kibana/public'; -import { ActionTypeModel, ActionConnector } from '../../types'; -import { TypeRegistry } from '../type_registry'; +import { ActionTypeRegistryContract, ActionConnector } from '../../types'; export interface ActionsConnectorsContextValue { http: HttpSetup; - actionTypeRegistry: TypeRegistry; + actionTypeRegistry: ActionTypeRegistryContract; toastNotifications: ToastsSetup; capabilities: ApplicationStart['capabilities']; reloadConnectors?: () => Promise; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/context/alerts_context.tsx b/x-pack/plugins/triggers_actions_ui/public/application/context/alerts_context.tsx index b4cf13538d64d..a4293f94268ba 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/context/alerts_context.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/context/alerts_context.tsx @@ -18,14 +18,13 @@ import { DataPublicPluginStartUi, IndexPatternsContract, } from 'src/plugins/data/public'; -import { TypeRegistry } from '../type_registry'; -import { AlertTypeModel, ActionTypeModel } from '../../types'; +import { AlertTypeRegistryContract, ActionTypeRegistryContract } from '../../types'; export interface AlertsContextValue> { reloadAlerts?: () => Promise; http: HttpSetup; - alertTypeRegistry: TypeRegistry; - actionTypeRegistry: TypeRegistry; + alertTypeRegistry: AlertTypeRegistryContract; + actionTypeRegistry: ActionTypeRegistryContract; toastNotifications: ToastsStart; uiSettings?: IUiSettingsClient; charts?: ChartsPluginSetup; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/home.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/home.test.tsx new file mode 100644 index 0000000000000..d19dc3d303479 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/home.test.tsx @@ -0,0 +1,45 @@ +/* + * 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 { RouteComponentProps, Router } from 'react-router-dom'; +import { createMemoryHistory, createLocation } from 'history'; +import { mountWithIntl } from 'test_utils/enzyme_helpers'; + +import TriggersActionsUIHome, { MatchParams } from './home'; +import { AppContextProvider } from './app_context'; +import { getMockedAppDependencies } from './test_utils'; + +describe('home', () => { + it('renders the documentation link', async () => { + const deps = await getMockedAppDependencies(); + + const props: RouteComponentProps = { + history: createMemoryHistory(), + location: createLocation('/'), + match: { + isExact: true, + path: `/alerts`, + url: '', + params: { + section: 'alerts', + }, + }, + }; + const wrapper = mountWithIntl( + + + + + + ); + const documentationLink = wrapper.find('[data-test-subj="documentationLink"]'); + expect(documentationLink.exists()).toBeTruthy(); + expect(documentationLink.first().prop('href')).toEqual( + 'https://www.elastic.co/guide/en/kibana/mocked-test-branch/managing-alerts-and-actions.html' + ); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/home.tsx b/x-pack/plugins/triggers_actions_ui/public/application/home.tsx index 482b38ffc0d68..450f33d4f7e89 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/home.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/home.tsx @@ -10,13 +10,14 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiPageBody, EuiPageContent, - EuiPageContentHeader, - EuiPageContentHeaderSection, EuiSpacer, EuiTab, EuiTabs, EuiTitle, EuiText, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, } from '@elastic/eui'; import { Section, routeToConnectors, routeToAlerts } from './constants'; @@ -30,7 +31,7 @@ import { AlertsList } from './sections/alerts_list/components/alerts_list'; import { HealthCheck } from './components/health_check'; import { HealthContextProvider } from './context/health_context'; -interface MatchParams { +export interface MatchParams { section: Section; } @@ -80,27 +81,40 @@ export const TriggersActionsUIHome: React.FunctionComponent - - - + + +

-
- - -

+ + + -

-
-
-
+ + + + + + +

+ +

+
{tabs.map((tab) => ( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx index 60ec8004983a3..cf83062b5781e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx @@ -22,7 +22,7 @@ describe('action_connector_form', () => { ] = await mocks.getStartServices(); deps = { http: mocks.http, - actionTypeRegistry: actionTypeRegistry as any, + actionTypeRegistry, docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, capabilities, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx index f91bd7382b61c..3a1f9872a96a8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx @@ -24,10 +24,9 @@ import { ReducerAction } from './connector_reducer'; import { ActionConnector, IErrorObject, - ActionTypeModel, + ActionTypeRegistryContract, UserConfiguredActionConnector, } from '../../../types'; -import { TypeRegistry } from '../../type_registry'; import { hasSaveActionsCapability } from '../../lib/capabilities'; export function validateBaseProperties(actionObject: ActionConnector) { @@ -61,7 +60,7 @@ interface ActionConnectorProps< }; errors: IErrorObject; http: HttpSetup; - actionTypeRegistry: TypeRegistry; + actionTypeRegistry: ActionTypeRegistryContract; docLinks: DocLinksStart; capabilities: ApplicationStart['capabilities']; consumer?: string; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index 3e229c6a2333d..7c718e8248e41 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -178,7 +178,7 @@ describe('action_form', () => { }, }, setHasActionsWithBrokenConnector: jest.fn(), - actionTypeRegistry: actionTypeRegistry as any, + actionTypeRegistry, docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, }; actionTypeRegistry.list.mockReturnValue([ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index 61cf3f2d37925..51d3b0074ca54 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -34,6 +34,7 @@ import { loadActionTypes, loadAllActions as loadConnectors } from '../../lib/act import { IErrorObject, ActionTypeModel, + ActionTypeRegistryContract, AlertAction, ActionTypeIndex, ActionConnector, @@ -42,7 +43,6 @@ import { } from '../../../types'; import { SectionLoading } from '../../components/section_loading'; import { ConnectorAddModal } from './connector_add_modal'; -import { TypeRegistry } from '../../type_registry'; import { actionTypeCompare } from '../../lib/action_type_compare'; import { checkActionFormActionTypeEnabled } from '../../lib/check_action_type_enabled'; import { VIEW_LICENSE_OPTIONS_LINK } from '../../../common/constants'; @@ -55,7 +55,7 @@ interface ActionAccordionFormProps { setAlertProperty: (actions: AlertAction[]) => void; setActionParamsProperty: (key: string, value: any, index: number) => void; http: HttpSetup; - actionTypeRegistry: TypeRegistry; + actionTypeRegistry: ActionTypeRegistryContract; toastNotifications: ToastsSetup; docLinks: DocLinksStart; actionTypes?: ActionType[]; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx index a5e9cdc65cfa6..2fe068536f4a1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx @@ -33,7 +33,7 @@ describe('connector_add_flyout', () => { show: true, }, }, - actionTypeRegistry: actionTypeRegistry as any, + actionTypeRegistry, docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, }; }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.test.tsx index 0863465833c0b..b32a8ed4161d6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.test.tsx @@ -34,7 +34,7 @@ describe('connector_add_flyout', () => { show: true, }, }, - actionTypeRegistry: actionTypeRegistry as any, + actionTypeRegistry, docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, }; }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx index 3d621367fc40a..cba9eea3cf3f7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx @@ -32,7 +32,7 @@ describe('connector_add_modal', () => { delete: true, }, }, - actionTypeRegistry: actionTypeRegistry as any, + actionTypeRegistry, docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, }; }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx index d7ca91218d4dd..13ec8395aa557 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx @@ -19,12 +19,16 @@ import { EuiOverlayMask } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { HttpSetup, ToastsApi, ApplicationStart, DocLinksStart } from 'kibana/public'; import { ActionConnectorForm, validateBaseProperties } from './action_connector_form'; -import { ActionType, ActionConnector, IErrorObject, ActionTypeModel } from '../../../types'; import { connectorReducer } from './connector_reducer'; import { createActionConnector } from '../../lib/action_connector_api'; -import { TypeRegistry } from '../../type_registry'; import './connector_add_modal.scss'; import { hasSaveActionsCapability } from '../../lib/capabilities'; +import { + ActionType, + ActionConnector, + IErrorObject, + ActionTypeRegistryContract, +} from '../../../types'; interface ConnectorAddModalProps { actionType: ActionType; @@ -32,7 +36,7 @@ interface ConnectorAddModalProps { setAddModalVisibility: React.Dispatch>; postSaveEventHandler?: (savedAction: ActionConnector) => void; http: HttpSetup; - actionTypeRegistry: TypeRegistry; + actionTypeRegistry: ActionTypeRegistryContract; toastNotifications: Pick< ToastsApi, 'get$' | 'add' | 'remove' | 'addSuccess' | 'addWarning' | 'addDanger' | 'addError' diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx index 0c2f4df0ca52b..ac379e279f7f2 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx @@ -35,7 +35,7 @@ describe('connector_edit_flyout', () => { show: true, }, }, - actionTypeRegistry: actionTypeRegistry as any, + actionTypeRegistry, alertTypeRegistry: {} as any, docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx index c96e62df71ce4..33b839dc70b31 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx @@ -69,7 +69,7 @@ describe('actions_connectors_list component empty', () => { }, history: scopedHistoryMock.create(), setBreadcrumbs: jest.fn(), - actionTypeRegistry: actionTypeRegistry as any, + actionTypeRegistry, alertTypeRegistry: {} as any, }; actionTypeRegistry.has.mockReturnValue(true); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.test.tsx index 8ac80c4ad2880..0ac20626e1044 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.test.tsx @@ -84,8 +84,8 @@ describe('alert_add', () => { uiSettings: mocks.uiSettings, dataPlugin: dataPluginMock.createStartContract(), charts: chartPluginMock.createStartContract(), - actionTypeRegistry: actionTypeRegistry as any, - alertTypeRegistry: alertTypeRegistry as any, + actionTypeRegistry, + alertTypeRegistry, docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.test.tsx index 24eb7aabb9549..fe86e5da98765 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_edit.test.tsx @@ -36,8 +36,8 @@ describe('alert_edit', () => { toastNotifications: mockedCoreSetup.notifications.toasts, http: mockedCoreSetup.http, uiSettings: mockedCoreSetup.uiSettings, - actionTypeRegistry: actionTypeRegistry as any, - alertTypeRegistry: alertTypeRegistry as any, + actionTypeRegistry, + alertTypeRegistry, docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, capabilities, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.test.tsx index 6091519f5851e..cda791489d7f7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.test.tsx @@ -98,8 +98,8 @@ describe('alert_form', () => { toastNotifications: mocks.notifications.toasts, http: mocks.http, uiSettings: mocks.uiSettings, - actionTypeRegistry: actionTypeRegistry as any, - alertTypeRegistry: alertTypeRegistry as any, + actionTypeRegistry, + alertTypeRegistry, docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, capabilities, }; @@ -231,8 +231,8 @@ describe('alert_form', () => { toastNotifications: mocks.notifications.toasts, http: mocks.http, uiSettings: mocks.uiSettings, - actionTypeRegistry: actionTypeRegistry as any, - alertTypeRegistry: alertTypeRegistry as any, + actionTypeRegistry, + alertTypeRegistry, docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' }, capabilities, }; @@ -332,8 +332,8 @@ describe('alert_form', () => { toastNotifications: mockes.notifications.toasts, http: mockes.http, uiSettings: mockes.uiSettings, - actionTypeRegistry: actionTypeRegistry as any, - alertTypeRegistry: alertTypeRegistry as any, + actionTypeRegistry, + alertTypeRegistry, }; alertTypeRegistry.list.mockReturnValue([alertType]); alertTypeRegistry.get.mockReturnValue(alertType); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx index 86b9afd9565f8..e6e44d4d21bdf 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx @@ -109,8 +109,8 @@ describe('alerts_list component empty', () => { capabilities, history: scopedHistoryMock.create(), setBreadcrumbs: jest.fn(), - actionTypeRegistry: actionTypeRegistry as any, - alertTypeRegistry: alertTypeRegistry as any, + actionTypeRegistry, + alertTypeRegistry, }; wrapper = mountWithIntl( @@ -278,8 +278,8 @@ describe('alerts_list component with items', () => { capabilities, history: scopedHistoryMock.create(), setBreadcrumbs: jest.fn(), - actionTypeRegistry: actionTypeRegistry as any, - alertTypeRegistry: alertTypeRegistry as any, + actionTypeRegistry, + alertTypeRegistry, }; alertTypeRegistry.has.mockReturnValue(true); @@ -478,8 +478,8 @@ describe('alerts_list with show only capability', () => { capabilities, history: scopedHistoryMock.create(), setBreadcrumbs: jest.fn(), - actionTypeRegistry: actionTypeRegistry as any, - alertTypeRegistry: alertTypeRegistry as any, + actionTypeRegistry, + alertTypeRegistry, }; alertTypeRegistry.has.mockReturnValue(false); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/test_utils/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/test_utils/index.ts new file mode 100644 index 0000000000000..7b3872246ca50 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/test_utils/index.ts @@ -0,0 +1,41 @@ +/* + * 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 { chartPluginMock } from '../../../../../../src/plugins/charts/public/mocks'; +import { dataPluginMock } from '../../../../../../src/plugins/data/public/mocks'; +import { alertingPluginMock } from '../../../../alerts/public/mocks'; +import { actionTypeRegistryMock } from '../action_type_registry.mock'; +import { alertTypeRegistryMock } from '../alert_type_registry.mock'; +import { coreMock, scopedHistoryMock } from '../../../../../../src/core/public/mocks'; + +export async function getMockedAppDependencies() { + const coreSetupMock = coreMock.createSetup(); + const actionTypeRegistry = actionTypeRegistryMock.create(); + const alertTypeRegistry = alertTypeRegistryMock.create(); + const [ + { + chrome, + docLinks, + application: { capabilities, navigateToApp }, + }, + ] = await coreSetupMock.getStartServices(); + return { + chrome, + docLinks, + dataPlugin: dataPluginMock.createStartContract(), + charts: chartPluginMock.createStartContract(), + alerting: alertingPluginMock.createStartContract(), + toastNotifications: coreSetupMock.notifications.toasts, + http: coreSetupMock.http, + uiSettings: coreSetupMock.uiSettings, + navigateToApp, + capabilities, + history: scopedHistoryMock.create(), + setBreadcrumbs: jest.fn(), + actionTypeRegistry, + alertTypeRegistry, + }; +} From b10979c35e2a8e5b591d3e4211fea40191e2a5e3 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Fri, 30 Oct 2020 08:14:13 -0500 Subject: [PATCH 66/80] skip 'returns a single bucket if array has 1'. related #81460 --- .../server/lib/requests/__tests__/get_ping_histogram.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts index 0ae5887b31a7b..ac940ffb6676f 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts @@ -35,7 +35,7 @@ describe('getPingHistogram', () => { }, }; - it('returns a single bucket if array has 1', async () => { + it.skip('returns a single bucket if array has 1', async () => { expect.assertions(2); const mockEsClient = jest.fn(); mockEsClient.mockReturnValue({ From 415a063dd08a700fdf56d56ad73f1a78914021fb Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Fri, 30 Oct 2020 15:17:19 +0200 Subject: [PATCH 67/80] [Graph] Fix problem with duplicate ids (#82109) --- .../graph/public/components/field_manager/field_editor.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/graph/public/components/field_manager/field_editor.tsx b/x-pack/plugins/graph/public/components/field_manager/field_editor.tsx index f4006d6bf142b..ec5da1f44223c 100644 --- a/x-pack/plugins/graph/public/components/field_manager/field_editor.tsx +++ b/x-pack/plugins/graph/public/components/field_manager/field_editor.tsx @@ -116,7 +116,7 @@ export function FieldEditor({ return ( Date: Fri, 30 Oct 2020 08:38:08 -0500 Subject: [PATCH 68/80] TS project references for share plugin (#82051) --- src/plugins/share/tsconfig.json | 15 ++++++++++ tsconfig.json | 2 ++ tsconfig.refs.json | 1 + .../tsconfig.json | 1 + x-pack/test/tsconfig.json | 30 +++++++------------ x-pack/tsconfig.json | 1 + 6 files changed, 31 insertions(+), 19 deletions(-) create mode 100644 src/plugins/share/tsconfig.json diff --git a/src/plugins/share/tsconfig.json b/src/plugins/share/tsconfig.json new file mode 100644 index 0000000000000..a6318af602b4d --- /dev/null +++ b/src/plugins/share/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": ["common/**/*", "public/**/*", "server/**/*"], + "references": [ + { "path": "../../core/tsconfig.json" }, + { "path": "../../plugins/kibana_utils/tsconfig.json" } + ] +} diff --git a/tsconfig.json b/tsconfig.json index 30b38d0fc2dd3..2e4d5730d9320 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,7 @@ "src/plugins/kibana_usage_collection/**/*", "src/plugins/kibana_utils/**/*", "src/plugins/newsfeed/**/*", + "src/plugins/share/**/*", "src/plugins/telemetry_collection_manager/**/*", "src/plugins/telemetry/**/*", "src/plugins/url_forwarding/**/*", @@ -31,6 +32,7 @@ { "path": "./src/plugins/kibana_usage_collection/tsconfig.json" }, { "path": "./src/plugins/kibana_utils/tsconfig.json" }, { "path": "./src/plugins/newsfeed/tsconfig.json" }, + { "path": "./src/plugins/share/tsconfig.json" }, { "path": "./src/plugins/telemetry_collection_manager/tsconfig.json" }, { "path": "./src/plugins/telemetry/tsconfig.json" }, { "path": "./src/plugins/usage_collection/tsconfig.json" }, diff --git a/tsconfig.refs.json b/tsconfig.refs.json index c16e7a5e1b0f1..a37aa7b5b57fb 100644 --- a/tsconfig.refs.json +++ b/tsconfig.refs.json @@ -8,6 +8,7 @@ { "path": "./src/plugins/kibana_usage_collection/tsconfig.json" }, { "path": "./src/plugins/kibana_utils/tsconfig.json" }, { "path": "./src/plugins/newsfeed/tsconfig.json" }, + { "path": "./src/plugins/share/tsconfig.json" }, { "path": "./src/plugins/telemetry_collection_manager/tsconfig.json" }, { "path": "./src/plugins/telemetry/tsconfig.json" }, { "path": "./src/plugins/url_forwarding/tsconfig.json" }, diff --git a/x-pack/examples/ui_actions_enhanced_examples/tsconfig.json b/x-pack/examples/ui_actions_enhanced_examples/tsconfig.json index f8c1a6b53dac5..05e5f39d4d628 100644 --- a/x-pack/examples/ui_actions_enhanced_examples/tsconfig.json +++ b/x-pack/examples/ui_actions_enhanced_examples/tsconfig.json @@ -16,5 +16,6 @@ { "path": "../../../src/core/tsconfig.json" }, { "path": "../../../src/plugins/kibana_utils/tsconfig.json" }, { "path": "../../../src/plugins/kibana_react/tsconfig.json" }, + { "path": "../../../src/plugins/share/tsconfig.json" } ] } diff --git a/x-pack/test/tsconfig.json b/x-pack/test/tsconfig.json index 7bd38ea4afab7..e041292ebf3c9 100644 --- a/x-pack/test/tsconfig.json +++ b/x-pack/test/tsconfig.json @@ -3,30 +3,22 @@ "compilerOptions": { // overhead is too significant "incremental": false, - "types": [ - "mocha", - "node", - "flot" - ] + "types": ["mocha", "node", "flot"] }, - "include": [ - "**/*", - "../typings/**/*" - ], - "exclude": [ - "../typings/jest.d.ts" - ], + "include": ["**/*", "../typings/**/*"], + "exclude": ["../typings/jest.d.ts"], "references": [ { "path": "../../src/core/tsconfig.json" }, - { "path": "../../src/plugins/kibana_utils/tsconfig.json" }, { "path": "../../src/plugins/kibana_react/tsconfig.json" }, - { "path": "../plugins/licensing/tsconfig.json" }, - { "path": "../plugins/global_search/tsconfig.json" }, - { "path": "../../src/plugins/usage_collection/tsconfig.json" }, + { "path": "../../src/plugins/kibana_usage_collection/tsconfig.json" }, + { "path": "../../src/plugins/kibana_utils/tsconfig.json" }, + { "path": "../../src/plugins/newsfeed/tsconfig.json" }, + { "path": "../../src/plugins/share/tsconfig.json" }, { "path": "../../src/plugins/telemetry_collection_manager/tsconfig.json" }, { "path": "../../src/plugins/telemetry/tsconfig.json" }, - { "path": "../../src/plugins/kibana_usage_collection/tsconfig.json" }, - { "path": "../plugins/telemetry_collection_xpack/tsconfig.json" }, - { "path": "../../src/plugins/newsfeed/tsconfig.json" } + { "path": "../../src/plugins/usage_collection/tsconfig.json" }, + { "path": "../plugins/global_search/tsconfig.json" }, + { "path": "../plugins/licensing/tsconfig.json" }, + { "path": "../plugins/telemetry_collection_xpack/tsconfig.json" } ] } diff --git a/x-pack/tsconfig.json b/x-pack/tsconfig.json index 5c76a11315a56..804268fbf5dac 100644 --- a/x-pack/tsconfig.json +++ b/x-pack/tsconfig.json @@ -28,6 +28,7 @@ { "path": "../src/plugins/kibana_usage_collection/tsconfig.json" }, { "path": "../src/plugins/kibana_utils/tsconfig.json" }, { "path": "../src/plugins/newsfeed/tsconfig.json" }, + { "path": "../src/plugins/share/tsconfig.json" }, { "path": "../src/plugins/telemetry_collection_manager/tsconfig.json" }, { "path": "../src/plugins/telemetry/tsconfig.json" }, { "path": "../src/plugins/url_forwarding/tsconfig.json" }, From bf73bcf5d5773ea098f3f147a771a0b2aaf09713 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Fri, 30 Oct 2020 14:38:20 +0100 Subject: [PATCH 69/80] add tests for index pattern switching (#81987) --- .../apps/lens/persistent_context.ts | 7 ++++ .../test/functional/apps/lens/smokescreen.ts | 6 +++ .../es_archives/lens/basic/data.json.gz | Bin 4623 -> 4844 bytes .../test/functional/page_objects/lens_page.ts | 38 ++++++++++++++++++ 4 files changed, 51 insertions(+) diff --git a/x-pack/test/functional/apps/lens/persistent_context.ts b/x-pack/test/functional/apps/lens/persistent_context.ts index 8d536aac3f795..a115b720f6f2c 100644 --- a/x-pack/test/functional/apps/lens/persistent_context.ts +++ b/x-pack/test/functional/apps/lens/persistent_context.ts @@ -67,6 +67,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await filterBar.hasFilter('ip', '97.220.3.248', false, true); }); + it('keeps selected index pattern after refresh', async () => { + await PageObjects.lens.switchDataPanelIndexPattern('otherpattern'); + await browser.refresh(); + await PageObjects.header.waitUntilLoadingHasFinished(); + expect(await PageObjects.lens.getDataPanelIndexPattern()).to.equal('otherpattern'); + }); + it('keeps time range and pinned filters after refreshing directly after saving', async () => { // restore defaults so visualization becomes saveable await security.testUser.restoreDefaults(); diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index 6c4fa94a259e9..0ddafe581c21d 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -308,5 +308,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await PageObjects.lens.getDatatableHeaderText(1)).to.eql('Average of bytes'); expect(await PageObjects.lens.getDatatableCellText(0, 1)).to.eql('6,011.351'); }); + + it('should allow to change index pattern', async () => { + await PageObjects.lens.switchFirstLayerIndexPattern('otherpattern'); + expect(await PageObjects.lens.getFirstLayerIndexPattern()).to.equal('otherpattern'); + expect(await PageObjects.lens.isShowingNoResults()).to.equal(true); + }); }); } diff --git a/x-pack/test/functional/es_archives/lens/basic/data.json.gz b/x-pack/test/functional/es_archives/lens/basic/data.json.gz index ddf4a27289dffdaf1c605b0db01cfa9554a2b209..c9ae08fe6f6281d8f1e6066738dab36afd700f93 100644 GIT binary patch literal 4844 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 E0NnCaPXGV_ literal 4623 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 Date: Fri, 30 Oct 2020 14:12:11 +0000 Subject: [PATCH 70/80] [Security Solution] Modal for saving timeline (#81802) * init modal for saving timeline * disable auto save * unit test * fix type error * update translation * add unit tests * rename constant * break components into files * autoFocus and close modal on finish * rename constant * fix description label * update wording * review * fix dependency * remove classname * update wording Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../security_solution/common/constants.ts | 2 + .../components/flyout/header/index.tsx | 22 +- .../header/save_timeline_button.test.tsx | 76 +++++ .../timeline/header/save_timeline_button.tsx | 87 ++++++ .../header/title_and_description.test.tsx | 261 ++++++++++++++++++ .../timeline/header/title_and_description.tsx | 218 +++++++++++++++ .../timeline/header/translations.ts | 64 +++++ .../timeline/properties/helpers.test.tsx | 73 ++++- .../timeline/properties/helpers.tsx | 191 ++++++++++--- .../timeline/properties/index.test.tsx | 1 + .../components/timeline/properties/index.tsx | 1 + .../timeline/properties/properties_left.tsx | 4 + .../components/timeline/properties/styles.tsx | 26 +- .../timeline/properties/translations.ts | 9 +- .../properties/use_create_timeline.test.tsx | 40 +++ .../properties/use_create_timeline.tsx | 19 +- .../timelines/store/timeline/actions.ts | 24 +- .../public/timelines/store/timeline/epic.ts | 6 +- .../timelines/store/timeline/reducer.ts | 2 +- 19 files changed, 1064 insertions(+), 62 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/header/save_timeline_button.test.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/header/save_timeline_button.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/header/title_and_description.test.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/header/title_and_description.tsx diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index 2910f02a187f4..767a2616a4c7e 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -179,3 +179,5 @@ export const showAllOthersBucket: string[] = [ 'destination.ip', 'user.name', ]; + +export const ENABLE_NEW_TIMELINE = false; diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.tsx index a711e7a1d0442..0737db7a00788 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.tsx @@ -125,13 +125,27 @@ const makeMapStateToProps = () => { const mapDispatchToProps = (dispatch: Dispatch, { timelineId }: OwnProps) => ({ associateNote: (noteId: string) => dispatch(timelineActions.addNote({ id: timelineId, noteId })), - updateDescription: ({ id, description }: { id: string; description: string }) => - dispatch(timelineActions.updateDescription({ id, description })), + updateDescription: ({ + id, + description, + disableAutoSave, + }: { + id: string; + description: string; + disableAutoSave?: boolean; + }) => dispatch(timelineActions.updateDescription({ id, description, disableAutoSave })), updateIsFavorite: ({ id, isFavorite }: { id: string; isFavorite: boolean }) => dispatch(timelineActions.updateIsFavorite({ id, isFavorite })), updateNote: (note: Note) => dispatch(appActions.updateNote({ note })), - updateTitle: ({ id, title }: { id: string; title: string }) => - dispatch(timelineActions.updateTitle({ id, title })), + updateTitle: ({ + id, + title, + disableAutoSave, + }: { + id: string; + title: string; + disableAutoSave?: boolean; + }) => dispatch(timelineActions.updateTitle({ id, title, disableAutoSave })), toggleLock: ({ linkToId }: { linkToId: InputsModelId }) => dispatch(inputsActions.toggleTimelineLinkTo({ linkToId })), }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/header/save_timeline_button.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/save_timeline_button.test.tsx new file mode 100644 index 0000000000000..e9dc312ee8d19 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/save_timeline_button.test.tsx @@ -0,0 +1,76 @@ +/* + * 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 { shallow, mount } from 'enzyme'; + +import { SaveTimelineButton } from './save_timeline_button'; +import { act } from '@testing-library/react-hooks'; + +jest.mock('react-redux', () => { + const actual = jest.requireActual('react-redux'); + return { + ...actual, + useDispatch: jest.fn(), + }; +}); + +jest.mock('./title_and_description'); + +describe('SaveTimelineButton', () => { + const props = { + timelineId: 'timeline-1', + showOverlay: false, + toolTip: 'tooltip message', + toggleSaveTimeline: jest.fn(), + onSaveTimeline: jest.fn(), + updateTitle: jest.fn(), + updateDescription: jest.fn(), + }; + test('Show tooltip', () => { + const component = shallow(); + expect(component.find('[data-test-subj="save-timeline-btn-tooltip"]').exists()).toEqual(true); + }); + + test('Hide tooltip', () => { + const testProps = { + ...props, + showOverlay: true, + }; + const component = mount(); + component.find('[data-test-subj="save-timeline-button-icon"]').first().simulate('click'); + + act(() => { + expect(component.find('[data-test-subj="save-timeline-btn-tooltip"]').exists()).toEqual( + false + ); + }); + }); + + test('should show a button with pencil icon', () => { + const component = shallow(); + expect(component.find('[data-test-subj="save-timeline-button-icon"]').prop('iconType')).toEqual( + 'pencil' + ); + }); + + test('should not show a modal when showOverlay equals false', () => { + const component = shallow(); + expect(component.find('[data-test-subj="save-timeline-modal"]').exists()).toEqual(false); + }); + + test('should show a modal when showOverlay equals true', () => { + const testProps = { + ...props, + showOverlay: true, + }; + const component = mount(); + component.find('[data-test-subj="save-timeline-button-icon"]').first().simulate('click'); + act(() => { + expect(component.find('[data-test-subj="save-timeline-modal"]').exists()).toEqual(true); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/header/save_timeline_button.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/save_timeline_button.tsx new file mode 100644 index 0000000000000..476ef8d1dd5a1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/save_timeline_button.tsx @@ -0,0 +1,87 @@ +/* + * 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 { EuiButtonIcon, EuiOverlayMask, EuiModal, EuiToolTip } from '@elastic/eui'; + +import React, { useCallback, useMemo, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import { timelineActions } from '../../../store/timeline'; +import { NOTES_PANEL_WIDTH } from '../properties/notes_size'; + +import { TimelineTitleAndDescription } from './title_and_description'; +import { EDIT } from './translations'; + +export interface SaveTimelineComponentProps { + timelineId: string; + toolTip?: string; +} + +export const SaveTimelineButton = React.memo( + ({ timelineId, toolTip }) => { + const [showSaveTimelineOverlay, setShowSaveTimelineOverlay] = useState(false); + const onToggleSaveTimeline = useCallback(() => { + setShowSaveTimelineOverlay((prevShowSaveTimelineOverlay) => !prevShowSaveTimelineOverlay); + }, [setShowSaveTimelineOverlay]); + + const dispatch = useDispatch(); + const updateTitle = useCallback( + ({ id, title, disableAutoSave }: { id: string; title: string; disableAutoSave?: boolean }) => + dispatch(timelineActions.updateTitle({ id, title, disableAutoSave })), + [dispatch] + ); + + const updateDescription = useCallback( + ({ + id, + description, + disableAutoSave, + }: { + id: string; + description: string; + disableAutoSave?: boolean; + }) => dispatch(timelineActions.updateDescription({ id, description, disableAutoSave })), + [dispatch] + ); + + const saveTimelineButtonIcon = useMemo( + () => ( + + ), + [onToggleSaveTimeline] + ); + + return showSaveTimelineOverlay ? ( + <> + {saveTimelineButtonIcon} + + + + + + + ) : ( + + {saveTimelineButtonIcon} + + ); + } +); + +SaveTimelineButton.displayName = 'SaveTimelineButton'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/header/title_and_description.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/title_and_description.test.tsx new file mode 100644 index 0000000000000..bcc90a25d5789 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/title_and_description.test.tsx @@ -0,0 +1,261 @@ +/* + * 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 { shallow } from 'enzyme'; +import { TimelineTitleAndDescription } from './title_and_description'; +import { useShallowEqualSelector } from '../../../../common/hooks/use_selector'; +import { useCreateTimelineButton } from '../properties/use_create_timeline'; +import { TimelineType } from '../../../../../common/types/timeline'; +import * as i18n from './translations'; + +jest.mock('../../../../common/hooks/use_selector', () => ({ + useShallowEqualSelector: jest.fn(), +})); + +jest.mock('../../../../timelines/store/timeline', () => ({ + timelineSelectors: { + selectTimeline: jest.fn(), + }, +})); + +jest.mock('../properties/use_create_timeline', () => ({ + useCreateTimelineButton: jest.fn(), +})); + +jest.mock('react-redux', () => { + const actual = jest.requireActual('react-redux'); + return { + ...actual, + useDispatch: jest.fn(), + }; +}); + +describe('TimelineTitleAndDescription', () => { + describe('save timeline', () => { + const props = { + timelineId: 'timeline-1', + toggleSaveTimeline: jest.fn(), + onSaveTimeline: jest.fn(), + updateTitle: jest.fn(), + updateDescription: jest.fn(), + }; + + const mockGetButton = jest.fn().mockReturnValue(
); + + beforeEach(() => { + (useShallowEqualSelector as jest.Mock).mockReturnValue({ + description: '', + isSaving: true, + savedObjectId: null, + title: 'my timeline', + timelineType: TimelineType.default, + }); + (useCreateTimelineButton as jest.Mock).mockReturnValue({ + getButton: mockGetButton, + }); + }); + + afterEach(() => { + (useShallowEqualSelector as jest.Mock).mockReset(); + (useCreateTimelineButton as jest.Mock).mockReset(); + mockGetButton.mockClear(); + }); + + test('show proress bar while saving', () => { + const component = shallow(); + expect(component.find('[data-test-subj="progress-bar"]').exists()).toEqual(true); + }); + + test('Show correct header for save timeline modal', () => { + const component = shallow(); + expect(component.find('[data-test-subj="modal-header"]').prop('children')).toEqual( + i18n.SAVE_TIMELINE + ); + }); + + test('Show correct header for save timeline template modal', () => { + (useShallowEqualSelector as jest.Mock).mockReturnValue({ + description: '', + isSaving: true, + savedObjectId: null, + title: 'my timeline', + timelineType: TimelineType.template, + }); + const component = shallow(); + expect(component.find('[data-test-subj="modal-header"]').prop('children')).toEqual( + i18n.SAVE_TIMELINE_TEMPLATE + ); + }); + + test('Show name field', () => { + const component = shallow(); + expect(component.find('[data-test-subj="save-timeline-name"]').exists()).toEqual(true); + }); + + test('Show description field', () => { + const component = shallow(); + expect(component.find('[data-test-subj="save-timeline-description"]').exists()).toEqual(true); + }); + + test('Show close button', () => { + const component = shallow(); + expect(component.find('[data-test-subj="close-button"]').exists()).toEqual(true); + }); + + test('Show saveButton', () => { + const component = shallow(); + expect(component.find('[data-test-subj="save-button"]').exists()).toEqual(true); + }); + }); + + describe('update timeline', () => { + const props = { + timelineId: 'timeline-1', + toggleSaveTimeline: jest.fn(), + onSaveTimeline: jest.fn(), + updateTitle: jest.fn(), + updateDescription: jest.fn(), + }; + + const mockGetButton = jest.fn().mockReturnValue(
); + + beforeEach(() => { + (useShallowEqualSelector as jest.Mock).mockReturnValue({ + description: 'xxxx', + isSaving: true, + savedObjectId: '1234', + title: 'my timeline', + timelineType: TimelineType.default, + }); + (useCreateTimelineButton as jest.Mock).mockReturnValue({ + getButton: mockGetButton, + }); + }); + + afterEach(() => { + (useShallowEqualSelector as jest.Mock).mockReset(); + (useCreateTimelineButton as jest.Mock).mockReset(); + mockGetButton.mockClear(); + }); + + test('show proress bar while saving', () => { + const component = shallow(); + expect(component.find('[data-test-subj="progress-bar"]').exists()).toEqual(true); + }); + + test('Show correct header for save timeline modal', () => { + const component = shallow(); + expect(component.find('[data-test-subj="modal-header"]').prop('children')).toEqual( + i18n.NAME_TIMELINE + ); + }); + + test('Show correct header for save timeline template modal', () => { + (useShallowEqualSelector as jest.Mock).mockReturnValue({ + description: 'xxxx', + isSaving: true, + savedObjectId: '1234', + title: 'my timeline', + timelineType: TimelineType.template, + }); + const component = shallow(); + expect(component.find('[data-test-subj="modal-header"]').prop('children')).toEqual( + i18n.NAME_TIMELINE_TEMPLATE + ); + }); + + test('Show name field', () => { + const component = shallow(); + expect(component.find('[data-test-subj="save-timeline-name"]').exists()).toEqual(true); + }); + + test('Show description field', () => { + const component = shallow(); + expect(component.find('[data-test-subj="save-timeline-description"]').exists()).toEqual(true); + }); + + test('Show saveButton', () => { + const component = shallow(); + expect(component.find('[data-test-subj="save-button"]').exists()).toEqual(true); + }); + }); + + describe('showWarning', () => { + const props = { + timelineId: 'timeline-1', + toggleSaveTimeline: jest.fn(), + onSaveTimeline: jest.fn(), + updateTitle: jest.fn(), + updateDescription: jest.fn(), + showWarning: true, + }; + + const mockGetButton = jest.fn().mockReturnValue(
); + + beforeEach(() => { + (useShallowEqualSelector as jest.Mock).mockReturnValue({ + description: '', + isSaving: true, + savedObjectId: null, + title: 'my timeline', + timelineType: TimelineType.default, + showWarnging: true, + }); + (useCreateTimelineButton as jest.Mock).mockReturnValue({ + getButton: mockGetButton, + }); + }); + + afterEach(() => { + (useShallowEqualSelector as jest.Mock).mockReset(); + (useCreateTimelineButton as jest.Mock).mockReset(); + mockGetButton.mockClear(); + }); + + test('Show EuiCallOut', () => { + const component = shallow(); + expect(component.find('[data-test-subj="save-timeline-callout"]').exists()).toEqual(true); + }); + + test('Show discardTimelineButton', () => { + const component = shallow(); + expect(component.find('[data-test-subj="mock-discard-button"]').exists()).toEqual(true); + }); + + test('get discardTimelineButton with correct props', () => { + shallow(); + expect(mockGetButton).toBeCalledWith({ + title: i18n.DISCARD_TIMELINE, + outline: true, + iconType: '', + fill: false, + }); + }); + + test('get discardTimelineTemplateButton with correct props', () => { + (useShallowEqualSelector as jest.Mock).mockReturnValue({ + description: 'xxxx', + isSaving: true, + savedObjectId: null, + title: 'my timeline', + timelineType: TimelineType.template, + }); + shallow(); + expect(mockGetButton).toBeCalledWith({ + title: i18n.DISCARD_TIMELINE_TEMPLATE, + outline: true, + iconType: '', + fill: false, + }); + }); + + test('Show saveButton', () => { + const component = shallow(); + expect(component.find('[data-test-subj="save-button"]').exists()).toEqual(true); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/header/title_and_description.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/title_and_description.tsx new file mode 100644 index 0000000000000..3597b26e2663a --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/title_and_description.tsx @@ -0,0 +1,218 @@ +/* + * 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 { + EuiButton, + EuiFlexGroup, + EuiFormRow, + EuiFlexItem, + EuiModalBody, + EuiModalHeader, + EuiSpacer, + EuiProgress, + EuiCallOut, +} from '@elastic/eui'; +import React, { useCallback, useEffect, useMemo, useRef } from 'react'; +import { useDispatch } from 'react-redux'; +import styled from 'styled-components'; +import { TimelineType } from '../../../../../common/types/timeline'; +import { useShallowEqualSelector } from '../../../../common/hooks/use_selector'; +import { timelineActions, timelineSelectors } from '../../../../timelines/store/timeline'; +import { TimelineInput } from '../../../store/timeline/actions'; +import { Description, Name, UpdateTitle, UpdateDescription } from '../properties/helpers'; +import { TIMELINE_TITLE, DESCRIPTION, OPTIONAL } from '../properties/translations'; +import { useCreateTimelineButton } from '../properties/use_create_timeline'; +import * as i18n from './translations'; + +interface TimelineTitleAndDescriptionProps { + showWarning?: boolean; + timelineId: string; + toggleSaveTimeline: () => void; + updateTitle: UpdateTitle; + updateDescription: UpdateDescription; +} + +const Wrapper = styled(EuiModalBody)` + .euiFormRow { + max-width: none; + } + + .euiFormControlLayout { + max-width: none; + } + + .euiFieldText { + max-width: none; + } +`; + +Wrapper.displayName = 'Wrapper'; + +const usePrevious = (value: unknown) => { + const ref = useRef(); + useEffect(() => { + ref.current = value; + }); + return ref.current; +}; + +// when showWarning equals to true, +// the modal is used as a reminder for users to save / discard +// the unsaved timeline / template +export const TimelineTitleAndDescription = React.memo( + ({ timelineId, toggleSaveTimeline, updateTitle, updateDescription, showWarning }) => { + const timeline = useShallowEqualSelector((state) => + timelineSelectors.selectTimeline(state, timelineId) + ); + + const { description, isSaving, savedObjectId, title, timelineType } = timeline; + + const prevIsSaving = usePrevious(isSaving); + const dispatch = useDispatch(); + const onSaveTimeline = useCallback( + (args: TimelineInput) => dispatch(timelineActions.saveTimeline(args)), + [dispatch] + ); + + const handleClick = useCallback(() => { + onSaveTimeline({ + ...timeline, + id: timelineId, + }); + }, [onSaveTimeline, timeline, timelineId]); + + const { getButton } = useCreateTimelineButton({ timelineId, timelineType }); + + const discardTimelineButton = useMemo( + () => + getButton({ + title: + timelineType === TimelineType.template + ? i18n.DISCARD_TIMELINE_TEMPLATE + : i18n.DISCARD_TIMELINE, + outline: true, + iconType: '', + fill: false, + }), + [getButton, timelineType] + ); + + useEffect(() => { + if (!isSaving && prevIsSaving) { + toggleSaveTimeline(); + } + }, [isSaving, prevIsSaving, toggleSaveTimeline]); + + const modalHeader = + savedObjectId == null + ? timelineType === TimelineType.template + ? i18n.SAVE_TIMELINE_TEMPLATE + : i18n.SAVE_TIMELINE + : timelineType === TimelineType.template + ? i18n.NAME_TIMELINE_TEMPLATE + : i18n.NAME_TIMELINE; + + const saveButtonTitle = + savedObjectId == null && showWarning + ? timelineType === TimelineType.template + ? i18n.SAVE_TIMELINE_TEMPLATE + : i18n.SAVE_TIMELINE + : i18n.SAVE; + + const calloutMessage = useMemo(() => i18n.UNSAVED_TIMELINE_WARNING(timelineType), [ + timelineType, + ]); + + const descriptionLabel = savedObjectId == null ? `${DESCRIPTION} (${OPTIONAL})` : DESCRIPTION; + + return ( + <> + {isSaving && ( + + )} + {modalHeader} + + + {showWarning && ( + + + + + )} + + + + + + + + + + + + + + + + {savedObjectId == null && showWarning ? ( + discardTimelineButton + ) : ( + + {i18n.CLOSE_MODAL} + + )} + + + + {saveButtonTitle} + + + + + + + ); + } +); + +TimelineTitleAndDescription.displayName = 'TimelineTitleAndDescription'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/header/translations.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/translations.ts index 89ad11d75cae1..80aa719a3469d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/header/translations.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/translations.ts @@ -5,6 +5,7 @@ */ import { i18n } from '@kbn/i18n'; +import { TimelineType, TimelineTypeLiteral } from '../../../../../common/types/timeline'; export const CALL_OUT_UNAUTHORIZED_MSG = i18n.translate( 'xpack.securitySolution.timeline.callOut.unauthorized.message.description', @@ -21,3 +22,66 @@ export const CALL_OUT_IMMUTABLE = i18n.translate( 'This prebuilt timeline template cannot be modified. To make changes, please duplicate this template and make modifications to the duplicate template.', } ); + +export const EDIT = i18n.translate('xpack.securitySolution.timeline.saveTimeline.modal.button', { + defaultMessage: 'edit', +}); + +export const SAVE_TIMELINE = i18n.translate( + 'xpack.securitySolution.timeline.saveTimeline.modal.header', + { + defaultMessage: 'Save Timeline', + } +); + +export const SAVE_TIMELINE_TEMPLATE = i18n.translate( + 'xpack.securitySolution.timeline.saveTimelineTemplate.modal.header', + { + defaultMessage: 'Save Timeline Template', + } +); + +export const SAVE = i18n.translate('xpack.securitySolution.timeline.nameTimeline.save.title', { + defaultMessage: 'Save', +}); + +export const NAME_TIMELINE = i18n.translate( + 'xpack.securitySolution.timeline.nameTimeline.modal.header', + { + defaultMessage: 'Name Timeline', + } +); + +export const NAME_TIMELINE_TEMPLATE = i18n.translate( + 'xpack.securitySolution.timeline.nameTimelineTemplate.modal.header', + { + defaultMessage: 'Name Timeline Template', + } +); + +export const DISCARD_TIMELINE = i18n.translate( + 'xpack.securitySolution.timeline.saveTimeline.modal.discard.title', + { + defaultMessage: 'Discard Timeline', + } +); + +export const DISCARD_TIMELINE_TEMPLATE = i18n.translate( + 'xpack.securitySolution.timeline.saveTimelineTemplate.modal.discard.title', + { + defaultMessage: 'Discard Timeline Template', + } +); + +export const CLOSE_MODAL = i18n.translate( + 'xpack.securitySolution.timeline.saveTimeline.modal.close.title', + { + defaultMessage: 'Close', + } +); + +export const UNSAVED_TIMELINE_WARNING = (timelineType: TimelineTypeLiteral) => + i18n.translate('xpack.securitySolution.timeline.saveTimeline.modal.warning.title', { + values: { timeline: timelineType === TimelineType.template ? 'timeline template' : 'timeline' }, + defaultMessage: 'You have an unsaved {timeline}. Do you wish to save it?', + }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.test.tsx index 887c2e1e825f8..dd0695e795397 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.test.tsx @@ -5,8 +5,10 @@ */ import React from 'react'; import { mount, shallow } from 'enzyme'; -import { NewTimeline, NewTimelineProps } from './helpers'; +import { Description, Name, NewTimeline, NewTimelineProps } from './helpers'; import { useCreateTimelineButton } from './use_create_timeline'; +import * as i18n from './translations'; +import { TimelineType } from '../../../../../common/types/timeline'; jest.mock('./use_create_timeline', () => ({ useCreateTimelineButton: jest.fn(), @@ -83,3 +85,72 @@ describe('NewTimeline', () => { }); }); }); + +describe('Description', () => { + const props = { + description: 'xxx', + timelineId: 'timeline-1', + updateDescription: jest.fn(), + }; + + test('should render tooltip', () => { + const component = shallow(); + expect( + component.find('[data-test-subj="timeline-description-tool-tip"]').prop('content') + ).toEqual(i18n.DESCRIPTION_TOOL_TIP); + }); + + test('should not render textarea if isTextArea is false', () => { + const component = shallow(); + expect(component.find('[data-test-subj="timeline-description-textarea"]').exists()).toEqual( + false + ); + + expect(component.find('[data-test-subj="timeline-description"]').exists()).toEqual(true); + }); + + test('should render textarea if isTextArea is true', () => { + const testProps = { + ...props, + isTextArea: true, + }; + const component = shallow(); + expect(component.find('[data-test-subj="timeline-description-textarea"]').exists()).toEqual( + true + ); + }); +}); + +describe('Name', () => { + const props = { + timelineId: 'timeline-1', + timelineType: TimelineType.default, + title: 'xxx', + updateTitle: jest.fn(), + }; + + test('should render tooltip', () => { + const component = shallow(); + expect(component.find('[data-test-subj="timeline-title-tool-tip"]').prop('content')).toEqual( + i18n.TITLE + ); + }); + + test('should render placeholder by timelineType - timeline', () => { + const component = shallow(); + expect(component.find('[data-test-subj="timeline-title"]').prop('placeholder')).toEqual( + i18n.UNTITLED_TIMELINE + ); + }); + + test('should render placeholder by timelineType - timeline template', () => { + const testProps = { + ...props, + timelineType: TimelineType.template, + }; + const component = shallow(); + expect(component.find('[data-test-subj="timeline-title"]').prop('placeholder')).toEqual( + i18n.UNTITLED_TEMPLATE + ); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.tsx index a28f4240d3a2f..25039dbc9529a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/helpers.tsx @@ -16,8 +16,9 @@ import { EuiModal, EuiOverlayMask, EuiToolTip, + EuiTextArea, } from '@elastic/eui'; -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import uuid from 'uuid'; import styled from 'styled-components'; import { useDispatch } from 'react-redux'; @@ -41,14 +42,22 @@ import { Notes } from '../../notes'; import { AssociateNote, UpdateNote } from '../../notes/helpers'; import { NOTES_PANEL_WIDTH } from './notes_size'; -import { ButtonContainer, DescriptionContainer, LabelText, NameField, StyledStar } from './styles'; +import { + ButtonContainer, + DescriptionContainer, + LabelText, + NameField, + NameWrapper, + StyledStar, +} from './styles'; import * as i18n from './translations'; -import { setInsertTimeline, showTimeline } from '../../../store/timeline/actions'; +import { setInsertTimeline, showTimeline, TimelineInput } from '../../../store/timeline/actions'; import { useCreateTimelineButton } from './use_create_timeline'; export const historyToolTip = 'The chronological history of actions related to this timeline'; export const streamLiveToolTip = 'Update the Timeline as new data arrives'; export const newTimelineToolTip = 'Create a new timeline'; +export const TIMELINE_TITLE_CLASSNAME = 'timeline-title'; const NotesCountBadge = (styled(EuiBadge)` margin-left: 5px; @@ -66,8 +75,25 @@ type CreateTimeline = ({ timelineType?: TimelineTypeLiteral; }) => void; type UpdateIsFavorite = ({ id, isFavorite }: { id: string; isFavorite: boolean }) => void; -type UpdateTitle = ({ id, title }: { id: string; title: string }) => void; -type UpdateDescription = ({ id, description }: { id: string; description: string }) => void; +export type UpdateTitle = ({ + id, + title, + disableAutoSave, +}: { + id: string; + title: string; + disableAutoSave?: boolean; +}) => void; +export type UpdateDescription = ({ + id, + description, + disableAutoSave, +}: { + id: string; + description: string; + disableAutoSave?: boolean; +}) => void; +export type SaveTimeline = (args: TimelineInput) => void; export const StarIcon = React.memo<{ isFavorite: boolean; @@ -104,55 +130,146 @@ interface DescriptionProps { description: string; timelineId: string; updateDescription: UpdateDescription; + isTextArea?: boolean; + disableAutoSave?: boolean; + disableTooltip?: boolean; + disabled?: boolean; + marginRight?: number; } export const Description = React.memo( - ({ description, timelineId, updateDescription }) => ( - - - updateDescription({ id: timelineId, description: e.target.value })} - placeholder={i18n.DESCRIPTION} - spellCheck={true} - value={description} - /> + ({ + description, + timelineId, + updateDescription, + isTextArea = false, + disableAutoSave = false, + disableTooltip = false, + disabled = false, + marginRight, + }) => { + const onDescriptionChanged = useCallback( + (e) => { + updateDescription({ id: timelineId, description: e.target.value, disableAutoSave }); + }, + [updateDescription, disableAutoSave, timelineId] + ); + + const inputField = useMemo( + () => + isTextArea ? ( + + ) : ( + + ), + [description, isTextArea, onDescriptionChanged, disabled] + ); + return ( + + {disableTooltip ? ( + inputField + ) : ( + + {inputField} + + )} - - ) + ); + } ); Description.displayName = 'Description'; interface NameProps { + autoFocus?: boolean; + disableAutoSave?: boolean; + disableTooltip?: boolean; + disabled?: boolean; timelineId: string; timelineType: TimelineType; title: string; updateTitle: UpdateTitle; + width?: string; + marginRight?: number; } -export const Name = React.memo(({ timelineId, timelineType, title, updateTitle }) => { - const handleChange = useCallback((e) => updateTitle({ id: timelineId, title: e.target.value }), [ +export const Name = React.memo( + ({ + autoFocus = false, + disableAutoSave = false, + disableTooltip = false, + disabled = false, timelineId, + timelineType, + title, updateTitle, - ]); + width, + marginRight, + }) => { + const timelineNameRef = useRef(null); + + const handleChange = useCallback( + (e) => updateTitle({ id: timelineId, title: e.target.value, disableAutoSave }), + [timelineId, updateTitle, disableAutoSave] + ); - return ( - - - - ); -}); + useEffect(() => { + if (autoFocus && timelineNameRef && timelineNameRef.current) { + timelineNameRef.current.focus(); + } + }, [autoFocus]); + + const nameField = useMemo( + () => ( + + ), + [handleChange, marginRight, timelineType, title, width, disabled] + ); + + return ( + + {disableTooltip ? ( + nameField + ) : ( + + {nameField} + + )} + + ); + } +); Name.displayName = 'Name'; interface NewCaseProps { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/index.test.tsx index 19344a7fd7c9b..cdedca23e85af 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/index.test.tsx @@ -92,6 +92,7 @@ const defaultProps = { description: '', getNotesByIds: jest.fn(), noteIds: [], + saveTimeline: jest.fn(), status: TimelineStatus.active, timelineId: 'abc', toggleLock: jest.fn(), diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/index.tsx index 9eea95a0a9b1a..9df2b585449a0 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/index.tsx @@ -92,6 +92,7 @@ export const Properties = React.memo( setShowTimelineModal(true); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + const { Modal: AllCasesModal, onOpenModal: onOpenCaseModal } = useAllCasesModal({ timelineId }); const datePickerWidth = useMemo( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/properties_left.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/properties_left.tsx index a3cd8802c36bc..6b181a5af7bf3 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/properties_left.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/properties_left.tsx @@ -16,6 +16,8 @@ import { SuperDatePicker } from '../../../../common/components/super_date_picker import { TimelineTypeLiteral, TimelineStatusLiteral } from '../../../../../common/types/timeline'; import * as i18n from './translations'; +import { SaveTimelineButton } from '../header/save_timeline_button'; +import { ENABLE_NEW_TIMELINE } from '../../../../../common/constants'; type UpdateIsFavorite = ({ id, isFavorite }: { id: string; isFavorite: boolean }) => void; type UpdateTitle = ({ id, title }: { id: string; title: string }) => void; @@ -122,6 +124,8 @@ export const PropertiesLeft = React.memo( ) : null} + {ENABLE_NEW_TIMELINE && } + {showNotesFromWidth ? ( (({ width }) => ({ `; DatePicker.displayName = 'DatePicker'; -export const NameField = styled(EuiFieldText)` - width: 150px; - margin-right: 5px; +export const NameField = styled(({ width, marginRight, ...rest }) => )` + width: ${({ width = '150px' }) => width}; + margin-right: ${({ marginRight = 10 }) => marginRight} px; + + .euiToolTipAnchor { + display: block; + } `; NameField.displayName = 'NameField'; -export const DescriptionContainer = styled.div` +export const NameWrapper = styled.div` + .euiToolTipAnchor { + display: block; + } +`; +NameWrapper.displayName = 'NameWrapper'; + +export const DescriptionContainer = styled.div<{ marginRight?: number }>` animation: ${fadeInEffect} 0.3s; - margin-right: 5px; + margin-right: ${({ marginRight = 5 }) => marginRight}px; min-width: 150px; + + .euiToolTipAnchor { + display: block; + } `; DescriptionContainer.displayName = 'DescriptionContainer'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/translations.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/translations.ts index 1fc3b7b00f847..78d01b2d98ab3 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/translations.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/translations.ts @@ -34,7 +34,7 @@ export const NOT_A_FAVORITE = i18n.translate( export const TIMELINE_TITLE = i18n.translate( 'xpack.securitySolution.timeline.properties.timelineTitleAriaLabel', { - defaultMessage: 'Timeline title', + defaultMessage: 'Title', } ); @@ -194,3 +194,10 @@ export const UNLOCK_SYNC_MAIN_DATE_PICKER_ARIA = i18n.translate( defaultMessage: 'Unlock date picker to global date picker', } ); + +export const OPTIONAL = i18n.translate( + 'xpack.securitySolution.timeline.properties.timelineDescriptionOptional', + { + defaultMessage: 'Optional', + } +); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/use_create_timeline.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/use_create_timeline.test.tsx index c21592bed12e0..10b505da5c76f 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/use_create_timeline.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/use_create_timeline.test.tsx @@ -63,6 +63,46 @@ describe('useCreateTimelineButton', () => { }); }); + test('getButton renders correct iconType - EuiButton', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook( + () => useCreateTimelineButton({ timelineId: mockId, timelineType }), + { wrapper: wrapperContainer } + ); + await waitForNextUpdate(); + + const button = result.current.getButton({ + outline: true, + title: 'mock title', + iconType: 'pencil', + }); + const wrapper = shallow(button); + expect(wrapper.find('[data-test-subj="timeline-new-with-border"]').prop('iconType')).toEqual( + 'pencil' + ); + }); + }); + + test('getButton renders correct filling - EuiButton', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook( + () => useCreateTimelineButton({ timelineId: mockId, timelineType }), + { wrapper: wrapperContainer } + ); + await waitForNextUpdate(); + + const button = result.current.getButton({ + outline: true, + title: 'mock title', + fill: false, + }); + const wrapper = shallow(button); + expect(wrapper.find('[data-test-subj="timeline-new-with-border"]').prop('fill')).toEqual( + false + ); + }); + }); + test('getButton renders correct outline - EuiButtonEmpty', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/use_create_timeline.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/use_create_timeline.tsx index 28dd865c763ae..b4d168cc980b6 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/use_create_timeline.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/use_create_timeline.tsx @@ -93,15 +93,28 @@ export const useCreateTimelineButton = ({ }, [createTimeline, timelineId, timelineType, closeGearMenu]); const getButton = useCallback( - ({ outline, title }: { outline?: boolean; title?: string }) => { + ({ + outline, + title, + iconType = 'plusInCircle', + fill = true, + isDisabled = false, + }: { + outline?: boolean; + title?: string; + iconType?: string; + fill?: boolean; + isDisabled?: boolean; + }) => { const buttonProps = { - iconType: 'plusInCircle', + iconType, onClick: handleButtonClick, + fill, }; const dataTestSubjPrefix = timelineType === TimelineType.template ? `template-timeline-new` : `timeline-new`; return outline ? ( - + {title} ) : ( diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts index 472e82426468e..c066de8af9f20 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts @@ -56,7 +56,7 @@ export const applyDeltaToColumnWidth = actionCreator<{ delta: number; }>('APPLY_DELTA_TO_COLUMN_WIDTH'); -export const createTimeline = actionCreator<{ +export interface TimelineInput { id: string; dataProviders?: DataProvider[]; dateRange?: { @@ -76,9 +76,13 @@ export const createTimeline = actionCreator<{ sort?: Sort; showCheckboxes?: boolean; timelineType?: TimelineTypeLiteral; - templateTimelineId?: string; - templateTimelineVersion?: number; -}>('CREATE_TIMELINE'); + templateTimelineId?: string | null; + templateTimelineVersion?: number | null; +} + +export const saveTimeline = actionCreator('SAVE_TIMELINE'); + +export const createTimeline = actionCreator('CREATE_TIMELINE'); export const pinEvent = actionCreator<{ id: string; eventId: string }>('PIN_EVENT'); @@ -174,9 +178,11 @@ export const updateHighlightedDropAndProviderId = actionCreator<{ providerId: string; }>('UPDATE_DROP_AND_PROVIDER'); -export const updateDescription = actionCreator<{ id: string; description: string }>( - 'UPDATE_DESCRIPTION' -); +export const updateDescription = actionCreator<{ + id: string; + description: string; + disableAutoSave?: boolean; +}>('UPDATE_DESCRIPTION'); export const updateKqlMode = actionCreator<{ id: string; kqlMode: KqlMode }>('UPDATE_KQL_MODE'); @@ -205,7 +211,9 @@ export const updateItemsPerPageOptions = actionCreator<{ itemsPerPageOptions: number[]; }>('UPDATE_ITEMS_PER_PAGE_OPTIONS'); -export const updateTitle = actionCreator<{ id: string; title: string }>('UPDATE_TITLE'); +export const updateTitle = actionCreator<{ id: string; title: string; disableAutoSave?: boolean }>( + 'UPDATE_TITLE' +); export const updatePageIndex = actionCreator<{ id: string; activePage: number }>( 'UPDATE_PAGE_INDEX' diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts index cc8e856de1b16..d50de33412175 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts @@ -78,6 +78,7 @@ import { createTimeline, addTimeline, showCallOutUnauthorizedMsg, + saveTimeline, } from './actions'; import { ColumnHeaderOptions, TimelineModel } from './model'; import { epicPersistNote, timelineNoteActionsType } from './epic_note'; @@ -95,6 +96,7 @@ const timelineActionsType = [ dataProviderEdited.type, removeColumn.type, removeProvider.type, + saveTimeline.type, setExcludedRowRendererIds.type, setFilters.type, setSavedQueryId.type, @@ -179,11 +181,11 @@ export const createTimelineEpic = (): Epic< } else if ( timelineActionsType.includes(action.type) && !timelineObj.isLoading && - isItAtimelineAction(timelineId) + isItAtimelineAction(timelineId) && + !get('payload.disableAutoSave', action) ) { return true; } - return false; }), debounceTime(500), mergeMap(([action]) => { diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.ts index 1d956e02e7083..7c227f1c80610 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.ts @@ -389,7 +389,7 @@ export const timelineReducer = reducerWithInitialState(initialTimelineState) ...state, timelineById: updateTimelineKqlMode({ id, kqlMode, timelineById: state.timelineById }), })) - .case(updateTitle, (state, { id, title }) => ({ + .case(updateTitle, (state, { id, title, disableAutoSave }) => ({ ...state, timelineById: updateTimelineTitle({ id, title, timelineById: state.timelineById }), })) From 70807c98bd989f9715279e76567407c8012c7692 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Fri, 30 Oct 2020 16:45:24 +0200 Subject: [PATCH 71/80] [Actions] Fix actionType type on registerType function (#82125) --- x-pack/plugins/actions/server/plugin.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index d0c7bf350504b..06898f6688037 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -254,9 +254,10 @@ export class ActionsPlugin implements Plugin, Plugi registerType: < Config extends ActionTypeConfig = ActionTypeConfig, Secrets extends ActionTypeSecrets = ActionTypeSecrets, - Params extends ActionTypeParams = ActionTypeParams + Params extends ActionTypeParams = ActionTypeParams, + ExecutorResultData = void >( - actionType: ActionType + actionType: ActionType ) => { if (!(actionType.minimumLicenseRequired in LICENSE_TYPE)) { throw new Error(`"${actionType.minimumLicenseRequired}" is not a valid license type`); From c1294f0177bddb8764e61445b0242b7da0f2fcc8 Mon Sep 17 00:00:00 2001 From: igoristic Date: Fri, 30 Oct 2020 10:50:34 -0400 Subject: [PATCH 72/80] [Monitoring] Thread pool rejections alert (#79433) * Thread pool rejections first draft * Split search and write rejections to seperate alerts * Code review feedback * Optimized page loading and bundle size * Increased monitoring bundle limit * Removed server app import into the frontend * Fixed tests and bundle size Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- packages/kbn-optimizer/limits.yml | 2 +- x-pack/plugins/monitoring/common/constants.ts | 177 +++++++++- x-pack/plugins/monitoring/common/enums.ts | 1 + x-pack/plugins/monitoring/common/types.ts | 53 --- .../types.d.ts => common/types/alerts.ts} | 77 ++++- .../monitoring/public/alerts/badge.tsx | 4 +- .../monitoring/public/alerts/callout.tsx | 4 +- .../alerts/components/duration/expression.tsx | 20 +- .../cpu_usage_alert/cpu_usage_alert.tsx | 9 +- .../public/alerts/disk_usage_alert/index.tsx | 10 +- .../public/alerts/filter_alert_states.ts | 2 +- .../alert_param_duration.tsx | 2 +- .../flyout_expressions/alert_param_number.tsx | 36 ++ .../alerts/legacy_alert/legacy_alert.tsx | 11 +- .../public/alerts/lib/replace_tokens.tsx | 2 +- .../alerts/lib/should_show_alert_badge.ts | 2 +- .../alerts/memory_usage_alert/index.tsx | 10 +- .../expression.tsx | 4 +- .../missing_monitoring_data_alert.tsx | 12 +- .../monitoring/public/alerts/panel.tsx | 3 +- .../monitoring/public/alerts/status.tsx | 3 +- .../thread_pool_rejections_alert/index.tsx | 60 ++++ .../public/angular/providers/private.js | 8 +- .../public/components/chart/chart_target.js | 12 +- .../chart/timeseries_visualization.js | 24 +- .../cluster/overview/elasticsearch_panel.js | 4 + .../components/elasticsearch/nodes/nodes.js | 8 +- .../shard_allocation/components/unassigned.js | 4 +- .../lib/has_primary_children.js | 4 +- .../shard_allocation/lib/vents.js | 6 +- .../transformers/indices_by_nodes.js | 17 +- .../transformers/nodes_by_indices.js | 30 +- .../plugins/monitoring/public/legacy_shims.ts | 1 - .../public/lib/calculate_shard_stats.js | 8 +- .../public/lib/get_cluster_from_clusters.js | 6 +- .../monitoring/public/lib/route_init.js | 3 +- x-pack/plugins/monitoring/public/plugin.ts | 61 +++- .../monitoring/public/services/features.js | 6 +- .../monitoring/public/services/title.js | 4 +- .../elasticsearch/node/advanced/index.js | 4 + .../public/views/elasticsearch/node/index.js | 4 + .../public/views/elasticsearch/nodes/index.js | 4 + .../{alerts_common.ts => alert_helpers.ts} | 2 +- .../server/alerts/alerts_factory.test.ts | 5 - .../server/alerts/alerts_factory.ts | 8 +- .../monitoring/server/alerts/base_alert.ts | 23 +- .../server/alerts/cluster_health_alert.ts | 12 +- .../server/alerts/cpu_usage_alert.ts | 47 +-- .../server/alerts/disk_usage_alert.ts | 42 +-- .../elasticsearch_version_mismatch_alert.ts | 16 +- .../plugins/monitoring/server/alerts/index.ts | 4 +- .../alerts/kibana_version_mismatch_alert.ts | 16 +- .../server/alerts/license_expiration_alert.ts | 11 +- .../alerts/logstash_version_mismatch_alert.ts | 16 +- .../server/alerts/memory_usage_alert.ts | 42 +-- .../alerts/missing_monitoring_data_alert.ts | 37 +-- .../server/alerts/nodes_changed_alert.ts | 12 +- .../thread_pool_rejections_alert_base.ts | 312 ++++++++++++++++++ .../thread_pool_search_rejections_alert.ts | 26 ++ .../thread_pool_write_rejections_alert.ts | 26 ++ .../server/lib/alerts/fetch_clusters.ts | 2 +- .../lib/alerts/fetch_cpu_usage_node_stats.ts | 2 +- .../lib/alerts/fetch_disk_usage_node_stats.ts | 2 +- .../server/lib/alerts/fetch_legacy_alerts.ts | 2 +- .../alerts/fetch_memory_usage_node_stats.ts | 2 +- .../alerts/fetch_missing_monitoring_data.ts | 2 +- .../server/lib/alerts/fetch_status.test.ts | 2 +- .../server/lib/alerts/fetch_status.ts | 8 +- .../fetch_thread_pool_rejections_stats.ts | 141 ++++++++ .../server/routes/api/v1/alerts/status.ts | 2 +- 70 files changed, 1149 insertions(+), 395 deletions(-) delete mode 100644 x-pack/plugins/monitoring/common/types.ts rename x-pack/plugins/monitoring/{server/alerts/types.d.ts => common/types/alerts.ts} (66%) create mode 100644 x-pack/plugins/monitoring/public/alerts/flyout_expressions/alert_param_number.tsx create mode 100644 x-pack/plugins/monitoring/public/alerts/thread_pool_rejections_alert/index.tsx rename x-pack/plugins/monitoring/server/alerts/{alerts_common.ts => alert_helpers.ts} (97%) create mode 100644 x-pack/plugins/monitoring/server/alerts/thread_pool_rejections_alert_base.ts create mode 100644 x-pack/plugins/monitoring/server/alerts/thread_pool_search_rejections_alert.ts create mode 100644 x-pack/plugins/monitoring/server/alerts/thread_pool_write_rejections_alert.ts create mode 100644 x-pack/plugins/monitoring/server/lib/alerts/fetch_thread_pool_rejections_stats.ts diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index 3f9fdb164e759..770bb4f510301 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -54,7 +54,7 @@ pageLoadAssetSize: mapsLegacy: 116817 mapsLegacyLicensing: 20214 ml: 82187 - monitoring: 268612 + monitoring: 50000 navigation: 37269 newsfeed: 42228 observability: 89709 diff --git a/x-pack/plugins/monitoring/common/constants.ts b/x-pack/plugins/monitoring/common/constants.ts index 76d9e7517b6ab..8ff8381d702e8 100644 --- a/x-pack/plugins/monitoring/common/constants.ts +++ b/x-pack/plugins/monitoring/common/constants.ts @@ -4,6 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ +import { i18n } from '@kbn/i18n'; +import { CommonAlertParamDetail } from './types/alerts'; +import { AlertParamType } from './enums'; + /** * Helper string to add as a tag in every logging call */ @@ -215,15 +219,6 @@ export const REPORTING_SYSTEM_ID = 'reporting'; */ export const TELEMETRY_COLLECTION_INTERVAL = 86400000; -/** - * We want to slowly rollout the migration from watcher-based cluster alerts to - * kibana alerts and we only want to enable the kibana alerts once all - * watcher-based cluster alerts have been migrated so this flag will serve - * as the only way to see the new UI and actually run Kibana alerts. It will - * be false until all alerts have been migrated, then it will be removed - */ -export const KIBANA_CLUSTER_ALERTS_ENABLED = false; - /** * The prefix for all alert types used by monitoring */ @@ -238,6 +233,168 @@ export const ALERT_KIBANA_VERSION_MISMATCH = `${ALERT_PREFIX}alert_kibana_versio export const ALERT_LOGSTASH_VERSION_MISMATCH = `${ALERT_PREFIX}alert_logstash_version_mismatch`; export const ALERT_MEMORY_USAGE = `${ALERT_PREFIX}alert_jvm_memory_usage`; export const ALERT_MISSING_MONITORING_DATA = `${ALERT_PREFIX}alert_missing_monitoring_data`; +export const ALERT_THREAD_POOL_SEARCH_REJECTIONS = `${ALERT_PREFIX}alert_thread_pool_search_rejections`; +export const ALERT_THREAD_POOL_WRITE_REJECTIONS = `${ALERT_PREFIX}alert_thread_pool_write_rejections`; + +/** + * Legacy alerts details/label for server and public use + */ +export const LEGACY_ALERT_DETAILS = { + [ALERT_CLUSTER_HEALTH]: { + label: i18n.translate('xpack.monitoring.alerts.clusterHealth.label', { + defaultMessage: 'Cluster health', + }), + }, + [ALERT_ELASTICSEARCH_VERSION_MISMATCH]: { + label: i18n.translate('xpack.monitoring.alerts.elasticsearchVersionMismatch.label', { + defaultMessage: 'Elasticsearch version mismatch', + }), + }, + [ALERT_KIBANA_VERSION_MISMATCH]: { + label: i18n.translate('xpack.monitoring.alerts.kibanaVersionMismatch.label', { + defaultMessage: 'Kibana version mismatch', + }), + }, + [ALERT_LICENSE_EXPIRATION]: { + label: i18n.translate('xpack.monitoring.alerts.licenseExpiration.label', { + defaultMessage: 'License expiration', + }), + }, + [ALERT_LOGSTASH_VERSION_MISMATCH]: { + label: i18n.translate('xpack.monitoring.alerts.logstashVersionMismatch.label', { + defaultMessage: 'Logstash version mismatch', + }), + }, + [ALERT_NODES_CHANGED]: { + label: i18n.translate('xpack.monitoring.alerts.nodesChanged.label', { + defaultMessage: 'Nodes changed', + }), + }, +}; + +/** + * Alerts details/label for server and public use + */ +export const ALERT_DETAILS = { + [ALERT_CPU_USAGE]: { + label: i18n.translate('xpack.monitoring.alerts.cpuUsage.label', { + defaultMessage: 'CPU Usage', + }), + paramDetails: { + threshold: { + label: i18n.translate('xpack.monitoring.alerts.cpuUsage.paramDetails.threshold.label', { + defaultMessage: `Notify when CPU is over`, + }), + type: AlertParamType.Percentage, + } as CommonAlertParamDetail, + duration: { + label: i18n.translate('xpack.monitoring.alerts.cpuUsage.paramDetails.duration.label', { + defaultMessage: `Look at the average over`, + }), + type: AlertParamType.Duration, + } as CommonAlertParamDetail, + }, + }, + [ALERT_DISK_USAGE]: { + paramDetails: { + threshold: { + label: i18n.translate('xpack.monitoring.alerts.diskUsage.paramDetails.threshold.label', { + defaultMessage: `Notify when disk capacity is over`, + }), + type: AlertParamType.Percentage, + }, + duration: { + label: i18n.translate('xpack.monitoring.alerts.diskUsage.paramDetails.duration.label', { + defaultMessage: `Look at the average over`, + }), + type: AlertParamType.Duration, + }, + }, + label: i18n.translate('xpack.monitoring.alerts.diskUsage.label', { + defaultMessage: 'Disk Usage', + }), + }, + [ALERT_MEMORY_USAGE]: { + paramDetails: { + threshold: { + label: i18n.translate('xpack.monitoring.alerts.memoryUsage.paramDetails.threshold.label', { + defaultMessage: `Notify when memory usage is over`, + }), + type: AlertParamType.Percentage, + }, + duration: { + label: i18n.translate('xpack.monitoring.alerts.memoryUsage.paramDetails.duration.label', { + defaultMessage: `Look at the average over`, + }), + type: AlertParamType.Duration, + }, + }, + label: i18n.translate('xpack.monitoring.alerts.memoryUsage.label', { + defaultMessage: 'Memory Usage (JVM)', + }), + }, + [ALERT_MISSING_MONITORING_DATA]: { + paramDetails: { + duration: { + label: i18n.translate('xpack.monitoring.alerts.missingData.paramDetails.duration.label', { + defaultMessage: `Notify if monitoring data is missing for the last`, + }), + type: AlertParamType.Duration, + } as CommonAlertParamDetail, + limit: { + label: i18n.translate('xpack.monitoring.alerts.missingData.paramDetails.limit.label', { + defaultMessage: `looking back`, + }), + type: AlertParamType.Duration, + } as CommonAlertParamDetail, + }, + label: i18n.translate('xpack.monitoring.alerts.missingData.label', { + defaultMessage: 'Missing monitoring data', + }), + }, + [ALERT_THREAD_POOL_SEARCH_REJECTIONS]: { + paramDetails: { + threshold: { + label: i18n.translate('xpack.monitoring.alerts.rejection.paramDetails.threshold.label', { + defaultMessage: `Notify when {type} rejection count is over`, + values: { type: 'search' }, + }), + type: AlertParamType.Number, + }, + duration: { + label: i18n.translate('xpack.monitoring.alerts.rejection.paramDetails.duration.label', { + defaultMessage: `In the last`, + }), + type: AlertParamType.Duration, + }, + }, + label: i18n.translate('xpack.monitoring.alerts.threadPoolRejections.label', { + defaultMessage: 'Thread pool {type} rejections', + values: { type: 'search' }, + }), + }, + [ALERT_THREAD_POOL_WRITE_REJECTIONS]: { + paramDetails: { + threshold: { + label: i18n.translate('xpack.monitoring.alerts.rejection.paramDetails.threshold.label', { + defaultMessage: `Notify when {type} rejection count is over`, + values: { type: 'write' }, + }), + type: AlertParamType.Number, + }, + duration: { + label: i18n.translate('xpack.monitoring.alerts.rejection.paramDetails.duration.label', { + defaultMessage: `In the last`, + }), + type: AlertParamType.Duration, + }, + }, + label: i18n.translate('xpack.monitoring.alerts.threadPoolRejections.label', { + defaultMessage: 'Thread pool {type} rejections', + values: { type: 'write' }, + }), + }, +}; /** * A listing of all alert types @@ -253,6 +410,8 @@ export const ALERTS = [ ALERT_LOGSTASH_VERSION_MISMATCH, ALERT_MEMORY_USAGE, ALERT_MISSING_MONITORING_DATA, + ALERT_THREAD_POOL_SEARCH_REJECTIONS, + ALERT_THREAD_POOL_WRITE_REJECTIONS, ]; /** diff --git a/x-pack/plugins/monitoring/common/enums.ts b/x-pack/plugins/monitoring/common/enums.ts index d4058e9de801e..b373428bb279b 100644 --- a/x-pack/plugins/monitoring/common/enums.ts +++ b/x-pack/plugins/monitoring/common/enums.ts @@ -25,6 +25,7 @@ export enum AlertMessageTokenType { export enum AlertParamType { Duration = 'duration', Percentage = 'percentage', + Number = 'number', } export enum SetupModeFeature { diff --git a/x-pack/plugins/monitoring/common/types.ts b/x-pack/plugins/monitoring/common/types.ts deleted file mode 100644 index 825d2e454b3bb..0000000000000 --- a/x-pack/plugins/monitoring/common/types.ts +++ /dev/null @@ -1,53 +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 { Alert } from '../../alerts/common'; -import { AlertParamType } from './enums'; - -export interface CommonBaseAlert { - type: string; - label: string; - paramDetails: CommonAlertParamDetails; - rawAlert: Alert; - isLegacy: boolean; -} - -export interface CommonAlertStatus { - exists: boolean; - enabled: boolean; - states: CommonAlertState[]; - alert: CommonBaseAlert; -} - -export interface CommonAlertState { - firing: boolean; - state: any; - meta: any; -} - -export interface CommonAlertFilter { - nodeUuid?: string; -} - -export interface CommonAlertNodeUuidFilter extends CommonAlertFilter { - nodeUuid: string; -} - -export interface CommonAlertStackProductFilter extends CommonAlertFilter { - stackProduct: string; -} - -export interface CommonAlertParamDetail { - label: string; - type: AlertParamType; -} - -export interface CommonAlertParamDetails { - [name: string]: CommonAlertParamDetail; -} - -export interface CommonAlertParams { - [name: string]: string | number; -} diff --git a/x-pack/plugins/monitoring/server/alerts/types.d.ts b/x-pack/plugins/monitoring/common/types/alerts.ts similarity index 66% rename from x-pack/plugins/monitoring/server/alerts/types.d.ts rename to x-pack/plugins/monitoring/common/types/alerts.ts index 0b346e770a299..f7a27a1b1a2b0 100644 --- a/x-pack/plugins/monitoring/server/alerts/types.d.ts +++ b/x-pack/plugins/monitoring/common/types/alerts.ts @@ -3,8 +3,60 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { AlertMessageTokenType, AlertSeverity } from '../../common/enums'; -import { AlertInstanceState as BaseAlertInstanceState } from '../../../alerts/server'; + +import { Alert } from '../../../alerts/common'; +import { AlertParamType, AlertMessageTokenType, AlertSeverity } from '../enums'; + +export interface CommonBaseAlert { + type: string; + label: string; + paramDetails: CommonAlertParamDetails; + rawAlert: Alert; + isLegacy: boolean; +} + +export interface CommonAlertStatus { + exists: boolean; + enabled: boolean; + states: CommonAlertState[]; + alert: CommonBaseAlert; +} + +export interface CommonAlertState { + firing: boolean; + state: any; + meta: any; +} + +export interface CommonAlertFilter { + nodeUuid?: string; +} + +export interface CommonAlertNodeUuidFilter extends CommonAlertFilter { + nodeUuid: string; +} + +export interface CommonAlertStackProductFilter extends CommonAlertFilter { + stackProduct: string; +} + +export interface CommonAlertParamDetail { + label: string; + type?: AlertParamType; +} + +export interface CommonAlertParamDetails { + [name: string]: CommonAlertParamDetail | undefined; +} + +export interface CommonAlertParams { + [name: string]: string | number; +} + +export interface ThreadPoolRejectionsAlertParams { + threshold: number; + duration: string; +} export interface AlertEnableAction { id: string; @@ -12,7 +64,9 @@ export interface AlertEnableAction { } export interface AlertInstanceState { - alertStates: Array; + alertStates: Array< + AlertState | AlertCpuUsageState | AlertDiskUsageState | AlertThreadPoolRejectionsState + >; [x: string]: unknown; } @@ -46,6 +100,13 @@ export interface AlertMemoryUsageState extends AlertNodeState { memoryUsage: number; } +export interface AlertThreadPoolRejectionsState extends AlertState { + rejectionCount: number; + type: string; + nodeId: string; + nodeName?: string; +} + export interface AlertUiState { isFiring: boolean; severity: AlertSeverity; @@ -100,6 +161,14 @@ export interface AlertCpuUsageNodeStats extends AlertNodeStats { containerQuota: number; } +export interface AlertThreadPoolRejectionsStats { + clusterUuid: string; + nodeId: string; + nodeName: string; + rejectionCount: number; + ccs?: string; +} + export interface AlertDiskUsageNodeStats extends AlertNodeStats { diskUsage: number; } @@ -121,7 +190,7 @@ export interface AlertData { instanceKey: string; clusterUuid: string; ccs?: string; - shouldFire: boolean; + shouldFire?: boolean; severity: AlertSeverity; meta: any; } diff --git a/x-pack/plugins/monitoring/public/alerts/badge.tsx b/x-pack/plugins/monitoring/public/alerts/badge.tsx index d4e823a194f8e..4bfecf4380d4b 100644 --- a/x-pack/plugins/monitoring/public/alerts/badge.tsx +++ b/x-pack/plugins/monitoring/public/alerts/badge.tsx @@ -14,11 +14,11 @@ import { EuiFlexItem, EuiText, } from '@elastic/eui'; -import { CommonAlertStatus, CommonAlertState } from '../../common/types'; +import { CommonAlertStatus, CommonAlertState } from '../../common/types/alerts'; import { AlertSeverity } from '../../common/enums'; // @ts-ignore import { formatDateTimeLocal } from '../../common/formatting'; -import { AlertMessage, AlertState } from '../../server/alerts/types'; +import { AlertMessage, AlertState } from '../../common/types/alerts'; import { AlertPanel } from './panel'; import { Legacy } from '../legacy_shims'; import { isInSetupMode } from '../lib/setup_mode'; diff --git a/x-pack/plugins/monitoring/public/alerts/callout.tsx b/x-pack/plugins/monitoring/public/alerts/callout.tsx index 1ddd41c268456..769d4dc7b256d 100644 --- a/x-pack/plugins/monitoring/public/alerts/callout.tsx +++ b/x-pack/plugins/monitoring/public/alerts/callout.tsx @@ -7,10 +7,10 @@ import React, { Fragment } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiCallOut, EuiSpacer } from '@elastic/eui'; -import { CommonAlertStatus } from '../../common/types'; +import { CommonAlertStatus } from '../../common/types/alerts'; import { AlertSeverity } from '../../common/enums'; import { replaceTokens } from './lib/replace_tokens'; -import { AlertMessage, AlertState } from '../../server/alerts/types'; +import { AlertMessage, AlertState } from '../../common/types/alerts'; const TYPES = [ { diff --git a/x-pack/plugins/monitoring/public/alerts/components/duration/expression.tsx b/x-pack/plugins/monitoring/public/alerts/components/duration/expression.tsx index 2df7169efc675..26593fdd6e7b0 100644 --- a/x-pack/plugins/monitoring/public/alerts/components/duration/expression.tsx +++ b/x-pack/plugins/monitoring/public/alerts/components/duration/expression.tsx @@ -6,10 +6,11 @@ import React, { Fragment } from 'react'; import { EuiForm, EuiSpacer } from '@elastic/eui'; -import { CommonAlertParamDetails } from '../../../../common/types'; +import { CommonAlertParamDetails } from '../../../../common/types/alerts'; import { AlertParamDuration } from '../../flyout_expressions/alert_param_duration'; import { AlertParamType } from '../../../../common/enums'; import { AlertParamPercentage } from '../../flyout_expressions/alert_param_percentage'; +import { AlertParamNumber } from '../../flyout_expressions/alert_param_number'; export interface Props { alertParams: { [property: string]: any }; @@ -26,14 +27,14 @@ export const Expression: React.FC = (props) => { const details = paramDetails[alertParamName]; const value = alertParams[alertParamName]; - switch (details.type) { + switch (details?.type) { case AlertParamType.Duration: return ( @@ -43,12 +44,23 @@ export const Expression: React.FC = (props) => { ); + case AlertParamType.Number: + return ( + + ); } }); diff --git a/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/cpu_usage_alert.tsx b/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/cpu_usage_alert.tsx index fb4ecacf57fd6..d15fe6344ec0f 100644 --- a/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/cpu_usage_alert.tsx +++ b/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/cpu_usage_alert.tsx @@ -6,20 +6,17 @@ import React from 'react'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { AlertTypeModel } from '../../../../triggers_actions_ui/public/types'; -import { ALERT_CPU_USAGE } from '../../../common/constants'; +import { ALERT_CPU_USAGE, ALERT_DETAILS } from '../../../common/constants'; import { validate } from '../components/duration/validation'; import { Expression, Props } from '../components/duration/expression'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { CpuUsageAlert } from '../../../server/alerts'; export function createCpuUsageAlertType(): AlertTypeModel { - const alert = new CpuUsageAlert(); return { id: ALERT_CPU_USAGE, - name: alert.label, + name: ALERT_DETAILS[ALERT_CPU_USAGE].label, iconClass: 'bell', alertParamsExpression: (props: Props) => ( - + ), validate, defaultActionMessage: '{{context.internalFullMessage}}', diff --git a/x-pack/plugins/monitoring/public/alerts/disk_usage_alert/index.tsx b/x-pack/plugins/monitoring/public/alerts/disk_usage_alert/index.tsx index c2abb35612b38..589b374cae32c 100644 --- a/x-pack/plugins/monitoring/public/alerts/disk_usage_alert/index.tsx +++ b/x-pack/plugins/monitoring/public/alerts/disk_usage_alert/index.tsx @@ -10,17 +10,15 @@ import { Expression, Props } from '../components/duration/expression'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { AlertTypeModel } from '../../../../triggers_actions_ui/public/types'; - -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { DiskUsageAlert } from '../../../server/alerts'; +import { ALERT_DISK_USAGE, ALERT_DETAILS } from '../../../common/constants'; export function createDiskUsageAlertType(): AlertTypeModel { return { - id: DiskUsageAlert.TYPE, - name: DiskUsageAlert.LABEL, + id: ALERT_DISK_USAGE, + name: ALERT_DETAILS[ALERT_DISK_USAGE].label, iconClass: 'bell', alertParamsExpression: (props: Props) => ( - + ), validate, defaultActionMessage: '{{context.internalFullMessage}}', diff --git a/x-pack/plugins/monitoring/public/alerts/filter_alert_states.ts b/x-pack/plugins/monitoring/public/alerts/filter_alert_states.ts index 63714a6921e3f..e13ea7de0e226 100644 --- a/x-pack/plugins/monitoring/public/alerts/filter_alert_states.ts +++ b/x-pack/plugins/monitoring/public/alerts/filter_alert_states.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CommonAlertState, CommonAlertStatus } from '../../common/types'; +import { CommonAlertState, CommonAlertStatus } from '../../common/types/alerts'; export function filterAlertStates( alerts: { [type: string]: CommonAlertStatus }, diff --git a/x-pack/plugins/monitoring/public/alerts/flyout_expressions/alert_param_duration.tsx b/x-pack/plugins/monitoring/public/alerts/flyout_expressions/alert_param_duration.tsx index 862f32efd7361..4ece1b0c81827 100644 --- a/x-pack/plugins/monitoring/public/alerts/flyout_expressions/alert_param_duration.tsx +++ b/x-pack/plugins/monitoring/public/alerts/flyout_expressions/alert_param_duration.tsx @@ -69,7 +69,7 @@ export const AlertParamDuration: React.FC = (props: Props) => { }, [unit, value]); return ( - 0}> + 0}> void; +} +export const AlertParamNumber: React.FC = (props: Props) => { + const { name, label, setAlertParams, errors } = props; + const [value, setValue] = useState(props.value); + return ( + 0}> + { + let newValue = Number(e.target.value); + if (isNaN(newValue)) { + newValue = 0; + } + setValue(newValue); + setAlertParams(name, newValue); + }} + /> + + ); +}; diff --git a/x-pack/plugins/monitoring/public/alerts/legacy_alert/legacy_alert.tsx b/x-pack/plugins/monitoring/public/alerts/legacy_alert/legacy_alert.tsx index f6223d41ab30e..83201b0512dbb 100644 --- a/x-pack/plugins/monitoring/public/alerts/legacy_alert/legacy_alert.tsx +++ b/x-pack/plugins/monitoring/public/alerts/legacy_alert/legacy_alert.tsx @@ -3,24 +3,21 @@ * 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, { Fragment } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiTextColor, EuiSpacer } from '@elastic/eui'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { AlertTypeModel } from '../../../../triggers_actions_ui/public/types'; -import { LEGACY_ALERTS } from '../../../common/constants'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { BY_TYPE } from '../../../server/alerts'; +import { LEGACY_ALERTS, LEGACY_ALERT_DETAILS } from '../../../common/constants'; export function createLegacyAlertTypes(): AlertTypeModel[] { return LEGACY_ALERTS.map((legacyAlert) => { - const alertCls = BY_TYPE[legacyAlert]; - const alert = new alertCls(); return { id: legacyAlert, - name: alert.label, + name: LEGACY_ALERT_DETAILS[legacyAlert].label, iconClass: 'bell', - alertParamsExpression: (props: any) => ( + alertParamsExpression: () => ( diff --git a/x-pack/plugins/monitoring/public/alerts/lib/replace_tokens.tsx b/x-pack/plugins/monitoring/public/alerts/lib/replace_tokens.tsx index 02f5703f66382..b8ac69cbae68a 100644 --- a/x-pack/plugins/monitoring/public/alerts/lib/replace_tokens.tsx +++ b/x-pack/plugins/monitoring/public/alerts/lib/replace_tokens.tsx @@ -11,7 +11,7 @@ import { AlertMessageTimeToken, AlertMessageLinkToken, AlertMessageDocLinkToken, -} from '../../../server/alerts/types'; +} from '../../../common/types/alerts'; // @ts-ignore import { formatTimestampToDuration } from '../../../common'; import { CALCULATE_DURATION_UNTIL } from '../../../common/constants'; diff --git a/x-pack/plugins/monitoring/public/alerts/lib/should_show_alert_badge.ts b/x-pack/plugins/monitoring/public/alerts/lib/should_show_alert_badge.ts index 0b95592d92c84..2ec5d1ba8f94a 100644 --- a/x-pack/plugins/monitoring/public/alerts/lib/should_show_alert_badge.ts +++ b/x-pack/plugins/monitoring/public/alerts/lib/should_show_alert_badge.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { isInSetupMode } from '../../lib/setup_mode'; -import { CommonAlertStatus } from '../../../common/types'; +import { CommonAlertStatus } from '../../../common/types/alerts'; import { ISetupModeContext } from '../../components/setup_mode/setup_mode_context'; export function shouldShowAlertBadge( diff --git a/x-pack/plugins/monitoring/public/alerts/memory_usage_alert/index.tsx b/x-pack/plugins/monitoring/public/alerts/memory_usage_alert/index.tsx index dd60967a3458b..d3d48d907d02e 100644 --- a/x-pack/plugins/monitoring/public/alerts/memory_usage_alert/index.tsx +++ b/x-pack/plugins/monitoring/public/alerts/memory_usage_alert/index.tsx @@ -10,17 +10,15 @@ import { Expression, Props } from '../components/duration/expression'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { AlertTypeModel } from '../../../../triggers_actions_ui/public/types'; - -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { MemoryUsageAlert } from '../../../server/alerts'; +import { ALERT_MEMORY_USAGE, ALERT_DETAILS } from '../../../common/constants'; export function createMemoryUsageAlertType(): AlertTypeModel { return { - id: MemoryUsageAlert.TYPE, - name: MemoryUsageAlert.LABEL, + id: ALERT_MEMORY_USAGE, + name: ALERT_DETAILS[ALERT_MEMORY_USAGE].label, iconClass: 'bell', alertParamsExpression: (props: Props) => ( - + ), validate, defaultActionMessage: '{{context.internalFullMessage}}', diff --git a/x-pack/plugins/monitoring/public/alerts/missing_monitoring_data_alert/expression.tsx b/x-pack/plugins/monitoring/public/alerts/missing_monitoring_data_alert/expression.tsx index 7dc6155de529e..ac30a02173a5c 100644 --- a/x-pack/plugins/monitoring/public/alerts/missing_monitoring_data_alert/expression.tsx +++ b/x-pack/plugins/monitoring/public/alerts/missing_monitoring_data_alert/expression.tsx @@ -6,7 +6,7 @@ import React, { Fragment } from 'react'; import { EuiForm, EuiSpacer } from '@elastic/eui'; -import { CommonAlertParamDetails } from '../../../common/types'; +import { CommonAlertParamDetails } from '../../../common/types/alerts'; import { AlertParamDuration } from '../flyout_expressions/alert_param_duration'; import { AlertParamType } from '../../../common/enums'; import { AlertParamPercentage } from '../flyout_expressions/alert_param_percentage'; @@ -26,7 +26,7 @@ export const Expression: React.FC = (props) => { const details = paramDetails[alertParamName]; const value = alertParams[alertParamName]; - switch (details.type) { + switch (details?.type) { case AlertParamType.Duration: return ( ( - + ), validate, defaultActionMessage: '{{context.internalFullMessage}}', diff --git a/x-pack/plugins/monitoring/public/alerts/panel.tsx b/x-pack/plugins/monitoring/public/alerts/panel.tsx index eb3b6ff9da1be..99db6c8b3c945 100644 --- a/x-pack/plugins/monitoring/public/alerts/panel.tsx +++ b/x-pack/plugins/monitoring/public/alerts/panel.tsx @@ -18,8 +18,7 @@ import { EuiListGroupItem, } from '@elastic/eui'; -import { CommonAlertStatus, CommonAlertState } from '../../common/types'; -import { AlertMessage } from '../../server/alerts/types'; +import { CommonAlertStatus, CommonAlertState, AlertMessage } from '../../common/types/alerts'; import { Legacy } from '../legacy_shims'; import { replaceTokens } from './lib/replace_tokens'; import { AlertsContextProvider } from '../../../triggers_actions_ui/public'; diff --git a/x-pack/plugins/monitoring/public/alerts/status.tsx b/x-pack/plugins/monitoring/public/alerts/status.tsx index c1ad41fc8d763..53918807a4272 100644 --- a/x-pack/plugins/monitoring/public/alerts/status.tsx +++ b/x-pack/plugins/monitoring/public/alerts/status.tsx @@ -7,9 +7,8 @@ import React from 'react'; import { EuiToolTip, EuiHealth } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { CommonAlertStatus } from '../../common/types'; +import { CommonAlertStatus, AlertMessage, AlertState } from '../../common/types/alerts'; import { AlertSeverity } from '../../common/enums'; -import { AlertMessage, AlertState } from '../../server/alerts/types'; import { AlertsBadge } from './badge'; import { isInSetupMode } from '../lib/setup_mode'; import { SetupModeContext } from '../components/setup_mode/setup_mode_context'; diff --git a/x-pack/plugins/monitoring/public/alerts/thread_pool_rejections_alert/index.tsx b/x-pack/plugins/monitoring/public/alerts/thread_pool_rejections_alert/index.tsx new file mode 100644 index 0000000000000..5e8e676448218 --- /dev/null +++ b/x-pack/plugins/monitoring/public/alerts/thread_pool_rejections_alert/index.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 React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiSpacer } from '@elastic/eui'; +import { Expression, Props } from '../components/duration/expression'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { AlertTypeModel } from '../../../../triggers_actions_ui/public/types'; +import { CommonAlertParamDetails } from '../../../common/types/alerts'; + +interface ThreadPoolTypes { + [key: string]: unknown; +} + +interface ThreadPoolRejectionAlertDetails { + label: string; + paramDetails: CommonAlertParamDetails; +} + +export function createThreadPoolRejectionsAlertType( + alertType: string, + threadPoolAlertDetails: ThreadPoolRejectionAlertDetails +): AlertTypeModel { + return { + id: alertType, + name: threadPoolAlertDetails.label, + iconClass: 'bell', + alertParamsExpression: (props: Props) => ( + <> + + + + ), + validate: (inputValues: ThreadPoolTypes) => { + const errors: { [key: string]: string[] } = {}; + const value = inputValues.threshold as number; + if (value < 0) { + const errStr = i18n.translate('xpack.monitoring.alerts.validation.lessThanZero', { + defaultMessage: 'This value can not be less than zero', + }); + errors.threshold = [errStr]; + } + + if (!inputValues.duration) { + const errStr = i18n.translate('xpack.monitoring.alerts.validation.duration', { + defaultMessage: 'A valid duration is required.', + }); + errors.duration = [errStr]; + } + + return { errors }; + }, + defaultActionMessage: '{{context.internalFullMessage}}', + requiresAppContext: true, + }; +} diff --git a/x-pack/plugins/monitoring/public/angular/providers/private.js b/x-pack/plugins/monitoring/public/angular/providers/private.js index 3a667037b2919..7709865432fe6 100644 --- a/x-pack/plugins/monitoring/public/angular/providers/private.js +++ b/x-pack/plugins/monitoring/public/angular/providers/private.js @@ -81,9 +81,9 @@ * * @param {[type]} prov [description] */ -import _ from 'lodash'; +import { partial, uniqueId, isObject } from 'lodash'; -const nextId = _.partial(_.uniqueId, 'privateProvider#'); +const nextId = partial(uniqueId, 'privateProvider#'); function name(fn) { return fn.name || fn.toString().split('\n').shift(); @@ -141,7 +141,7 @@ export function PrivateProvider() { const context = {}; let instance = $injector.invoke(prov, context, locals); - if (!_.isObject(instance)) instance = context; + if (!isObject(instance)) instance = context; privPath.pop(); return instance; @@ -155,7 +155,7 @@ export function PrivateProvider() { if ($delegateId != null && $delegateProv != null) { instance = instantiate(prov, { - $decorate: _.partial(get, $delegateId, $delegateProv), + $decorate: partial(get, $delegateId, $delegateProv), }); } else { instance = instantiate(prov); diff --git a/x-pack/plugins/monitoring/public/components/chart/chart_target.js b/x-pack/plugins/monitoring/public/components/chart/chart_target.js index 9a590d803bb19..519964e4d5914 100644 --- a/x-pack/plugins/monitoring/public/components/chart/chart_target.js +++ b/x-pack/plugins/monitoring/public/components/chart/chart_target.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; +import { get, isEqual, filter } from 'lodash'; import $ from 'jquery'; import React from 'react'; import { eventBus } from './event_bus'; @@ -50,12 +50,12 @@ export class ChartTarget extends React.Component { } UNSAFE_componentWillReceiveProps(newProps) { - if (this.plot && !_.isEqual(newProps, this.props)) { + if (this.plot && !isEqual(newProps, this.props)) { const { series, timeRange } = newProps; const xaxisOptions = this.plot.getAxes().xaxis.options; - xaxisOptions.min = _.get(timeRange, 'min'); - xaxisOptions.max = _.get(timeRange, 'max'); + xaxisOptions.min = get(timeRange, 'min'); + xaxisOptions.max = get(timeRange, 'max'); this.plot.setData(this.filterData(series, newProps.seriesToShow)); this.plot.setupGrid(); @@ -73,7 +73,7 @@ export class ChartTarget extends React.Component { } filterData(data, seriesToShow) { - return _(data).filter(this.filterByShow(seriesToShow)).value(); + return filter(data, this.filterByShow(seriesToShow)); } async getOptions() { @@ -128,7 +128,7 @@ export class ChartTarget extends React.Component { this.handleThorPlotHover = (_event, pos, item, originalPlot) => { if (this.plot !== originalPlot) { // the crosshair is set for the original chart already - this.plot.setCrosshair({ x: _.get(pos, 'x') }); + this.plot.setCrosshair({ x: get(pos, 'x') }); } this.props.updateLegend(pos, item); }; diff --git a/x-pack/plugins/monitoring/public/components/chart/timeseries_visualization.js b/x-pack/plugins/monitoring/public/components/chart/timeseries_visualization.js index eb32ee108e7b3..829994791f769 100644 --- a/x-pack/plugins/monitoring/public/components/chart/timeseries_visualization.js +++ b/x-pack/plugins/monitoring/public/components/chart/timeseries_visualization.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; +import { debounce, keys, has, includes, isFunction, difference, assign } from 'lodash'; import React from 'react'; import { getLastValue } from './get_last_value'; import { TimeseriesContainer } from './timeseries_container'; @@ -17,7 +17,7 @@ export class TimeseriesVisualization extends React.Component { constructor(props) { super(props); - this.debouncedUpdateLegend = _.debounce(this.updateLegend, DEBOUNCE_SLOW_MS); + this.debouncedUpdateLegend = debounce(this.updateLegend, DEBOUNCE_SLOW_MS); this.debouncedUpdateLegend = this.debouncedUpdateLegend.bind(this); this.toggleFilter = this.toggleFilter.bind(this); @@ -26,18 +26,18 @@ export class TimeseriesVisualization extends React.Component { this.state = { values: {}, - seriesToShow: _.keys(values), + seriesToShow: keys(values), ignoreVisibilityUpdates: false, }; } filterLegend(id) { - if (!_.has(this.state.values, id)) { + if (!has(this.state.values, id)) { return []; } - const notAllShown = _.keys(this.state.values).length !== this.state.seriesToShow.length; - const isCurrentlyShown = _.includes(this.state.seriesToShow, id); + const notAllShown = keys(this.state.values).length !== this.state.seriesToShow.length; + const isCurrentlyShown = includes(this.state.seriesToShow, id); const seriesToShow = []; if (notAllShown && isCurrentlyShown) { @@ -59,7 +59,7 @@ export class TimeseriesVisualization extends React.Component { toggleFilter(_event, id) { const seriesToShow = this.filterLegend(id); - if (_.isFunction(this.props.onFilter)) { + if (isFunction(this.props.onFilter)) { this.props.onFilter(seriesToShow); } } @@ -94,7 +94,7 @@ export class TimeseriesVisualization extends React.Component { getValuesByX(this.props.series, pos.x, setValueCallback); } } else { - _.assign(values, this.getLastValues()); + assign(values, this.getLastValues()); } this.setState({ values }); @@ -102,13 +102,13 @@ export class TimeseriesVisualization extends React.Component { UNSAFE_componentWillReceiveProps(props) { const values = this.getLastValues(props); - const currentKeys = _.keys(this.state.values); - const keys = _.keys(values); - const diff = _.difference(keys, currentKeys); + const currentKeys = keys(this.state.values); + const valueKeys = keys(values); + const diff = difference(valueKeys, currentKeys); const nextState = { values: values }; if (diff.length && !this.state.ignoreVisibilityUpdates) { - nextState.seriesToShow = keys; + nextState.seriesToShow = valueKeys; } this.setState(nextState); diff --git a/x-pack/plugins/monitoring/public/components/cluster/overview/elasticsearch_panel.js b/x-pack/plugins/monitoring/public/components/cluster/overview/elasticsearch_panel.js index 0fe434afa2c88..7e85d62c4bbd6 100644 --- a/x-pack/plugins/monitoring/public/components/cluster/overview/elasticsearch_panel.js +++ b/x-pack/plugins/monitoring/public/components/cluster/overview/elasticsearch_panel.js @@ -41,6 +41,8 @@ import { ALERT_CLUSTER_HEALTH, ALERT_CPU_USAGE, ALERT_DISK_USAGE, + ALERT_THREAD_POOL_SEARCH_REJECTIONS, + ALERT_THREAD_POOL_WRITE_REJECTIONS, ALERT_MEMORY_USAGE, ALERT_NODES_CHANGED, ALERT_ELASTICSEARCH_VERSION_MISMATCH, @@ -162,6 +164,8 @@ const OVERVIEW_PANEL_ALERTS = [ALERT_CLUSTER_HEALTH, ALERT_LICENSE_EXPIRATION]; const NODES_PANEL_ALERTS = [ ALERT_CPU_USAGE, ALERT_DISK_USAGE, + ALERT_THREAD_POOL_SEARCH_REJECTIONS, + ALERT_THREAD_POOL_WRITE_REJECTIONS, ALERT_MEMORY_USAGE, ALERT_NODES_CHANGED, ALERT_ELASTICSEARCH_VERSION_MISMATCH, diff --git a/x-pack/plugins/monitoring/public/components/elasticsearch/nodes/nodes.js b/x-pack/plugins/monitoring/public/components/elasticsearch/nodes/nodes.js index 41d3a579db5a2..61188487e2f99 100644 --- a/x-pack/plugins/monitoring/public/components/elasticsearch/nodes/nodes.js +++ b/x-pack/plugins/monitoring/public/components/elasticsearch/nodes/nodes.js @@ -27,7 +27,7 @@ import { EuiHealth, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import _ from 'lodash'; +import { get } from 'lodash'; import { ELASTICSEARCH_SYSTEM_ID } from '../../../../common/constants'; import { FormattedMessage } from '@kbn/i18n/react'; import { ListingCallOut } from '../../setup_mode/listing_callout'; @@ -58,7 +58,7 @@ const getNodeTooltip = (node) => { return null; }; -const getSortHandler = (type) => (item) => _.get(item, [type, 'summary', 'lastVal']); +const getSortHandler = (type) => (item) => get(item, [type, 'summary', 'lastVal']); const getColumns = (showCgroupMetricsElasticsearch, setupMode, clusterUuid, alerts) => { const cols = []; @@ -87,7 +87,7 @@ const getColumns = (showCgroupMetricsElasticsearch, setupMode, clusterUuid, aler let setupModeStatus = null; if (isSetupModeFeatureEnabled(SetupModeFeature.MetricbeatMigration)) { - const list = _.get(setupMode, 'data.byUuid', {}); + const list = get(setupMode, 'data.byUuid', {}); const status = list[node.resolver] || {}; const instance = { uuid: node.resolver, @@ -396,7 +396,7 @@ export function ElasticsearchNodes({ clusterStatus, showCgroupMetricsElasticsear setupMode.data.totalUniqueInstanceCount ) { const finishMigrationAction = - _.get(setupMode.meta, 'liveClusterUuid') === clusterUuid + get(setupMode.meta, 'liveClusterUuid') === clusterUuid ? setupMode.shortcutToFinishMigration : setupMode.openFlyout; diff --git a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/components/unassigned.js b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/components/unassigned.js index 2c66d14a40605..5c8dca54894b4 100644 --- a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/components/unassigned.js +++ b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/components/unassigned.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; +import { sortBy } from 'lodash'; import React from 'react'; import { Shard } from './shard'; import { i18n } from '@kbn/i18n'; @@ -36,7 +36,7 @@ export class Unassigned extends React.Component { }; render() { - const shards = _.sortBy(this.props.shards, 'shard').map(this.createShard); + const shards = sortBy(this.props.shards, 'shard').map(this.createShard); return ( diff --git a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/lib/has_primary_children.js b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/lib/has_primary_children.js index 47739b8fe31e8..a371f3e5ff40c 100644 --- a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/lib/has_primary_children.js +++ b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/lib/has_primary_children.js @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; +import { some } from 'lodash'; export function hasPrimaryChildren(item) { - return _.some(item.children, { primary: true }); + return some(item.children, { primary: true }); } diff --git a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/lib/vents.js b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/lib/vents.js index db9b7bacc3cdf..335c3d29a5b9e 100644 --- a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/lib/vents.js +++ b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/lib/vents.js @@ -4,13 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; +import { each, isArray } from 'lodash'; export const _vents = {}; export const vents = { vents: _vents, on: function (id, cb) { - if (!_.isArray(_vents[id])) { + if (!isArray(_vents[id])) { _vents[id] = []; } _vents[id].push(cb); @@ -22,7 +22,7 @@ export const vents = { const args = Array.prototype.slice.call(arguments); const id = args.shift(); if (_vents[id]) { - _.each(_vents[id], function (cb) { + each(_vents[id], function (cb) { cb.apply(null, args); }); } diff --git a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/transformers/indices_by_nodes.js b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/transformers/indices_by_nodes.js index a9808ebc4c6ad..a04e2bcd1786e 100644 --- a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/transformers/indices_by_nodes.js +++ b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/transformers/indices_by_nodes.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; +import { find, reduce, values, sortBy } from 'lodash'; import { decorateShards } from '../lib/decorate_shards'; export function indicesByNodes() { @@ -39,7 +39,7 @@ export function indicesByNodes() { return obj; } - let nodeObj = _.find(obj[index].children, { id: node }); + let nodeObj = find(obj[index].children, { id: node }); if (!nodeObj) { nodeObj = { id: node, @@ -55,7 +55,7 @@ export function indicesByNodes() { return obj; } - const data = _.reduce( + const data = reduce( decorateShards(shards, nodes), function (obj, shard) { obj = createIndex(obj, shard); @@ -64,10 +64,11 @@ export function indicesByNodes() { }, {} ); - - return _(data) - .values() - .sortBy((index) => [!index.unassignedPrimaries, /^\./.test(index.name), index.name]) - .value(); + const dataValues = values(data); + return sortBy(dataValues, (index) => [ + !index.unassignedPrimaries, + /^\./.test(index.name), + index.name, + ]); }; } diff --git a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/transformers/nodes_by_indices.js b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/transformers/nodes_by_indices.js index 353e1c23d4bc1..f8dd5b6cb8e8d 100644 --- a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/transformers/nodes_by_indices.js +++ b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/transformers/nodes_by_indices.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; +import { find, some, reduce, values, sortBy } from 'lodash'; import { hasPrimaryChildren } from '../lib/has_primary_children'; import { decorateShards } from '../lib/decorate_shards'; @@ -32,7 +32,7 @@ export function nodesByIndices() { if (!obj[node]) { createNode(obj, nodes[node], node); } - let indexObj = _.find(obj[node].children, { id: index }); + let indexObj = find(obj[node].children, { id: index }); if (!indexObj) { indexObj = { id: index, @@ -51,7 +51,7 @@ export function nodesByIndices() { } let data = {}; - if (_.some(shards, isUnassigned)) { + if (some(shards, isUnassigned)) { data.unassigned = { name: 'Unassigned', master: false, @@ -60,19 +60,15 @@ export function nodesByIndices() { }; } - data = _.reduce(decorateShards(shards, nodes), createIndexAddShard, data); - - return _(data) - .values() - .sortBy(function (node) { - return [node.name !== 'Unassigned', !node.master, node.name]; - }) - .map(function (node) { - if (node.name === 'Unassigned') { - node.unassignedPrimaries = node.children.some(hasPrimaryChildren); - } - return node; - }) - .value(); + data = reduce(decorateShards(shards, nodes), createIndexAddShard, data); + const dataValues = values(data); + return sortBy(dataValues, function (node) { + return [node.name !== 'Unassigned', !node.master, node.name]; + }).map(function (node) { + if (node.name === 'Unassigned') { + node.unassignedPrimaries = node.children.some(hasPrimaryChildren); + } + return node; + }); }; } diff --git a/x-pack/plugins/monitoring/public/legacy_shims.ts b/x-pack/plugins/monitoring/public/legacy_shims.ts index bb9f73b5e9ddb..c3c903dab38e9 100644 --- a/x-pack/plugins/monitoring/public/legacy_shims.ts +++ b/x-pack/plugins/monitoring/public/legacy_shims.ts @@ -5,7 +5,6 @@ */ import { CoreStart, HttpSetup, IUiSettingsClient } from 'kibana/public'; -import angular from 'angular'; import { Observable } from 'rxjs'; import { HttpRequestInit } from '../../../../src/core/public'; import { MonitoringStartPluginDependencies } from './types'; diff --git a/x-pack/plugins/monitoring/public/lib/calculate_shard_stats.js b/x-pack/plugins/monitoring/public/lib/calculate_shard_stats.js index 6aee89a9817d5..cd504374da2e4 100644 --- a/x-pack/plugins/monitoring/public/lib/calculate_shard_stats.js +++ b/x-pack/plugins/monitoring/public/lib/calculate_shard_stats.js @@ -5,10 +5,10 @@ */ import { set } from '@elastic/safer-lodash-set'; -import _ from 'lodash'; +import { get, each } from 'lodash'; function addOne(obj, key) { - let value = _.get(obj, key); + let value = get(obj, key); set(obj, key, ++value); } @@ -34,8 +34,8 @@ export function calculateShardStats(state) { data[shard.index] = metrics; }; if (state) { - const shards = _.get(state, 'cluster_state.shards'); - _.each(shards, processShards); + const shards = get(state, 'cluster_state.shards'); + each(shards, processShards); } return data; } diff --git a/x-pack/plugins/monitoring/public/lib/get_cluster_from_clusters.js b/x-pack/plugins/monitoring/public/lib/get_cluster_from_clusters.js index 73422219add95..6e05c02ac7338 100644 --- a/x-pack/plugins/monitoring/public/lib/get_cluster_from_clusters.js +++ b/x-pack/plugins/monitoring/public/lib/get_cluster_from_clusters.js @@ -4,16 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; +import { find, first } from 'lodash'; export function getClusterFromClusters(clusters, globalState, unsetGlobalState = false) { const cluster = (() => { - const existingCurrent = _.find(clusters, { cluster_uuid: globalState.cluster_uuid }); + const existingCurrent = find(clusters, { cluster_uuid: globalState.cluster_uuid }); if (existingCurrent) { return existingCurrent; } - const firstCluster = _.first(clusters); + const firstCluster = first(clusters); if (firstCluster && firstCluster.cluster_uuid) { return firstCluster; } diff --git a/x-pack/plugins/monitoring/public/lib/route_init.js b/x-pack/plugins/monitoring/public/lib/route_init.js index eebdfa8692f1a..97ff621ee3164 100644 --- a/x-pack/plugins/monitoring/public/lib/route_init.js +++ b/x-pack/plugins/monitoring/public/lib/route_init.js @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; import { ajaxErrorHandlersProvider } from './ajax_error_handler'; import { isInSetupMode } from './setup_mode'; import { getClusterFromClusters } from './get_cluster_from_clusters'; @@ -13,7 +12,7 @@ export function routeInitProvider(Private, monitoringClusters, globalState, lice const ajaxErrorHandlers = Private(ajaxErrorHandlersProvider); function isOnPage(hash) { - return _.includes(window.location.hash, hash); + return window.location.hash.includes(hash); } /* diff --git a/x-pack/plugins/monitoring/public/plugin.ts b/x-pack/plugins/monitoring/public/plugin.ts index 4c50abb40dd3d..a228c540761b8 100644 --- a/x-pack/plugins/monitoring/public/plugin.ts +++ b/x-pack/plugins/monitoring/public/plugin.ts @@ -22,11 +22,11 @@ import { UI_SETTINGS } from '../../../../src/plugins/data/public'; import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public'; import { MonitoringStartPluginDependencies, MonitoringConfig } from './types'; import { TriggersAndActionsUIPublicPluginSetup } from '../../triggers_actions_ui/public'; -import { createCpuUsageAlertType } from './alerts/cpu_usage_alert'; -import { createMissingMonitoringDataAlertType } from './alerts/missing_monitoring_data_alert'; -import { createLegacyAlertTypes } from './alerts/legacy_alert'; -import { createDiskUsageAlertType } from './alerts/disk_usage_alert'; -import { createMemoryUsageAlertType } from './alerts/memory_usage_alert'; +import { + ALERT_THREAD_POOL_SEARCH_REJECTIONS, + ALERT_THREAD_POOL_WRITE_REJECTIONS, + ALERT_DETAILS, +} from '../common/constants'; interface MonitoringSetupPluginDependencies { home?: HomePublicPluginSetup; @@ -40,7 +40,7 @@ export class MonitoringPlugin Plugin { constructor(private initializerContext: PluginInitializerContext) {} - public setup( + public async setup( core: CoreSetup, plugins: MonitoringSetupPluginDependencies ) { @@ -73,16 +73,7 @@ export class MonitoringPlugin }); } - const { alertTypeRegistry } = plugins.triggersActionsUi; - alertTypeRegistry.register(createCpuUsageAlertType()); - alertTypeRegistry.register(createDiskUsageAlertType()); - alertTypeRegistry.register(createMemoryUsageAlertType()); - alertTypeRegistry.register(createMissingMonitoringDataAlertType()); - - const legacyAlertTypes = createLegacyAlertTypes(); - for (const legacyAlertType of legacyAlertTypes) { - alertTypeRegistry.register(legacyAlertType); - } + await this.registerAlertsAsync(plugins); const app: App = { id, @@ -106,7 +97,6 @@ export class MonitoringPlugin usageCollection: plugins.usageCollection, }; - pluginsStart.kibanaLegacy.loadFontAwesome(); this.setInitialTimefilter(deps); const monitoringApp = new AngularApp(deps); @@ -154,4 +144,41 @@ export class MonitoringPlugin ['showCgroupMetricsLogstash', monitoring.ui.container.logstash.enabled], ]; } + + private registerAlertsAsync = async (plugins: MonitoringSetupPluginDependencies) => { + const { createCpuUsageAlertType } = await import('./alerts/cpu_usage_alert'); + const { createMissingMonitoringDataAlertType } = await import( + './alerts/missing_monitoring_data_alert' + ); + const { createLegacyAlertTypes } = await import('./alerts/legacy_alert'); + const { createDiskUsageAlertType } = await import('./alerts/disk_usage_alert'); + const { createThreadPoolRejectionsAlertType } = await import( + './alerts/thread_pool_rejections_alert' + ); + const { createMemoryUsageAlertType } = await import('./alerts/memory_usage_alert'); + + const { + triggersActionsUi: { alertTypeRegistry }, + } = plugins; + alertTypeRegistry.register(createCpuUsageAlertType()); + alertTypeRegistry.register(createDiskUsageAlertType()); + alertTypeRegistry.register(createMemoryUsageAlertType()); + alertTypeRegistry.register(createMissingMonitoringDataAlertType()); + alertTypeRegistry.register( + createThreadPoolRejectionsAlertType( + ALERT_THREAD_POOL_SEARCH_REJECTIONS, + ALERT_DETAILS[ALERT_THREAD_POOL_SEARCH_REJECTIONS] + ) + ); + alertTypeRegistry.register( + createThreadPoolRejectionsAlertType( + ALERT_THREAD_POOL_WRITE_REJECTIONS, + ALERT_DETAILS[ALERT_THREAD_POOL_WRITE_REJECTIONS] + ) + ); + const legacyAlertTypes = createLegacyAlertTypes(); + for (const legacyAlertType of legacyAlertTypes) { + alertTypeRegistry.register(legacyAlertType); + } + }; } diff --git a/x-pack/plugins/monitoring/public/services/features.js b/x-pack/plugins/monitoring/public/services/features.js index f98af10f8dfb4..5e29353e497d1 100644 --- a/x-pack/plugins/monitoring/public/services/features.js +++ b/x-pack/plugins/monitoring/public/services/features.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; +import { has, isUndefined } from 'lodash'; export function featuresProvider($window) { function getData() { @@ -28,11 +28,11 @@ export function featuresProvider($window) { function isEnabled(featureName, defaultSetting) { const monitoringDataObj = getData(); - if (_.has(monitoringDataObj, featureName)) { + if (has(monitoringDataObj, featureName)) { return monitoringDataObj[featureName]; } - if (_.isUndefined(defaultSetting)) { + if (isUndefined(defaultSetting)) { return false; } diff --git a/x-pack/plugins/monitoring/public/services/title.js b/x-pack/plugins/monitoring/public/services/title.js index 0715f4dc9e0b6..91ef4c32f3b98 100644 --- a/x-pack/plugins/monitoring/public/services/title.js +++ b/x-pack/plugins/monitoring/public/services/title.js @@ -4,13 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; +import { get } from 'lodash'; import { i18n } from '@kbn/i18n'; import { Legacy } from '../legacy_shims'; export function titleProvider($rootScope) { return function changeTitle(cluster, suffix) { - let clusterName = _.get(cluster, 'cluster_name'); + let clusterName = get(cluster, 'cluster_name'); clusterName = clusterName ? `- ${clusterName}` : ''; suffix = suffix ? `- ${suffix}` : ''; $rootScope.$applyAsync(() => { diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.js index 8021ae7e5f63c..7e78170d1117f 100644 --- a/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.js +++ b/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.js @@ -20,6 +20,8 @@ import { MonitoringViewBaseController } from '../../../base_controller'; import { CODE_PATH_ELASTICSEARCH, ALERT_CPU_USAGE, + ALERT_THREAD_POOL_SEARCH_REJECTIONS, + ALERT_THREAD_POOL_WRITE_REJECTIONS, ALERT_MISSING_MONITORING_DATA, ALERT_DISK_USAGE, ALERT_MEMORY_USAGE, @@ -76,6 +78,8 @@ uiRoutes.when('/elasticsearch/nodes/:node/advanced', { alertTypeIds: [ ALERT_CPU_USAGE, ALERT_DISK_USAGE, + ALERT_THREAD_POOL_SEARCH_REJECTIONS, + ALERT_THREAD_POOL_WRITE_REJECTIONS, ALERT_MEMORY_USAGE, ALERT_MISSING_MONITORING_DATA, ], diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js index 5164e93c266ca..586261eecb250 100644 --- a/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js +++ b/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js @@ -21,6 +21,8 @@ import { MonitoringViewBaseController } from '../../base_controller'; import { CODE_PATH_ELASTICSEARCH, ALERT_CPU_USAGE, + ALERT_THREAD_POOL_SEARCH_REJECTIONS, + ALERT_THREAD_POOL_WRITE_REJECTIONS, ALERT_MISSING_MONITORING_DATA, ALERT_DISK_USAGE, ALERT_MEMORY_USAGE, @@ -60,6 +62,8 @@ uiRoutes.when('/elasticsearch/nodes/:node', { alertTypeIds: [ ALERT_CPU_USAGE, ALERT_DISK_USAGE, + ALERT_THREAD_POOL_SEARCH_REJECTIONS, + ALERT_THREAD_POOL_WRITE_REJECTIONS, ALERT_MEMORY_USAGE, ALERT_MISSING_MONITORING_DATA, ], diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/nodes/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/nodes/index.js index e69d572f9560b..3ec9c6235867b 100644 --- a/x-pack/plugins/monitoring/public/views/elasticsearch/nodes/index.js +++ b/x-pack/plugins/monitoring/public/views/elasticsearch/nodes/index.js @@ -19,6 +19,8 @@ import { ELASTICSEARCH_SYSTEM_ID, CODE_PATH_ELASTICSEARCH, ALERT_CPU_USAGE, + ALERT_THREAD_POOL_SEARCH_REJECTIONS, + ALERT_THREAD_POOL_WRITE_REJECTIONS, ALERT_MISSING_MONITORING_DATA, ALERT_DISK_USAGE, ALERT_MEMORY_USAGE, @@ -93,6 +95,8 @@ uiRoutes.when('/elasticsearch/nodes', { alertTypeIds: [ ALERT_CPU_USAGE, ALERT_DISK_USAGE, + ALERT_THREAD_POOL_SEARCH_REJECTIONS, + ALERT_THREAD_POOL_WRITE_REJECTIONS, ALERT_MEMORY_USAGE, ALERT_MISSING_MONITORING_DATA, ], diff --git a/x-pack/plugins/monitoring/server/alerts/alerts_common.ts b/x-pack/plugins/monitoring/server/alerts/alert_helpers.ts similarity index 97% rename from x-pack/plugins/monitoring/server/alerts/alerts_common.ts rename to x-pack/plugins/monitoring/server/alerts/alert_helpers.ts index 41c8bba17df0a..984746e59f06b 100644 --- a/x-pack/plugins/monitoring/server/alerts/alerts_common.ts +++ b/x-pack/plugins/monitoring/server/alerts/alert_helpers.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { AlertMessageDocLinkToken } from './types'; +import { AlertMessageDocLinkToken } from '../../common/types/alerts'; import { AlertMessageTokenType } from '../../common/enums'; export class AlertingDefaults { diff --git a/x-pack/plugins/monitoring/server/alerts/alerts_factory.test.ts b/x-pack/plugins/monitoring/server/alerts/alerts_factory.test.ts index f486061109b39..cc0423051f2aa 100644 --- a/x-pack/plugins/monitoring/server/alerts/alerts_factory.test.ts +++ b/x-pack/plugins/monitoring/server/alerts/alerts_factory.test.ts @@ -60,9 +60,4 @@ describe('AlertsFactory', () => { expect(alert).not.toBeNull(); expect(alert?.type).toBe(ALERT_CPU_USAGE); }); - - it('should get all', () => { - const alerts = AlertsFactory.getAll(); - expect(alerts.length).toBe(10); - }); }); diff --git a/x-pack/plugins/monitoring/server/alerts/alerts_factory.ts b/x-pack/plugins/monitoring/server/alerts/alerts_factory.ts index 22c41c9c60038..efd3d7d5e3b30 100644 --- a/x-pack/plugins/monitoring/server/alerts/alerts_factory.ts +++ b/x-pack/plugins/monitoring/server/alerts/alerts_factory.ts @@ -8,6 +8,8 @@ import { CpuUsageAlert, MissingMonitoringDataAlert, DiskUsageAlert, + ThreadPoolSearchRejectionsAlert, + ThreadPoolWriteRejectionsAlert, MemoryUsageAlert, NodesChangedAlert, ClusterHealthAlert, @@ -23,6 +25,8 @@ import { ALERT_CPU_USAGE, ALERT_MISSING_MONITORING_DATA, ALERT_DISK_USAGE, + ALERT_THREAD_POOL_SEARCH_REJECTIONS, + ALERT_THREAD_POOL_WRITE_REJECTIONS, ALERT_MEMORY_USAGE, ALERT_NODES_CHANGED, ALERT_LOGSTASH_VERSION_MISMATCH, @@ -31,12 +35,14 @@ import { } from '../../common/constants'; import { AlertsClient } from '../../../alerts/server'; -export const BY_TYPE = { +const BY_TYPE = { [ALERT_CLUSTER_HEALTH]: ClusterHealthAlert, [ALERT_LICENSE_EXPIRATION]: LicenseExpirationAlert, [ALERT_CPU_USAGE]: CpuUsageAlert, [ALERT_MISSING_MONITORING_DATA]: MissingMonitoringDataAlert, [ALERT_DISK_USAGE]: DiskUsageAlert, + [ALERT_THREAD_POOL_SEARCH_REJECTIONS]: ThreadPoolSearchRejectionsAlert, + [ALERT_THREAD_POOL_WRITE_REJECTIONS]: ThreadPoolWriteRejectionsAlert, [ALERT_MEMORY_USAGE]: MemoryUsageAlert, [ALERT_NODES_CHANGED]: NodesChangedAlert, [ALERT_LOGSTASH_VERSION_MISMATCH]: LogstashVersionMismatchAlert, diff --git a/x-pack/plugins/monitoring/server/alerts/base_alert.ts b/x-pack/plugins/monitoring/server/alerts/base_alert.ts index c92291cf72093..48b783a450807 100644 --- a/x-pack/plugins/monitoring/server/alerts/base_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/base_alert.ts @@ -28,14 +28,16 @@ import { AlertData, AlertInstanceState, AlertEnableAction, -} from './types'; + CommonAlertFilter, + CommonAlertParams, + CommonBaseAlert, +} from '../../common/types/alerts'; import { fetchAvailableCcs } from '../lib/alerts/fetch_available_ccs'; import { fetchClusters } from '../lib/alerts/fetch_clusters'; import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; import { INDEX_PATTERN_ELASTICSEARCH } from '../../common/constants'; import { MonitoringConfig } from '../config'; import { AlertSeverity } from '../../common/enums'; -import { CommonAlertFilter, CommonAlertParams, CommonBaseAlert } from '../../common/types'; import { MonitoringLicenseService } from '../types'; import { mbSafeQuery } from '../lib/mb_safe_query'; import { appendMetricbeatIndex } from '../lib/alerts/append_mb_index'; @@ -269,18 +271,18 @@ export class BaseAlert { } protected async fetchData( - params: CommonAlertParams, + params: CommonAlertParams | unknown, callCluster: any, clusters: AlertCluster[], uiSettings: IUiSettingsClient, availableCcs: string[] - ): Promise { + ): Promise> { // Child should implement throw new Error('Child classes must implement `fetchData`'); } protected async processData( - data: AlertData[], + data: Array, clusters: AlertCluster[], services: AlertServices, logger: Logger, @@ -365,15 +367,18 @@ export class BaseAlert { }; } - protected getUiMessage(alertState: AlertState, item: AlertData): AlertMessage { + protected getUiMessage( + alertState: AlertState | unknown, + item: AlertData | unknown + ): AlertMessage { throw new Error('Child classes must implement `getUiMessage`'); } protected executeActions( instance: AlertInstance, - instanceState: AlertInstanceState, - item: AlertData, - cluster: AlertCluster + instanceState: AlertInstanceState | unknown, + item: AlertData | unknown, + cluster?: AlertCluster | unknown ) { throw new Error('Child classes must implement `executeActions`'); } diff --git a/x-pack/plugins/monitoring/server/alerts/cluster_health_alert.ts b/x-pack/plugins/monitoring/server/alerts/cluster_health_alert.ts index 427dd2f86de00..1d3d36413ebc2 100644 --- a/x-pack/plugins/monitoring/server/alerts/cluster_health_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/cluster_health_alert.ts @@ -14,15 +14,15 @@ import { AlertMessageLinkToken, AlertInstanceState, LegacyAlert, -} from './types'; + CommonAlertParams, +} from '../../common/types/alerts'; import { AlertInstance } from '../../../alerts/server'; -import { INDEX_ALERTS, ALERT_CLUSTER_HEALTH } from '../../common/constants'; +import { INDEX_ALERTS, ALERT_CLUSTER_HEALTH, LEGACY_ALERT_DETAILS } from '../../common/constants'; import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; import { AlertMessageTokenType, AlertClusterHealthType } from '../../common/enums'; import { fetchLegacyAlerts } from '../lib/alerts/fetch_legacy_alerts'; import { mapLegacySeverity } from '../lib/alerts/map_legacy_severity'; -import { CommonAlertParams } from '../../common/types'; -import { AlertingDefaults } from './alerts_common'; +import { AlertingDefaults } from './alert_helpers'; const RED_STATUS_MESSAGE = i18n.translate('xpack.monitoring.alerts.clusterHealth.redMessage', { defaultMessage: 'Allocate missing primary and replica shards', @@ -39,9 +39,7 @@ const WATCH_NAME = 'elasticsearch_cluster_status'; export class ClusterHealthAlert extends BaseAlert { public type = ALERT_CLUSTER_HEALTH; - public label = i18n.translate('xpack.monitoring.alerts.clusterHealth.label', { - defaultMessage: 'Cluster health', - }); + public label = LEGACY_ALERT_DETAILS[ALERT_CLUSTER_HEALTH].label; public isLegacy = true; protected actionVariables = [ diff --git a/x-pack/plugins/monitoring/server/alerts/cpu_usage_alert.ts b/x-pack/plugins/monitoring/server/alerts/cpu_usage_alert.ts index 09133dadca162..55931e2996cbf 100644 --- a/x-pack/plugins/monitoring/server/alerts/cpu_usage_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/cpu_usage_alert.ts @@ -16,55 +16,36 @@ import { AlertMessageTimeToken, AlertMessageLinkToken, AlertInstanceState, -} from './types'; + CommonAlertFilter, + CommonAlertNodeUuidFilter, + CommonAlertParams, +} from '../../common/types/alerts'; import { AlertInstance, AlertServices } from '../../../alerts/server'; -import { INDEX_PATTERN_ELASTICSEARCH, ALERT_CPU_USAGE } from '../../common/constants'; +import { + INDEX_PATTERN_ELASTICSEARCH, + ALERT_CPU_USAGE, + ALERT_DETAILS, +} from '../../common/constants'; import { fetchCpuUsageNodeStats } from '../lib/alerts/fetch_cpu_usage_node_stats'; import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; -import { AlertMessageTokenType, AlertSeverity, AlertParamType } from '../../common/enums'; +import { AlertMessageTokenType, AlertSeverity } from '../../common/enums'; import { RawAlertInstance } from '../../../alerts/common'; import { parseDuration } from '../../../alerts/common/parse_duration'; -import { - CommonAlertFilter, - CommonAlertNodeUuidFilter, - CommonAlertParams, - CommonAlertParamDetail, -} from '../../common/types'; -import { AlertingDefaults, createLink } from './alerts_common'; +import { AlertingDefaults, createLink } from './alert_helpers'; import { appendMetricbeatIndex } from '../lib/alerts/append_mb_index'; -const DEFAULT_THRESHOLD = 85; -const DEFAULT_DURATION = '5m'; - interface CpuUsageParams { threshold: number; duration: string; } export class CpuUsageAlert extends BaseAlert { - public static paramDetails = { - threshold: { - label: i18n.translate('xpack.monitoring.alerts.cpuUsage.paramDetails.threshold.label', { - defaultMessage: `Notify when CPU is over`, - }), - type: AlertParamType.Percentage, - } as CommonAlertParamDetail, - duration: { - label: i18n.translate('xpack.monitoring.alerts.cpuUsage.paramDetails.duration.label', { - defaultMessage: `Look at the average over`, - }), - type: AlertParamType.Duration, - } as CommonAlertParamDetail, - }; - public type = ALERT_CPU_USAGE; - public label = i18n.translate('xpack.monitoring.alerts.cpuUsage.label', { - defaultMessage: 'CPU Usage', - }); + public label = ALERT_DETAILS[ALERT_CPU_USAGE].label; protected defaultParams: CpuUsageParams = { - threshold: DEFAULT_THRESHOLD, - duration: DEFAULT_DURATION, + threshold: 85, + duration: '5m', }; protected actionVariables = [ diff --git a/x-pack/plugins/monitoring/server/alerts/disk_usage_alert.ts b/x-pack/plugins/monitoring/server/alerts/disk_usage_alert.ts index 34c640de79625..e54e736724357 100644 --- a/x-pack/plugins/monitoring/server/alerts/disk_usage_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/disk_usage_alert.ts @@ -15,43 +15,25 @@ import { AlertMessageTimeToken, AlertMessageLinkToken, AlertInstanceState, -} from './types'; + CommonAlertFilter, + CommonAlertParams, +} from '../../common/types/alerts'; import { AlertInstance, AlertServices } from '../../../alerts/server'; -import { INDEX_PATTERN_ELASTICSEARCH, ALERT_DISK_USAGE } from '../../common/constants'; +import { + INDEX_PATTERN_ELASTICSEARCH, + ALERT_DISK_USAGE, + ALERT_DETAILS, +} from '../../common/constants'; import { fetchDiskUsageNodeStats } from '../lib/alerts/fetch_disk_usage_node_stats'; import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; -import { AlertMessageTokenType, AlertSeverity, AlertParamType } from '../../common/enums'; +import { AlertMessageTokenType, AlertSeverity } from '../../common/enums'; import { RawAlertInstance } from '../../../alerts/common'; -import { CommonAlertFilter, CommonAlertParams, CommonAlertParamDetail } from '../../common/types'; -import { AlertingDefaults, createLink } from './alerts_common'; +import { AlertingDefaults, createLink } from './alert_helpers'; import { appendMetricbeatIndex } from '../lib/alerts/append_mb_index'; -interface ParamDetails { - [key: string]: CommonAlertParamDetail; -} - export class DiskUsageAlert extends BaseAlert { - public static readonly PARAM_DETAILS: ParamDetails = { - threshold: { - label: i18n.translate('xpack.monitoring.alerts.diskUsage.paramDetails.threshold.label', { - defaultMessage: `Notify when disk capacity is over`, - }), - type: AlertParamType.Percentage, - }, - duration: { - label: i18n.translate('xpack.monitoring.alerts.diskUsage.paramDetails.duration.label', { - defaultMessage: `Look at the average over`, - }), - type: AlertParamType.Duration, - }, - }; - public static paramDetails = DiskUsageAlert.PARAM_DETAILS; - public static readonly TYPE = ALERT_DISK_USAGE; - public static readonly LABEL = i18n.translate('xpack.monitoring.alerts.diskUsage.label', { - defaultMessage: 'Disk Usage', - }); - public type = DiskUsageAlert.TYPE; - public label = DiskUsageAlert.LABEL; + public type = ALERT_DISK_USAGE; + public label = ALERT_DETAILS[ALERT_DISK_USAGE].label; protected defaultParams = { threshold: 80, diff --git a/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_alert.ts b/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_alert.ts index f26b21f0c64c5..6412dcfde54bd 100644 --- a/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_alert.ts @@ -13,22 +13,24 @@ import { AlertMessage, AlertInstanceState, LegacyAlert, -} from './types'; + CommonAlertParams, +} from '../../common/types/alerts'; import { AlertInstance } from '../../../alerts/server'; -import { INDEX_ALERTS, ALERT_ELASTICSEARCH_VERSION_MISMATCH } from '../../common/constants'; +import { + INDEX_ALERTS, + ALERT_ELASTICSEARCH_VERSION_MISMATCH, + LEGACY_ALERT_DETAILS, +} from '../../common/constants'; import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; import { AlertSeverity } from '../../common/enums'; -import { CommonAlertParams } from '../../common/types'; import { fetchLegacyAlerts } from '../lib/alerts/fetch_legacy_alerts'; -import { AlertingDefaults } from './alerts_common'; +import { AlertingDefaults } from './alert_helpers'; const WATCH_NAME = 'elasticsearch_version_mismatch'; export class ElasticsearchVersionMismatchAlert extends BaseAlert { public type = ALERT_ELASTICSEARCH_VERSION_MISMATCH; - public label = i18n.translate('xpack.monitoring.alerts.elasticsearchVersionMismatch.label', { - defaultMessage: 'Elasticsearch version mismatch', - }); + public label = LEGACY_ALERT_DETAILS[ALERT_ELASTICSEARCH_VERSION_MISMATCH].label; public isLegacy = true; protected actionVariables = [ diff --git a/x-pack/plugins/monitoring/server/alerts/index.ts b/x-pack/plugins/monitoring/server/alerts/index.ts index 48254f2dec326..5fa718dfb34cd 100644 --- a/x-pack/plugins/monitoring/server/alerts/index.ts +++ b/x-pack/plugins/monitoring/server/alerts/index.ts @@ -8,6 +8,8 @@ export { BaseAlert } from './base_alert'; export { CpuUsageAlert } from './cpu_usage_alert'; export { MissingMonitoringDataAlert } from './missing_monitoring_data_alert'; export { DiskUsageAlert } from './disk_usage_alert'; +export { ThreadPoolSearchRejectionsAlert } from './thread_pool_search_rejections_alert'; +export { ThreadPoolWriteRejectionsAlert } from './thread_pool_write_rejections_alert'; export { MemoryUsageAlert } from './memory_usage_alert'; export { ClusterHealthAlert } from './cluster_health_alert'; export { LicenseExpirationAlert } from './license_expiration_alert'; @@ -15,4 +17,4 @@ export { NodesChangedAlert } from './nodes_changed_alert'; export { ElasticsearchVersionMismatchAlert } from './elasticsearch_version_mismatch_alert'; export { KibanaVersionMismatchAlert } from './kibana_version_mismatch_alert'; export { LogstashVersionMismatchAlert } from './logstash_version_mismatch_alert'; -export { AlertsFactory, BY_TYPE } from './alerts_factory'; +export { AlertsFactory } from './alerts_factory'; diff --git a/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_alert.ts b/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_alert.ts index 316f305603964..851a401635792 100644 --- a/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_alert.ts @@ -13,22 +13,24 @@ import { AlertMessage, AlertInstanceState, LegacyAlert, -} from './types'; + CommonAlertParams, +} from '../../common/types/alerts'; import { AlertInstance } from '../../../alerts/server'; -import { INDEX_ALERTS, ALERT_KIBANA_VERSION_MISMATCH } from '../../common/constants'; +import { + INDEX_ALERTS, + ALERT_KIBANA_VERSION_MISMATCH, + LEGACY_ALERT_DETAILS, +} from '../../common/constants'; import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; import { AlertSeverity } from '../../common/enums'; -import { CommonAlertParams } from '../../common/types'; import { fetchLegacyAlerts } from '../lib/alerts/fetch_legacy_alerts'; -import { AlertingDefaults } from './alerts_common'; +import { AlertingDefaults } from './alert_helpers'; const WATCH_NAME = 'kibana_version_mismatch'; export class KibanaVersionMismatchAlert extends BaseAlert { public type = ALERT_KIBANA_VERSION_MISMATCH; - public label = i18n.translate('xpack.monitoring.alerts.kibanaVersionMismatch.label', { - defaultMessage: 'Kibana version mismatch', - }); + public label = LEGACY_ALERT_DETAILS[ALERT_KIBANA_VERSION_MISMATCH].label; public isLegacy = true; protected actionVariables = [ diff --git a/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.ts b/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.ts index f1412ff0fc91a..e0396ee6673e8 100644 --- a/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.ts @@ -16,27 +16,26 @@ import { AlertMessageLinkToken, AlertInstanceState, LegacyAlert, -} from './types'; + CommonAlertParams, +} from '../../common/types/alerts'; import { AlertInstance } from '../../../alerts/server'; import { INDEX_ALERTS, ALERT_LICENSE_EXPIRATION, FORMAT_DURATION_TEMPLATE_SHORT, + LEGACY_ALERT_DETAILS, } from '../../common/constants'; import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; import { AlertMessageTokenType } from '../../common/enums'; -import { CommonAlertParams } from '../../common/types'; import { fetchLegacyAlerts } from '../lib/alerts/fetch_legacy_alerts'; import { mapLegacySeverity } from '../lib/alerts/map_legacy_severity'; -import { AlertingDefaults } from './alerts_common'; +import { AlertingDefaults } from './alert_helpers'; const WATCH_NAME = 'xpack_license_expiration'; export class LicenseExpirationAlert extends BaseAlert { public type = ALERT_LICENSE_EXPIRATION; - public label = i18n.translate('xpack.monitoring.alerts.licenseExpiration.label', { - defaultMessage: 'License expiration', - }); + public label = LEGACY_ALERT_DETAILS[ALERT_LICENSE_EXPIRATION].label; public isLegacy = true; protected actionVariables = [ { diff --git a/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_alert.ts b/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_alert.ts index 37515e32e591a..7f5c0ea40e36a 100644 --- a/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_alert.ts @@ -13,22 +13,24 @@ import { AlertMessage, AlertInstanceState, LegacyAlert, -} from './types'; + CommonAlertParams, +} from '../../common/types/alerts'; import { AlertInstance } from '../../../alerts/server'; -import { INDEX_ALERTS, ALERT_LOGSTASH_VERSION_MISMATCH } from '../../common/constants'; +import { + INDEX_ALERTS, + ALERT_LOGSTASH_VERSION_MISMATCH, + LEGACY_ALERT_DETAILS, +} from '../../common/constants'; import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; import { AlertSeverity } from '../../common/enums'; -import { CommonAlertParams } from '../../common/types'; import { fetchLegacyAlerts } from '../lib/alerts/fetch_legacy_alerts'; -import { AlertingDefaults } from './alerts_common'; +import { AlertingDefaults } from './alert_helpers'; const WATCH_NAME = 'logstash_version_mismatch'; export class LogstashVersionMismatchAlert extends BaseAlert { public type = ALERT_LOGSTASH_VERSION_MISMATCH; - public label = i18n.translate('xpack.monitoring.alerts.logstashVersionMismatch.label', { - defaultMessage: 'Logstash version mismatch', - }); + public label = LEGACY_ALERT_DETAILS[ALERT_LOGSTASH_VERSION_MISMATCH].label; public isLegacy = true; protected actionVariables = [ diff --git a/x-pack/plugins/monitoring/server/alerts/memory_usage_alert.ts b/x-pack/plugins/monitoring/server/alerts/memory_usage_alert.ts index 8dc707afab1e1..c37176764c020 100644 --- a/x-pack/plugins/monitoring/server/alerts/memory_usage_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/memory_usage_alert.ts @@ -15,44 +15,26 @@ import { AlertMessageTimeToken, AlertMessageLinkToken, AlertInstanceState, -} from './types'; + CommonAlertFilter, + CommonAlertParams, +} from '../../common/types/alerts'; import { AlertInstance, AlertServices } from '../../../alerts/server'; -import { INDEX_PATTERN_ELASTICSEARCH, ALERT_MEMORY_USAGE } from '../../common/constants'; +import { + INDEX_PATTERN_ELASTICSEARCH, + ALERT_MEMORY_USAGE, + ALERT_DETAILS, +} from '../../common/constants'; import { fetchMemoryUsageNodeStats } from '../lib/alerts/fetch_memory_usage_node_stats'; import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; -import { AlertMessageTokenType, AlertSeverity, AlertParamType } from '../../common/enums'; +import { AlertMessageTokenType, AlertSeverity } from '../../common/enums'; import { RawAlertInstance } from '../../../alerts/common'; -import { CommonAlertFilter, CommonAlertParams, CommonAlertParamDetail } from '../../common/types'; -import { AlertingDefaults, createLink } from './alerts_common'; +import { AlertingDefaults, createLink } from './alert_helpers'; import { appendMetricbeatIndex } from '../lib/alerts/append_mb_index'; import { parseDuration } from '../../../alerts/common/parse_duration'; -interface ParamDetails { - [key: string]: CommonAlertParamDetail; -} - export class MemoryUsageAlert extends BaseAlert { - public static readonly PARAM_DETAILS: ParamDetails = { - threshold: { - label: i18n.translate('xpack.monitoring.alerts.memoryUsage.paramDetails.threshold.label', { - defaultMessage: `Notify when memory usage is over`, - }), - type: AlertParamType.Percentage, - }, - duration: { - label: i18n.translate('xpack.monitoring.alerts.memoryUsage.paramDetails.duration.label', { - defaultMessage: `Look at the average over`, - }), - type: AlertParamType.Duration, - }, - }; - public static paramDetails = MemoryUsageAlert.PARAM_DETAILS; - public static readonly TYPE = ALERT_MEMORY_USAGE; - public static readonly LABEL = i18n.translate('xpack.monitoring.alerts.memoryUsage.label', { - defaultMessage: 'Memory Usage (JVM)', - }); - public type = MemoryUsageAlert.TYPE; - public label = MemoryUsageAlert.LABEL; + public type = ALERT_MEMORY_USAGE; + public label = ALERT_DETAILS[ALERT_MEMORY_USAGE].label; protected defaultParams = { threshold: 85, diff --git a/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_alert.ts b/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_alert.ts index 5b4542a4439ca..456ad92855f65 100644 --- a/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_alert.ts @@ -16,24 +16,22 @@ import { AlertMissingData, AlertMessageTimeToken, AlertInstanceState, -} from './types'; + CommonAlertFilter, + CommonAlertParams, + CommonAlertStackProductFilter, + CommonAlertNodeUuidFilter, +} from '../../common/types/alerts'; import { AlertInstance, AlertServices } from '../../../alerts/server'; import { INDEX_PATTERN, ALERT_MISSING_MONITORING_DATA, INDEX_PATTERN_ELASTICSEARCH, + ALERT_DETAILS, } from '../../common/constants'; import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; -import { AlertMessageTokenType, AlertSeverity, AlertParamType } from '../../common/enums'; +import { AlertMessageTokenType, AlertSeverity } from '../../common/enums'; import { RawAlertInstance } from '../../../alerts/common'; import { parseDuration } from '../../../alerts/common/parse_duration'; -import { - CommonAlertFilter, - CommonAlertParams, - CommonAlertParamDetail, - CommonAlertStackProductFilter, - CommonAlertNodeUuidFilter, -} from '../../common/types'; import { appendMetricbeatIndex } from '../lib/alerts/append_mb_index'; import { fetchMissingMonitoringData } from '../lib/alerts/fetch_missing_monitoring_data'; import { getTypeLabelForStackProduct } from '../lib/alerts/get_type_label_for_stack_product'; @@ -41,7 +39,7 @@ import { getListingLinkForStackProduct } from '../lib/alerts/get_listing_link_fo import { getStackProductLabel } from '../lib/alerts/get_stack_product_label'; import { fetchClusters } from '../lib/alerts/fetch_clusters'; import { fetchAvailableCcs } from '../lib/alerts/fetch_available_ccs'; -import { AlertingDefaults, createLink } from './alerts_common'; +import { AlertingDefaults, createLink } from './alert_helpers'; const RESOLVED = i18n.translate('xpack.monitoring.alerts.missingData.resolved', { defaultMessage: 'resolved', @@ -62,27 +60,10 @@ interface MissingDataParams { } export class MissingMonitoringDataAlert extends BaseAlert { - public static paramDetails = { - duration: { - label: i18n.translate('xpack.monitoring.alerts.missingData.paramDetails.duration.label', { - defaultMessage: `Notify if monitoring data is missing for the last`, - }), - type: AlertParamType.Duration, - } as CommonAlertParamDetail, - limit: { - label: i18n.translate('xpack.monitoring.alerts.missingData.paramDetails.limit.label', { - defaultMessage: `looking back`, - }), - type: AlertParamType.Duration, - } as CommonAlertParamDetail, - }; - public defaultThrottle: string = '6h'; public type = ALERT_MISSING_MONITORING_DATA; - public label = i18n.translate('xpack.monitoring.alerts.missingData.label', { - defaultMessage: 'Missing monitoring data', - }); + public label = ALERT_DETAILS[ALERT_MISSING_MONITORING_DATA].label; protected defaultParams: MissingDataParams = { duration: DEFAULT_DURATION, diff --git a/x-pack/plugins/monitoring/server/alerts/nodes_changed_alert.ts b/x-pack/plugins/monitoring/server/alerts/nodes_changed_alert.ts index e03e6ea53ab4e..7b54ef629cba6 100644 --- a/x-pack/plugins/monitoring/server/alerts/nodes_changed_alert.ts +++ b/x-pack/plugins/monitoring/server/alerts/nodes_changed_alert.ts @@ -14,22 +14,20 @@ import { AlertInstanceState, LegacyAlert, LegacyAlertNodesChangedList, -} from './types'; + CommonAlertParams, +} from '../../common/types/alerts'; import { AlertInstance } from '../../../alerts/server'; -import { INDEX_ALERTS, ALERT_NODES_CHANGED } from '../../common/constants'; +import { INDEX_ALERTS, ALERT_NODES_CHANGED, LEGACY_ALERT_DETAILS } from '../../common/constants'; import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; -import { CommonAlertParams } from '../../common/types'; import { fetchLegacyAlerts } from '../lib/alerts/fetch_legacy_alerts'; import { mapLegacySeverity } from '../lib/alerts/map_legacy_severity'; -import { AlertingDefaults } from './alerts_common'; +import { AlertingDefaults } from './alert_helpers'; const WATCH_NAME = 'elasticsearch_nodes'; export class NodesChangedAlert extends BaseAlert { public type = ALERT_NODES_CHANGED; - public label = i18n.translate('xpack.monitoring.alerts.nodesChanged.label', { - defaultMessage: 'Nodes changed', - }); + public label = LEGACY_ALERT_DETAILS[ALERT_NODES_CHANGED].label; public isLegacy = true; protected actionVariables = [ diff --git a/x-pack/plugins/monitoring/server/alerts/thread_pool_rejections_alert_base.ts b/x-pack/plugins/monitoring/server/alerts/thread_pool_rejections_alert_base.ts new file mode 100644 index 0000000000000..4905ae73b0545 --- /dev/null +++ b/x-pack/plugins/monitoring/server/alerts/thread_pool_rejections_alert_base.ts @@ -0,0 +1,312 @@ +/* + * 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 { IUiSettingsClient, Logger } from 'kibana/server'; +import { i18n } from '@kbn/i18n'; +import { BaseAlert } from './base_alert'; +import { + AlertData, + AlertCluster, + AlertMessage, + AlertThreadPoolRejectionsState, + AlertMessageTimeToken, + AlertMessageLinkToken, + CommonAlertFilter, + ThreadPoolRejectionsAlertParams, +} from '../../common/types/alerts'; +import { AlertInstance, AlertServices } from '../../../alerts/server'; +import { INDEX_PATTERN_ELASTICSEARCH } from '../../common/constants'; +import { fetchThreadPoolRejectionStats } from '../lib/alerts/fetch_thread_pool_rejections_stats'; +import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; +import { AlertMessageTokenType, AlertSeverity } from '../../common/enums'; +import { Alert, RawAlertInstance } from '../../../alerts/common'; +import { AlertingDefaults, createLink } from './alert_helpers'; +import { appendMetricbeatIndex } from '../lib/alerts/append_mb_index'; + +type ActionVariables = Array<{ name: string; description: string }>; + +export class ThreadPoolRejectionsAlertBase extends BaseAlert { + protected static createActionVariables(type: string) { + return [ + { + name: 'count', + description: i18n.translate( + 'xpack.monitoring.alerts.threadPoolRejections.actionVariables.count', + { + defaultMessage: 'The number of nodes reporting high thread pool {type} rejections.', + values: { type }, + } + ), + }, + ...Object.values(AlertingDefaults.ALERT_TYPE.context), + ]; + } + + protected defaultParams: ThreadPoolRejectionsAlertParams = { + threshold: 300, + duration: '5m', + }; + + constructor( + rawAlert: Alert | undefined = undefined, + public readonly type: string, + public readonly threadPoolType: string, + public readonly label: string, + public readonly actionVariables: ActionVariables + ) { + super(rawAlert); + } + + protected async fetchData( + params: ThreadPoolRejectionsAlertParams, + callCluster: any, + clusters: AlertCluster[], + uiSettings: IUiSettingsClient, + availableCcs: string[] + ): Promise { + let esIndexPattern = appendMetricbeatIndex(this.config, INDEX_PATTERN_ELASTICSEARCH); + if (availableCcs) { + esIndexPattern = getCcsIndexPattern(esIndexPattern, availableCcs); + } + + const { threshold, duration } = params; + + const stats = await fetchThreadPoolRejectionStats( + callCluster, + clusters, + esIndexPattern, + this.config.ui.max_bucket_size, + this.threadPoolType, + duration + ); + + return stats.map((stat) => { + const { clusterUuid, nodeId, rejectionCount, ccs } = stat; + + return { + instanceKey: `${clusterUuid}:${nodeId}`, + shouldFire: rejectionCount > threshold, + rejectionCount, + severity: AlertSeverity.Danger, + meta: stat, + clusterUuid, + ccs, + }; + }); + } + + protected filterAlertInstance(alertInstance: RawAlertInstance, filters: CommonAlertFilter[]) { + const alertInstanceStates = alertInstance.state + ?.alertStates as AlertThreadPoolRejectionsState[]; + const nodeUuid = filters?.find((filter) => filter.nodeUuid)?.nodeUuid; + + if (!alertInstanceStates?.length || !nodeUuid) { + return true; + } + + const nodeAlerts = alertInstanceStates.filter(({ nodeId }) => nodeId === nodeUuid); + return Boolean(nodeAlerts.length); + } + + protected getUiMessage( + alertState: AlertThreadPoolRejectionsState, + rejectionCount: number + ): AlertMessage { + const { nodeName, nodeId } = alertState; + return { + text: i18n.translate('xpack.monitoring.alerts.threadPoolRejections.ui.firingMessage', { + defaultMessage: `Node #start_link{nodeName}#end_link is reporting {rejectionCount} {type} rejections at #absolute`, + values: { + nodeName, + type: this.threadPoolType, + rejectionCount, + }, + }), + nextSteps: [ + createLink( + i18n.translate( + 'xpack.monitoring.alerts.threadPoolRejections.ui.nextSteps.monitorThisNode', + { + defaultMessage: `#start_linkMonitor this node#end_link`, + } + ), + `elasticsearch/nodes/${nodeId}/advanced`, + AlertMessageTokenType.Link + ), + createLink( + i18n.translate( + 'xpack.monitoring.alerts.threadPoolRejections.ui.nextSteps.optimizeQueries', + { + defaultMessage: '#start_linkOptimize complex queries#end_link', + } + ), + `{elasticWebsiteUrl}blog/advanced-tuning-finding-and-fixing-slow-elasticsearch-queries` + ), + createLink( + i18n.translate('xpack.monitoring.alerts.threadPoolRejections.ui.nextSteps.addMoreNodes', { + defaultMessage: '#start_linkAdd more nodes#end_link', + }), + `{elasticWebsiteUrl}guide/en/elasticsearch/reference/{docLinkVersion}/add-elasticsearch-nodes.html` + ), + createLink( + i18n.translate( + 'xpack.monitoring.alerts.threadPoolRejections.ui.nextSteps.resizeYourDeployment', + { + defaultMessage: '#start_linkResize your deployment (ECE)#end_link', + } + ), + `{elasticWebsiteUrl}guide/en/cloud-enterprise/current/ece-resize-deployment.html` + ), + createLink( + i18n.translate( + 'xpack.monitoring.alerts.threadPoolRejections.ui.nextSteps.threadPoolSettings', + { + defaultMessage: '#start_linkThread pool settings#end_link', + } + ), + `{elasticWebsiteUrl}guide/en/elasticsearch/reference/{docLinkVersion}/modules-threadpool.html` + ), + ], + tokens: [ + { + startToken: '#absolute', + type: AlertMessageTokenType.Time, + isAbsolute: true, + isRelative: false, + timestamp: alertState.ui.triggeredMS, + } as AlertMessageTimeToken, + { + startToken: '#start_link', + endToken: '#end_link', + type: AlertMessageTokenType.Link, + url: `elasticsearch/nodes/${nodeId}`, + } as AlertMessageLinkToken, + ], + }; + } + + protected executeActions( + instance: AlertInstance, + alertStates: AlertThreadPoolRejectionsState[], + cluster: AlertCluster + ) { + const type = this.threadPoolType; + const count = alertStates.length; + const { clusterName: clusterKnownName, clusterUuid } = cluster; + const clusterName = clusterKnownName || clusterUuid; + const shortActionText = i18n.translate( + 'xpack.monitoring.alerts.threadPoolRejections.shortAction', + { + defaultMessage: 'Verify thread pool {type} rejections across affected nodes.', + values: { + type, + }, + } + ); + + const fullActionText = i18n.translate( + 'xpack.monitoring.alerts.threadPoolRejections.fullAction', + { + defaultMessage: 'View nodes', + } + ); + + const ccs = alertStates.find((state) => state.ccs)?.ccs; + const globalStateLink = this.createGlobalStateLink('elasticsearch/nodes', clusterUuid, ccs); + + const action = `[${fullActionText}](${globalStateLink})`; + const internalShortMessage = i18n.translate( + 'xpack.monitoring.alerts.threadPoolRejections.firing.internalShortMessage', + { + defaultMessage: `Thread pool {type} rejections alert is firing for {count} node(s) in cluster: {clusterName}. {shortActionText}`, + values: { + count, + clusterName, + shortActionText, + type, + }, + } + ); + const internalFullMessage = i18n.translate( + 'xpack.monitoring.alerts.threadPoolRejections.firing.internalFullMessage', + { + defaultMessage: `Thread pool {type} rejections alert is firing for {count} node(s) in cluster: {clusterName}. {action}`, + values: { + count, + clusterName, + action, + type, + }, + } + ); + + instance.scheduleActions('default', { + internalShortMessage, + internalFullMessage: this.isCloud ? internalShortMessage : internalFullMessage, + threadPoolType: type, + state: AlertingDefaults.ALERT_STATE.firing, + count, + clusterName, + action, + actionPlain: shortActionText, + }); + } + + protected async processData( + data: AlertData[], + clusters: AlertCluster[], + services: AlertServices, + logger: Logger, + state: { lastChecked?: number } + ) { + const currentUTC = +new Date(); + for (const cluster of clusters) { + const nodes = data.filter((node) => node.clusterUuid === cluster.clusterUuid); + if (!nodes.length) { + continue; + } + + const firingNodeUuids = nodes.filter((node) => node.shouldFire); + + if (!firingNodeUuids.length) { + continue; + } + + const instanceSuffix = firingNodeUuids.map((node) => node.meta.nodeId); + + const instancePrefix = `${this.type}:${cluster.clusterUuid}:`; + const alertInstanceId = `${instancePrefix}:${instanceSuffix}`; + const alertInstance = services.alertInstanceFactory(alertInstanceId); + const newAlertStates: AlertThreadPoolRejectionsState[] = []; + + for (const node of nodes) { + if (!node.shouldFire) { + continue; + } + const stat = node.meta as AlertThreadPoolRejectionsState; + const nodeState = this.getDefaultAlertState( + cluster, + node + ) as AlertThreadPoolRejectionsState; + const { nodeId, nodeName, rejectionCount } = stat; + nodeState.nodeId = nodeId; + nodeState.nodeName = nodeName; + nodeState.ui.triggeredMS = currentUTC; + nodeState.ui.isFiring = true; + nodeState.ui.severity = node.severity; + nodeState.ui.message = this.getUiMessage(nodeState, rejectionCount); + newAlertStates.push(nodeState); + } + + alertInstance.replaceState({ alertStates: newAlertStates }); + if (newAlertStates.length) { + this.executeActions(alertInstance, newAlertStates, cluster); + } + } + + state.lastChecked = currentUTC; + return state; + } +} diff --git a/x-pack/plugins/monitoring/server/alerts/thread_pool_search_rejections_alert.ts b/x-pack/plugins/monitoring/server/alerts/thread_pool_search_rejections_alert.ts new file mode 100644 index 0000000000000..10df95c05ba3f --- /dev/null +++ b/x-pack/plugins/monitoring/server/alerts/thread_pool_search_rejections_alert.ts @@ -0,0 +1,26 @@ +/* + * 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 { ThreadPoolRejectionsAlertBase } from './thread_pool_rejections_alert_base'; +import { ALERT_THREAD_POOL_SEARCH_REJECTIONS, ALERT_DETAILS } from '../../common/constants'; +import { Alert } from '../../../alerts/common'; + +export class ThreadPoolSearchRejectionsAlert extends ThreadPoolRejectionsAlertBase { + private static TYPE = ALERT_THREAD_POOL_SEARCH_REJECTIONS; + private static THREAD_POOL_TYPE = 'search'; + private static readonly LABEL = ALERT_DETAILS[ALERT_THREAD_POOL_SEARCH_REJECTIONS].label; + constructor(rawAlert?: Alert) { + super( + rawAlert, + ThreadPoolSearchRejectionsAlert.TYPE, + ThreadPoolSearchRejectionsAlert.THREAD_POOL_TYPE, + ThreadPoolSearchRejectionsAlert.LABEL, + ThreadPoolRejectionsAlertBase.createActionVariables( + ThreadPoolSearchRejectionsAlert.THREAD_POOL_TYPE + ) + ); + } +} diff --git a/x-pack/plugins/monitoring/server/alerts/thread_pool_write_rejections_alert.ts b/x-pack/plugins/monitoring/server/alerts/thread_pool_write_rejections_alert.ts new file mode 100644 index 0000000000000..d415515315b37 --- /dev/null +++ b/x-pack/plugins/monitoring/server/alerts/thread_pool_write_rejections_alert.ts @@ -0,0 +1,26 @@ +/* + * 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 { ThreadPoolRejectionsAlertBase } from './thread_pool_rejections_alert_base'; +import { ALERT_THREAD_POOL_WRITE_REJECTIONS, ALERT_DETAILS } from '../../common/constants'; +import { Alert } from '../../../alerts/common'; + +export class ThreadPoolWriteRejectionsAlert extends ThreadPoolRejectionsAlertBase { + private static TYPE = ALERT_THREAD_POOL_WRITE_REJECTIONS; + private static THREAD_POOL_TYPE = 'write'; + private static readonly LABEL = ALERT_DETAILS[ALERT_THREAD_POOL_WRITE_REJECTIONS].label; + constructor(rawAlert?: Alert) { + super( + rawAlert, + ThreadPoolWriteRejectionsAlert.TYPE, + ThreadPoolWriteRejectionsAlert.THREAD_POOL_TYPE, + ThreadPoolWriteRejectionsAlert.LABEL, + ThreadPoolRejectionsAlertBase.createActionVariables( + ThreadPoolWriteRejectionsAlert.THREAD_POOL_TYPE + ) + ); + } +} diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.ts index d474338bce922..368a909279b8c 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { get } from 'lodash'; -import { AlertCluster } from '../../alerts/types'; +import { AlertCluster } from '../../../common/types/alerts'; interface RangeFilter { [field: string]: { diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.ts index ecd324c083a8c..b38a32164223e 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.ts @@ -6,7 +6,7 @@ import { get } from 'lodash'; import moment from 'moment'; import { NORMALIZED_DERIVATIVE_UNIT } from '../../../common/constants'; -import { AlertCluster, AlertCpuUsageNodeStats } from '../../alerts/types'; +import { AlertCluster, AlertCpuUsageNodeStats } from '../../../common/types/alerts'; interface NodeBucketESResponse { key: string; diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.ts index 6201204ebebe0..f00c42d708b16 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.ts @@ -5,7 +5,7 @@ */ import { get } from 'lodash'; -import { AlertCluster, AlertDiskUsageNodeStats } from '../../alerts/types'; +import { AlertCluster, AlertDiskUsageNodeStats } from '../../../common/types/alerts'; export async function fetchDiskUsageNodeStats( callCluster: any, diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_legacy_alerts.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_legacy_alerts.ts index fe01a1b921c2e..fbf7608a737ba 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_legacy_alerts.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_legacy_alerts.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { get } from 'lodash'; -import { LegacyAlert, AlertCluster, LegacyAlertMetadata } from '../../alerts/types'; +import { LegacyAlert, AlertCluster, LegacyAlertMetadata } from '../../../common/types/alerts'; export async function fetchLegacyAlerts( callCluster: any, diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.ts index c6843c3ed5f12..9a68b3afc7758 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.ts @@ -5,7 +5,7 @@ */ import { get } from 'lodash'; -import { AlertCluster, AlertMemoryUsageNodeStats } from '../../alerts/types'; +import { AlertCluster, AlertMemoryUsageNodeStats } from '../../../common/types/alerts'; export async function fetchMemoryUsageNodeStats( callCluster: any, diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.ts index 91fc05137a8c1..49307764e9f01 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { get } from 'lodash'; -import { AlertCluster, AlertMissingData } from '../../alerts/types'; +import { AlertCluster, AlertMissingData } from '../../../common/types/alerts'; import { KIBANA_SYSTEM_ID, BEATS_SYSTEM_ID, diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.test.ts index 824eeab7245b4..c31ab91866b1d 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.test.ts @@ -5,7 +5,7 @@ */ import { fetchStatus } from './fetch_status'; -import { AlertUiState, AlertState } from '../../alerts/types'; +import { AlertUiState, AlertState } from '../../../common/types/alerts'; import { AlertSeverity } from '../../../common/enums'; import { ALERT_CPU_USAGE, diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.ts index ed49f42e4908c..ed860ee21344d 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.ts @@ -4,10 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ import moment from 'moment'; -import { AlertInstanceState } from '../../alerts/types'; +import { AlertInstanceState } from '../../../common/types/alerts'; import { AlertsClient } from '../../../../alerts/server'; import { AlertsFactory } from '../../alerts'; -import { CommonAlertStatus, CommonAlertState, CommonAlertFilter } from '../../../common/types'; +import { + CommonAlertStatus, + CommonAlertState, + CommonAlertFilter, +} from '../../../common/types/alerts'; import { ALERTS } from '../../../common/constants'; import { MonitoringLicenseService } from '../../types'; diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_thread_pool_rejections_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_thread_pool_rejections_stats.ts new file mode 100644 index 0000000000000..664ceb1d9411b --- /dev/null +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_thread_pool_rejections_stats.ts @@ -0,0 +1,141 @@ +/* + * 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 { get } from 'lodash'; +import { AlertCluster, AlertThreadPoolRejectionsStats } from '../../../common/types/alerts'; + +const invalidNumberValue = (value: number) => { + return isNaN(value) || value === undefined || value === null; +}; + +const getTopHits = (threadType: string, order: string) => ({ + top_hits: { + sort: [ + { + timestamp: { + order, + unmapped_type: 'long', + }, + }, + ], + _source: { + includes: [`node_stats.thread_pool.${threadType}.rejected`, 'source_node.name'], + }, + size: 1, + }, +}); + +export async function fetchThreadPoolRejectionStats( + callCluster: any, + clusters: AlertCluster[], + index: string, + size: number, + threadType: string, + duration: string +): Promise { + const clustersIds = clusters.map((cluster) => cluster.clusterUuid); + const params = { + index, + filterPath: ['aggregations'], + body: { + size: 0, + query: { + bool: { + filter: [ + { + terms: { + cluster_uuid: clustersIds, + }, + }, + { + term: { + type: 'node_stats', + }, + }, + { + range: { + timestamp: { + gte: `now-${duration}`, + }, + }, + }, + ], + }, + }, + aggs: { + clusters: { + terms: { + field: 'cluster_uuid', + size, + }, + aggs: { + nodes: { + terms: { + field: 'source_node.uuid', + size, + }, + aggs: { + most_recent: { + ...getTopHits(threadType, 'desc'), + }, + least_recent: { + ...getTopHits(threadType, 'asc'), + }, + }, + }, + }, + }, + }, + }, + }; + + const response = await callCluster('search', params); + const stats: AlertThreadPoolRejectionsStats[] = []; + const { buckets: clusterBuckets = [] } = response.aggregations.clusters; + + if (!clusterBuckets.length) { + return stats; + } + + for (const clusterBucket of clusterBuckets) { + for (const node of clusterBucket.nodes.buckets) { + const mostRecentDoc = get(node, 'most_recent.hits.hits[0]'); + mostRecentDoc.timestamp = mostRecentDoc.sort[0]; + + const leastRecentDoc = get(node, 'least_recent.hits.hits[0]'); + leastRecentDoc.timestamp = leastRecentDoc.sort[0]; + + if (!mostRecentDoc || mostRecentDoc.timestamp === leastRecentDoc.timestamp) { + continue; + } + + const rejectedPath = `_source.node_stats.thread_pool.${threadType}.rejected`; + const newRejectionCount = Number(get(mostRecentDoc, rejectedPath)); + const oldRejectionCount = Number(get(leastRecentDoc, rejectedPath)); + + if (invalidNumberValue(newRejectionCount) || invalidNumberValue(oldRejectionCount)) { + continue; + } + + const rejectionCount = + oldRejectionCount > newRejectionCount + ? newRejectionCount + : newRejectionCount - oldRejectionCount; + const indexName = mostRecentDoc._index; + const nodeName = get(mostRecentDoc, '_source.source_node.name') || node.key; + const nodeStat = { + rejectionCount, + type: threadType, + clusterUuid: clusterBucket.key, + nodeId: node.key, + nodeName, + ccs: indexName.includes(':') ? indexName.split(':')[0] : null, + }; + stats.push(nodeStat); + } + } + return stats; +} diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts index d97bc34c2adb0..29a27ac3d05e7 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts @@ -9,7 +9,7 @@ import { schema } from '@kbn/config-schema'; import { handleError } from '../../../../lib/errors'; import { RouteDependencies } from '../../../../types'; import { fetchStatus } from '../../../../lib/alerts/fetch_status'; -import { CommonAlertFilter } from '../../../../../common/types'; +import { CommonAlertFilter } from '../../../../../common/types/alerts'; export function alertStatusRoute(server: any, npRoute: RouteDependencies) { npRoute.router.post( From f5b1faea4703b8263bdb3a5ec025564b0af5e422 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Fri, 30 Oct 2020 15:52:30 +0100 Subject: [PATCH 73/80] [Chrome] Extension to append an element to the last breadcrumb (#82015) --- ...omestart.getbreadcrumbsappendextension_.md | 17 ++++ .../kibana-plugin-core-public.chromestart.md | 2 + ...romestart.setbreadcrumbsappendextension.md | 24 +++++ src/core/public/chrome/chrome_service.mock.ts | 3 + src/core/public/chrome/chrome_service.test.ts | 73 +++++++++----- src/core/public/chrome/chrome_service.tsx | 30 ++++++ .../header/__snapshots__/header.test.tsx.snap | 98 +++++++++++++++++++ .../public/chrome/ui/header/header.test.tsx | 1 + src/core/public/chrome/ui/header/header.tsx | 4 +- .../ui/header/header_breadcrumbs.test.tsx | 32 +++++- .../chrome/ui/header/header_breadcrumbs.tsx | 17 +++- .../ui/header/header_extension.test.tsx | 8 ++ .../chrome/ui/header/header_extension.tsx | 8 +- src/core/public/public.api.md | 3 + 14 files changed, 288 insertions(+), 32 deletions(-) create mode 100644 docs/development/core/public/kibana-plugin-core-public.chromestart.getbreadcrumbsappendextension_.md create mode 100644 docs/development/core/public/kibana-plugin-core-public.chromestart.setbreadcrumbsappendextension.md diff --git a/docs/development/core/public/kibana-plugin-core-public.chromestart.getbreadcrumbsappendextension_.md b/docs/development/core/public/kibana-plugin-core-public.chromestart.getbreadcrumbsappendextension_.md new file mode 100644 index 0000000000000..dfe25c5c9e42d --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.chromestart.getbreadcrumbsappendextension_.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ChromeStart](./kibana-plugin-core-public.chromestart.md) > [getBreadcrumbsAppendExtension$](./kibana-plugin-core-public.chromestart.getbreadcrumbsappendextension_.md) + +## ChromeStart.getBreadcrumbsAppendExtension$() method + +Get an observable of the current extension appended to breadcrumbs + +Signature: + +```typescript +getBreadcrumbsAppendExtension$(): Observable; +``` +Returns: + +`Observable` + diff --git a/docs/development/core/public/kibana-plugin-core-public.chromestart.md b/docs/development/core/public/kibana-plugin-core-public.chromestart.md index 2594848ef0847..663b326193de5 100644 --- a/docs/development/core/public/kibana-plugin-core-public.chromestart.md +++ b/docs/development/core/public/kibana-plugin-core-public.chromestart.md @@ -55,6 +55,7 @@ core.chrome.setHelpExtension(elem => { | [getBadge$()](./kibana-plugin-core-public.chromestart.getbadge_.md) | Get an observable of the current badge | | [getBrand$()](./kibana-plugin-core-public.chromestart.getbrand_.md) | Get an observable of the current brand information. | | [getBreadcrumbs$()](./kibana-plugin-core-public.chromestart.getbreadcrumbs_.md) | Get an observable of the current list of breadcrumbs | +| [getBreadcrumbsAppendExtension$()](./kibana-plugin-core-public.chromestart.getbreadcrumbsappendextension_.md) | Get an observable of the current extension appended to breadcrumbs | | [getCustomNavLink$()](./kibana-plugin-core-public.chromestart.getcustomnavlink_.md) | Get an observable of the current custom nav link | | [getHelpExtension$()](./kibana-plugin-core-public.chromestart.gethelpextension_.md) | Get an observable of the current custom help conttent | | [getIsNavDrawerLocked$()](./kibana-plugin-core-public.chromestart.getisnavdrawerlocked_.md) | Get an observable of the current locked state of the nav drawer. | @@ -64,6 +65,7 @@ core.chrome.setHelpExtension(elem => { | [setBadge(badge)](./kibana-plugin-core-public.chromestart.setbadge.md) | Override the current badge | | [setBrand(brand)](./kibana-plugin-core-public.chromestart.setbrand.md) | Set the brand configuration. | | [setBreadcrumbs(newBreadcrumbs)](./kibana-plugin-core-public.chromestart.setbreadcrumbs.md) | Override the current set of breadcrumbs | +| [setBreadcrumbsAppendExtension(breadcrumbsAppendExtension)](./kibana-plugin-core-public.chromestart.setbreadcrumbsappendextension.md) | Mount an element next to the last breadcrumb | | [setCustomNavLink(newCustomNavLink)](./kibana-plugin-core-public.chromestart.setcustomnavlink.md) | Override the current set of custom nav link | | [setHelpExtension(helpExtension)](./kibana-plugin-core-public.chromestart.sethelpextension.md) | Override the current set of custom help content | | [setHelpSupportUrl(url)](./kibana-plugin-core-public.chromestart.sethelpsupporturl.md) | Override the default support URL shown in the help menu | diff --git a/docs/development/core/public/kibana-plugin-core-public.chromestart.setbreadcrumbsappendextension.md b/docs/development/core/public/kibana-plugin-core-public.chromestart.setbreadcrumbsappendextension.md new file mode 100644 index 0000000000000..02adb9b4d325d --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.chromestart.setbreadcrumbsappendextension.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ChromeStart](./kibana-plugin-core-public.chromestart.md) > [setBreadcrumbsAppendExtension](./kibana-plugin-core-public.chromestart.setbreadcrumbsappendextension.md) + +## ChromeStart.setBreadcrumbsAppendExtension() method + +Mount an element next to the last breadcrumb + +Signature: + +```typescript +setBreadcrumbsAppendExtension(breadcrumbsAppendExtension?: ChromeBreadcrumbsAppendExtension): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| breadcrumbsAppendExtension | ChromeBreadcrumbsAppendExtension | | + +Returns: + +`void` + diff --git a/src/core/public/chrome/chrome_service.mock.ts b/src/core/public/chrome/chrome_service.mock.ts index cbcd23615d34c..6df8d57c8c574 100644 --- a/src/core/public/chrome/chrome_service.mock.ts +++ b/src/core/public/chrome/chrome_service.mock.ts @@ -63,6 +63,8 @@ const createStartContractMock = () => { setBadge: jest.fn(), getBreadcrumbs$: jest.fn(), setBreadcrumbs: jest.fn(), + getBreadcrumbsAppendExtension$: jest.fn(), + setBreadcrumbsAppendExtension: jest.fn(), getHelpExtension$: jest.fn(), setHelpExtension: jest.fn(), setHelpSupportUrl: jest.fn(), @@ -76,6 +78,7 @@ const createStartContractMock = () => { startContract.getApplicationClasses$.mockReturnValue(new BehaviorSubject(['class-name'])); startContract.getBadge$.mockReturnValue(new BehaviorSubject({} as ChromeBadge)); startContract.getBreadcrumbs$.mockReturnValue(new BehaviorSubject([{} as ChromeBreadcrumb])); + startContract.getBreadcrumbsAppendExtension$.mockReturnValue(new BehaviorSubject(undefined)); startContract.getCustomNavLink$.mockReturnValue(new BehaviorSubject(undefined)); startContract.getHelpExtension$.mockReturnValue(new BehaviorSubject(undefined)); startContract.getIsNavDrawerLocked$.mockReturnValue(new BehaviorSubject(false)); diff --git a/src/core/public/chrome/chrome_service.test.ts b/src/core/public/chrome/chrome_service.test.ts index 0150554a60906..3783f3bd9b65e 100644 --- a/src/core/public/chrome/chrome_service.test.ts +++ b/src/core/public/chrome/chrome_service.test.ts @@ -363,6 +363,25 @@ describe('start', () => { }); }); + describe('breadcrumbsAppendExtension$', () => { + it('updates the breadcrumbsAppendExtension$', async () => { + const { chrome, service } = await start(); + const promise = chrome.getBreadcrumbsAppendExtension$().pipe(toArray()).toPromise(); + + chrome.setBreadcrumbsAppendExtension({ content: (element) => () => {} }); + service.stop(); + + await expect(promise).resolves.toMatchInlineSnapshot(` + Array [ + undefined, + Object { + "content": [Function], + }, + ] + `); + }); + }); + describe('custom nav link', () => { it('updates/emits the current custom nav link', async () => { const { chrome, service } = await start(); @@ -429,33 +448,33 @@ describe('start', () => { expect(docTitleResetSpy).toBeCalledTimes(1); await expect(promises).resolves.toMatchInlineSnapshot(` - Array [ - Array [ - undefined, - Object { - "appName": "App name", - }, - undefined, - ], - Array [ - Array [], - Array [ - Object { - "text": "App breadcrumb", - }, - ], - Array [], - ], - Array [ - undefined, - Object { - "text": "App badge", - "tooltip": "App tooltip", - }, - undefined, - ], - ] - `); + Array [ + Array [ + undefined, + Object { + "appName": "App name", + }, + undefined, + ], + Array [ + Array [], + Array [ + Object { + "text": "App breadcrumb", + }, + ], + Array [], + ], + Array [ + undefined, + Object { + "text": "App badge", + "tooltip": "App tooltip", + }, + undefined, + ], + ] + `); }); }); }); diff --git a/src/core/public/chrome/chrome_service.tsx b/src/core/public/chrome/chrome_service.tsx index b01f120b81305..b39c83498859c 100644 --- a/src/core/public/chrome/chrome_service.tsx +++ b/src/core/public/chrome/chrome_service.tsx @@ -24,6 +24,7 @@ import { BehaviorSubject, combineLatest, merge, Observable, of, ReplaySubject } import { flatMap, map, takeUntil } from 'rxjs/operators'; import { parse } from 'url'; import { EuiLink } from '@elastic/eui'; +import { MountPoint } from '../types'; import { mountReactNode } from '../utils/mount'; import { InternalApplicationStart } from '../application'; import { DocLinksStart } from '../doc_links'; @@ -58,6 +59,11 @@ export interface ChromeBrand { /** @public */ export type ChromeBreadcrumb = EuiBreadcrumb; +/** @public */ +export interface ChromeBreadcrumbsAppendExtension { + content: MountPoint; +} + /** @public */ export interface ChromeHelpExtension { /** @@ -146,6 +152,9 @@ export class ChromeService { const applicationClasses$ = new BehaviorSubject>(new Set()); const helpExtension$ = new BehaviorSubject(undefined); const breadcrumbs$ = new BehaviorSubject([]); + const breadcrumbsAppendExtension$ = new BehaviorSubject< + ChromeBreadcrumbsAppendExtension | undefined + >(undefined); const badge$ = new BehaviorSubject(undefined); const customNavLink$ = new BehaviorSubject(undefined); const helpSupportUrl$ = new BehaviorSubject(KIBANA_ASK_ELASTIC_LINK); @@ -225,6 +234,7 @@ export class ChromeService { badge$={badge$.pipe(takeUntil(this.stop$))} basePath={http.basePath} breadcrumbs$={breadcrumbs$.pipe(takeUntil(this.stop$))} + breadcrumbsAppendExtension$={breadcrumbsAppendExtension$.pipe(takeUntil(this.stop$))} customNavLink$={customNavLink$.pipe(takeUntil(this.stop$))} kibanaDocLink={docLinks.links.kibana} forceAppSwitcherNavigation$={navLinks.getForceAppSwitcherNavigation$()} @@ -290,6 +300,14 @@ export class ChromeService { breadcrumbs$.next(newBreadcrumbs); }, + getBreadcrumbsAppendExtension$: () => breadcrumbsAppendExtension$.pipe(takeUntil(this.stop$)), + + setBreadcrumbsAppendExtension: ( + breadcrumbsAppendExtension?: ChromeBreadcrumbsAppendExtension + ) => { + breadcrumbsAppendExtension$.next(breadcrumbsAppendExtension); + }, + getHelpExtension$: () => helpExtension$.pipe(takeUntil(this.stop$)), setHelpExtension: (helpExtension?: ChromeHelpExtension) => { @@ -431,6 +449,18 @@ export interface ChromeStart { */ setBreadcrumbs(newBreadcrumbs: ChromeBreadcrumb[]): void; + /** + * Get an observable of the current extension appended to breadcrumbs + */ + getBreadcrumbsAppendExtension$(): Observable; + + /** + * Mount an element next to the last breadcrumb + */ + setBreadcrumbsAppendExtension( + breadcrumbsAppendExtension?: ChromeBreadcrumbsAppendExtension + ): void; + /** * Get an observable of the current custom nav link */ diff --git a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap index 34c5f213a7221..ee2fcbd5078af 100644 --- a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap +++ b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap @@ -300,6 +300,55 @@ exports[`Header renders 1`] = ` "thrownError": null, } } + breadcrumbsAppendExtension$={ + BehaviorSubject { + "_isScalar": false, + "_value": undefined, + "closed": false, + "hasError": false, + "isStopped": false, + "observers": Array [ + Subscriber { + "_parentOrParents": null, + "_subscriptions": Array [ + SubjectSubscription { + "_parentOrParents": [Circular], + "_subscriptions": null, + "closed": false, + "subject": [Circular], + "subscriber": [Circular], + }, + ], + "closed": false, + "destination": SafeSubscriber { + "_complete": undefined, + "_context": [Circular], + "_error": undefined, + "_next": [Function], + "_parentOrParents": null, + "_parentSubscriber": [Circular], + "_subscriptions": null, + "closed": false, + "destination": Object { + "closed": true, + "complete": [Function], + "error": [Function], + "next": [Function], + }, + "isStopped": false, + "syncErrorThrowable": false, + "syncErrorThrown": false, + "syncErrorValue": null, + }, + "isStopped": false, + "syncErrorThrowable": true, + "syncErrorThrown": false, + "syncErrorValue": null, + }, + ], + "thrownError": null, + } + } customNavLink$={ BehaviorSubject { "_isScalar": false, @@ -5029,6 +5078,55 @@ exports[`Header renders 1`] = ` "thrownError": null, } } + breadcrumbsAppendExtension$={ + BehaviorSubject { + "_isScalar": false, + "_value": undefined, + "closed": false, + "hasError": false, + "isStopped": false, + "observers": Array [ + Subscriber { + "_parentOrParents": null, + "_subscriptions": Array [ + SubjectSubscription { + "_parentOrParents": [Circular], + "_subscriptions": null, + "closed": false, + "subject": [Circular], + "subscriber": [Circular], + }, + ], + "closed": false, + "destination": SafeSubscriber { + "_complete": undefined, + "_context": [Circular], + "_error": undefined, + "_next": [Function], + "_parentOrParents": null, + "_parentSubscriber": [Circular], + "_subscriptions": null, + "closed": false, + "destination": Object { + "closed": true, + "complete": [Function], + "error": [Function], + "next": [Function], + }, + "isStopped": false, + "syncErrorThrowable": false, + "syncErrorThrown": false, + "syncErrorValue": null, + }, + "isStopped": false, + "syncErrorThrowable": true, + "syncErrorThrown": false, + "syncErrorValue": null, + }, + ], + "thrownError": null, + } + } > ; badge$: Observable; breadcrumbs$: Observable; + breadcrumbsAppendExtension$: Observable; customNavLink$: Observable; homeHref: string; isVisible$: Observable; @@ -169,6 +170,7 @@ export function Header({ diff --git a/src/core/public/chrome/ui/header/header_breadcrumbs.test.tsx b/src/core/public/chrome/ui/header/header_breadcrumbs.test.tsx index 7fe2c91087090..64401171d142a 100644 --- a/src/core/public/chrome/ui/header/header_breadcrumbs.test.tsx +++ b/src/core/public/chrome/ui/header/header_breadcrumbs.test.tsx @@ -22,12 +22,17 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import { BehaviorSubject } from 'rxjs'; import { HeaderBreadcrumbs } from './header_breadcrumbs'; +import { ChromeBreadcrumbsAppendExtension } from '../../chrome_service'; describe('HeaderBreadcrumbs', () => { it('renders updates to the breadcrumbs$ observable', () => { const breadcrumbs$ = new BehaviorSubject([{ text: 'First' }]); const wrapper = mount( - + ); expect(wrapper.find('.euiBreadcrumb')).toMatchSnapshot(); @@ -39,4 +44,29 @@ describe('HeaderBreadcrumbs', () => { wrapper.update(); expect(wrapper.find('.euiBreadcrumb')).toMatchSnapshot(); }); + + it('renders breadcrumbs extension', () => { + const breadcrumbs$ = new BehaviorSubject([{ text: 'First' }]); + const breadcrumbsAppendExtension$ = new BehaviorSubject< + undefined | ChromeBreadcrumbsAppendExtension + >({ + content: (root: HTMLDivElement) => { + root.innerHTML = '
__render__
'; + return () => (root.innerHTML = ''); + }, + }); + + const wrapper = mount( + + ); + + expect(wrapper.find('.euiBreadcrumb').getDOMNode().querySelector('my-extension')).toBeDefined(); + act(() => breadcrumbsAppendExtension$.next(undefined)); + wrapper.update(); + expect(wrapper.find('.euiBreadcrumb').getDOMNode().querySelector('my-extension')).toBeNull(); + }); }); diff --git a/src/core/public/chrome/ui/header/header_breadcrumbs.tsx b/src/core/public/chrome/ui/header/header_breadcrumbs.tsx index 52412f8990c7a..d52faa87cfecd 100644 --- a/src/core/public/chrome/ui/header/header_breadcrumbs.tsx +++ b/src/core/public/chrome/ui/header/header_breadcrumbs.tsx @@ -22,16 +22,19 @@ import classNames from 'classnames'; import React from 'react'; import useObservable from 'react-use/lib/useObservable'; import { Observable } from 'rxjs'; -import { ChromeBreadcrumb } from '../../chrome_service'; +import { ChromeBreadcrumb, ChromeBreadcrumbsAppendExtension } from '../../chrome_service'; +import { HeaderExtension } from './header_extension'; interface Props { appTitle$: Observable; breadcrumbs$: Observable; + breadcrumbsAppendExtension$: Observable; } -export function HeaderBreadcrumbs({ appTitle$, breadcrumbs$ }: Props) { +export function HeaderBreadcrumbs({ appTitle$, breadcrumbs$, breadcrumbsAppendExtension$ }: Props) { const appTitle = useObservable(appTitle$, 'Kibana'); const breadcrumbs = useObservable(breadcrumbs$, []); + const breadcrumbsAppendExtension = useObservable(breadcrumbsAppendExtension$); let crumbs = breadcrumbs; if (breadcrumbs.length === 0 && appTitle) { @@ -48,5 +51,15 @@ export function HeaderBreadcrumbs({ appTitle$, breadcrumbs$ }: Props) { ), })); + if (breadcrumbsAppendExtension) { + const lastCrumb = crumbs[crumbs.length - 1]; + lastCrumb.text = ( + <> + {lastCrumb.text} + + + ); + } + return ; } diff --git a/src/core/public/chrome/ui/header/header_extension.test.tsx b/src/core/public/chrome/ui/header/header_extension.test.tsx index 3d5678b8bb7ef..ba00c74b81cfa 100644 --- a/src/core/public/chrome/ui/header/header_extension.test.tsx +++ b/src/core/public/chrome/ui/header/header_extension.test.tsx @@ -32,6 +32,14 @@ describe('HeaderExtension', () => { expect(divNode).toBeInstanceOf(HTMLElement); }); + it('calls navControl.render with div node as inlineBlock', () => { + const renderSpy = jest.fn(); + mount(); + + const [divNode] = renderSpy.mock.calls[0]; + expect(divNode).toHaveAttribute('style', 'display: inline-block;'); + }); + it('calls unrender callback when unmounted', () => { const unrenderSpy = jest.fn(); const render = () => unrenderSpy; diff --git a/src/core/public/chrome/ui/header/header_extension.tsx b/src/core/public/chrome/ui/header/header_extension.tsx index 76413a0ea0317..97cf38f44c3f1 100644 --- a/src/core/public/chrome/ui/header/header_extension.tsx +++ b/src/core/public/chrome/ui/header/header_extension.tsx @@ -22,6 +22,7 @@ import { MountPoint } from '../../../types'; interface Props { extension?: MountPoint; + display?: 'block' | 'inlineBlock'; } export class HeaderExtension extends React.Component { @@ -46,7 +47,12 @@ export class HeaderExtension extends React.Component { } public render() { - return
; + return ( +
+ ); } private renderExtension() { diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index f52d5b6fbd6a5..4babec38a936e 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -343,6 +343,8 @@ export interface ChromeStart { getBadge$(): Observable; getBrand$(): Observable; getBreadcrumbs$(): Observable; + // Warning: (ae-forgotten-export) The symbol "ChromeBreadcrumbsAppendExtension" needs to be exported by the entry point index.d.ts + getBreadcrumbsAppendExtension$(): Observable; getCustomNavLink$(): Observable | undefined>; getHelpExtension$(): Observable; getIsNavDrawerLocked$(): Observable; @@ -355,6 +357,7 @@ export interface ChromeStart { setBadge(badge?: ChromeBadge): void; setBrand(brand: ChromeBrand): void; setBreadcrumbs(newBreadcrumbs: ChromeBreadcrumb[]): void; + setBreadcrumbsAppendExtension(breadcrumbsAppendExtension?: ChromeBreadcrumbsAppendExtension): void; setCustomNavLink(newCustomNavLink?: Partial): void; setHelpExtension(helpExtension?: ChromeHelpExtension): void; setHelpSupportUrl(url: string): void; From 7833fb36f18eb30f9c50298adf7c05c99c271822 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Fri, 30 Oct 2020 17:38:37 +0100 Subject: [PATCH 74/80] [Search] fix cancelation related memory leaks (#81996) --- .../data/common/utils/abort_utils.test.ts | 79 +++++++++++++++++-- src/plugins/data/common/utils/abort_utils.ts | 35 ++++++-- .../data/public/search/search_interceptor.ts | 7 +- .../expressions/common/execution/execution.ts | 22 +++--- .../execution/execution_contract.test.ts | 2 +- .../public/search/search_interceptor.ts | 5 +- 6 files changed, 121 insertions(+), 29 deletions(-) diff --git a/src/plugins/data/common/utils/abort_utils.test.ts b/src/plugins/data/common/utils/abort_utils.test.ts index ca187e95f528b..358f00e5e82bd 100644 --- a/src/plugins/data/common/utils/abort_utils.test.ts +++ b/src/plugins/data/common/utils/abort_utils.test.ts @@ -41,7 +41,7 @@ describe('AbortUtils', () => { describe('rejects', () => { test('should not reject if the signal does not abort', async () => { const controller = new AbortController(); - const promise = toPromise(controller.signal); + const promise = toPromise(controller.signal).promise; const whenRejected = jest.fn(); promise.catch(whenRejected); await flushPromises(); @@ -50,7 +50,7 @@ describe('AbortUtils', () => { test('should reject if the signal does abort', async () => { const controller = new AbortController(); - const promise = toPromise(controller.signal); + const promise = toPromise(controller.signal).promise; const whenRejected = jest.fn(); promise.catch(whenRejected); controller.abort(); @@ -58,13 +58,30 @@ describe('AbortUtils', () => { expect(whenRejected).toBeCalled(); expect(whenRejected.mock.calls[0][0]).toBeInstanceOf(AbortError); }); + + test('should expose cleanup handler', () => { + const controller = new AbortController(); + const promise = toPromise(controller.signal); + expect(promise.cleanup).toBeDefined(); + }); + + test('calling clean up handler prevents rejects', async () => { + const controller = new AbortController(); + const { promise, cleanup } = toPromise(controller.signal); + const whenRejected = jest.fn(); + promise.catch(whenRejected); + cleanup(); + controller.abort(); + await flushPromises(); + expect(whenRejected).not.toBeCalled(); + }); }); }); describe('getCombinedSignal', () => { test('should return an AbortSignal', () => { - const signal = getCombinedSignal([]); - expect(signal instanceof AbortSignal).toBe(true); + const signal = getCombinedSignal([]).signal; + expect(signal).toBeInstanceOf(AbortSignal); }); test('should not abort if none of the signals abort', async () => { @@ -72,7 +89,7 @@ describe('AbortUtils', () => { const controller2 = new AbortController(); setTimeout(() => controller1.abort(), 2000); setTimeout(() => controller2.abort(), 1000); - const signal = getCombinedSignal([controller1.signal, controller2.signal]); + const signal = getCombinedSignal([controller1.signal, controller2.signal]).signal; expect(signal.aborted).toBe(false); jest.advanceTimersByTime(500); await flushPromises(); @@ -84,7 +101,7 @@ describe('AbortUtils', () => { const controller2 = new AbortController(); setTimeout(() => controller1.abort(), 2000); setTimeout(() => controller2.abort(), 1000); - const signal = getCombinedSignal([controller1.signal, controller2.signal]); + const signal = getCombinedSignal([controller1.signal, controller2.signal]).signal; expect(signal.aborted).toBe(false); jest.advanceTimersByTime(1000); await flushPromises(); @@ -95,8 +112,56 @@ describe('AbortUtils', () => { const controller1 = new AbortController(); const controller2 = new AbortController(); controller1.abort(); - const signal = getCombinedSignal([controller1.signal, controller2.signal]); + const signal = getCombinedSignal([controller1.signal, controller2.signal]).signal; expect(signal.aborted).toBe(true); }); + + describe('cleanup listener', () => { + const createMockController = () => { + const controller = new AbortController(); + const spyAddListener = jest.spyOn(controller.signal, 'addEventListener'); + const spyRemoveListener = jest.spyOn(controller.signal, 'removeEventListener'); + return { + controller, + getTotalListeners: () => + Math.max(spyAddListener.mock.calls.length - spyRemoveListener.mock.calls.length, 0), + }; + }; + + test('cleanup should cleanup inner listeners', () => { + const controller1 = createMockController(); + const controller2 = createMockController(); + + const { cleanup } = getCombinedSignal([ + controller1.controller.signal, + controller2.controller.signal, + ]); + + expect(controller1.getTotalListeners()).toBe(1); + expect(controller2.getTotalListeners()).toBe(1); + + cleanup(); + + expect(controller1.getTotalListeners()).toBe(0); + expect(controller2.getTotalListeners()).toBe(0); + }); + + test('abort should cleanup inner listeners', async () => { + const controller1 = createMockController(); + const controller2 = createMockController(); + + getCombinedSignal([controller1.controller.signal, controller2.controller.signal]); + + expect(controller1.getTotalListeners()).toBe(1); + expect(controller2.getTotalListeners()).toBe(1); + + controller1.controller.abort(); + + await flushPromises(); + + expect(controller1.getTotalListeners()).toBe(0); + expect(controller2.getTotalListeners()).toBe(0); + }); + }); }); }); diff --git a/src/plugins/data/common/utils/abort_utils.ts b/src/plugins/data/common/utils/abort_utils.ts index a26fec9423f83..81f30b7454c7b 100644 --- a/src/plugins/data/common/utils/abort_utils.ts +++ b/src/plugins/data/common/utils/abort_utils.ts @@ -36,15 +36,23 @@ export class AbortError extends Error { * * @param signal The `AbortSignal` to generate the `Promise` from */ -export function toPromise(signal: AbortSignal): Promise { - return new Promise((resolve, reject) => { - if (signal.aborted) reject(new AbortError()); - const abortHandler = () => { +export function toPromise(signal: AbortSignal): { promise: Promise; cleanup: () => void } { + let abortHandler: () => void; + const cleanup = () => { + if (abortHandler) { signal.removeEventListener('abort', abortHandler); + } + }; + const promise = new Promise((resolve, reject) => { + if (signal.aborted) reject(new AbortError()); + abortHandler = () => { + cleanup(); reject(new AbortError()); }; signal.addEventListener('abort', abortHandler); }); + + return { promise, cleanup }; } /** @@ -52,13 +60,26 @@ export function toPromise(signal: AbortSignal): Promise { * * @param signals */ -export function getCombinedSignal(signals: AbortSignal[]) { +export function getCombinedSignal( + signals: AbortSignal[] +): { signal: AbortSignal; cleanup: () => void } { const controller = new AbortController(); + let cleanup = () => {}; + if (signals.some((signal) => signal.aborted)) { controller.abort(); } else { const promises = signals.map((signal) => toPromise(signal)); - Promise.race(promises).catch(() => controller.abort()); + cleanup = () => { + promises.forEach((p) => p.cleanup()); + controller.signal.removeEventListener('abort', cleanup); + }; + controller.signal.addEventListener('abort', cleanup); + Promise.race(promises.map((p) => p.promise)).catch(() => { + cleanup(); + controller.abort(); + }); } - return controller.signal; + + return { signal: controller.signal, cleanup }; } diff --git a/src/plugins/data/public/search/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor.ts index 087ca9e4f5c47..0f069d54ee9c8 100644 --- a/src/plugins/data/public/search/search_interceptor.ts +++ b/src/plugins/data/public/search/search_interceptor.ts @@ -24,13 +24,13 @@ import { PublicMethodsOf } from '@kbn/utility-types'; import { CoreStart, CoreSetup, ToastsSetup } from 'kibana/public'; import { i18n } from '@kbn/i18n'; import { - getCombinedSignal, AbortError, IKibanaSearchRequest, IKibanaSearchResponse, ISearchOptions, ES_SEARCH_STRATEGY, ISessionService, + getCombinedSignal, } from '../../common'; import { SearchUsageCollector } from './collectors'; import { @@ -171,11 +171,12 @@ export class SearchInterceptor { ...(abortSignal ? [abortSignal] : []), ]; - const combinedSignal = getCombinedSignal(signals); + const { signal: combinedSignal, cleanup: cleanupCombinedSignal } = getCombinedSignal(signals); const cleanup = () => { subscription.unsubscribe(); + combinedSignal.removeEventListener('abort', cleanup); + cleanupCombinedSignal(); }; - combinedSignal.addEventListener('abort', cleanup); return { diff --git a/src/plugins/expressions/common/execution/execution.ts b/src/plugins/expressions/common/execution/execution.ts index 2bcf441b14203..ba115a7538604 100644 --- a/src/plugins/expressions/common/execution/execution.ts +++ b/src/plugins/expressions/common/execution/execution.ts @@ -99,7 +99,7 @@ export class Execution< * Races a given promise against the "abort" event of `abortController`. */ private race(promise: Promise): Promise { - return Promise.race([this.abortRejection, promise]); + return Promise.race([this.abortRejection.promise, promise]); } /** @@ -189,14 +189,18 @@ export class Execution< else reject(error); }); - this.firstResultFuture.promise.then( - (result) => { - this.state.transitions.setResult(result); - }, - (error) => { - this.state.transitions.setError(error); - } - ); + this.firstResultFuture.promise + .then( + (result) => { + this.state.transitions.setResult(result); + }, + (error) => { + this.state.transitions.setError(error); + } + ) + .finally(() => { + this.abortRejection.cleanup(); + }); } async invokeChain(chainArr: ExpressionAstFunction[], input: unknown): Promise { diff --git a/src/plugins/expressions/common/execution/execution_contract.test.ts b/src/plugins/expressions/common/execution/execution_contract.test.ts index 856b22470d782..eaf7e6ea862eb 100644 --- a/src/plugins/expressions/common/execution/execution_contract.test.ts +++ b/src/plugins/expressions/common/execution/execution_contract.test.ts @@ -59,7 +59,7 @@ describe('ExecutionContract', () => { test('can cancel execution', () => { const execution = createExecution('foo bar=123'); - const spy = jest.spyOn(execution, 'cancel'); + const spy = jest.spyOn(execution, 'cancel').mockImplementation(() => {}); const contract = new ExecutionContract(execution); expect(spy).toHaveBeenCalledTimes(0); diff --git a/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts b/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts index aee32a7c62759..3226ecf6f0dda 100644 --- a/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts +++ b/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts @@ -64,7 +64,7 @@ export class EnhancedSearchInterceptor extends SearchInterceptor { abortSignal: options.abortSignal, timeout: this.searchTimeout, }); - const aborted$ = from(toPromise(combinedSignal)); + const abortedPromise = toPromise(combinedSignal); const strategy = options?.strategy || ENHANCED_ES_SEARCH_STRATEGY; this.pendingCount$.next(this.pendingCount$.getValue() + 1); @@ -90,7 +90,7 @@ export class EnhancedSearchInterceptor extends SearchInterceptor { }) ); }), - takeUntil(aborted$), + takeUntil(from(abortedPromise.promise)), catchError((e: any) => { // If we haven't received the response to the initial request, including the ID, then // we don't need to send a follow-up request to delete this search. Otherwise, we @@ -103,6 +103,7 @@ export class EnhancedSearchInterceptor extends SearchInterceptor { finalize(() => { this.pendingCount$.next(this.pendingCount$.getValue() - 1); cleanup(); + abortedPromise.cleanup(); }) ); } From ecf3483730614fd0653825b39766bc1e87d05460 Mon Sep 17 00:00:00 2001 From: James Rodewig <40268737+jrodewig@users.noreply.github.com> Date: Fri, 30 Oct 2020 13:03:31 -0400 Subject: [PATCH 75/80] [DOCS] Remove index mgmt docs (#82099) --- .../management-index-templates-mappings.png | Bin 238638 -> 0 bytes .../images/management-index-templates.png | Bin 83706 -> 0 bytes .../management_index_component_template.png | Bin 73463 -> 0 bytes .../images/management_index_create_wizard.png | Bin 75138 -> 0 bytes ...gement_index_data_stream_backing_index.png | Bin 83747 -> 0 bytes .../management_index_data_stream_stats.png | Bin 99196 -> 0 bytes .../images/management_index_details.png | Bin 87055 -> 0 bytes .../images/management_index_labels.png | Bin 290179 -> 0 bytes docs/management/managing-indices.asciidoc | 258 ------------------ docs/management/watcher-ui/index.asciidoc | 2 +- docs/redirects.asciidoc | 5 + docs/user/management.asciidoc | 4 +- 12 files changed, 7 insertions(+), 262 deletions(-) delete mode 100644 docs/management/images/management-index-templates-mappings.png delete mode 100644 docs/management/images/management-index-templates.png delete mode 100644 docs/management/images/management_index_component_template.png delete mode 100644 docs/management/images/management_index_create_wizard.png delete mode 100644 docs/management/images/management_index_data_stream_backing_index.png delete mode 100644 docs/management/images/management_index_data_stream_stats.png delete mode 100644 docs/management/images/management_index_details.png delete mode 100644 docs/management/images/management_index_labels.png delete mode 100644 docs/management/managing-indices.asciidoc diff --git a/docs/management/images/management-index-templates-mappings.png b/docs/management/images/management-index-templates-mappings.png deleted file mode 100644 index beb964b348171fbc6ff19d58fa18478f96c2f09c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238638 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 diff --git a/docs/management/images/management-index-templates.png b/docs/management/images/management-index-templates.png deleted file mode 100644 index 07f1fb9a7add11baf20498991b00b19224d9edc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83706 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 diff --git a/docs/management/images/management_index_component_template.png b/docs/management/images/management_index_component_template.png deleted file mode 100644 index c03029fd172f05df731a355d4f9dc7c24e8b71c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73463 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˨XH;y%6fFYSV?hr7Ys1E=uK4H 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 diff --git a/docs/management/images/management_index_data_stream_backing_index.png b/docs/management/images/management_index_data_stream_backing_index.png deleted file mode 100644 index a5c577affbbb2d3fd23ae4e04b21f0c809575765..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83747 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 diff --git a/docs/management/images/management_index_data_stream_stats.png b/docs/management/images/management_index_data_stream_stats.png deleted file mode 100644 index a67ab4a7deb320df493ebe563e8aba8c03c45d9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99196 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 St_2S8(Nxt_sk>(#^?v{!__xRa diff --git a/docs/management/images/management_index_labels.png b/docs/management/images/management_index_labels.png deleted file mode 100644 index a89c32e08beff1b601967630e000fae8a15210df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 290179 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

  • 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%0D`kU#x||BF@5+sIr-KOTOKm%h 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 Index Management*. - -[role="screenshot"] -image::images/management_index_labels.png[Index Management UI] - -[float] -=== Before you start - -Before using this feature, you should be familiar with index management -operations. Refer to the {ref}/indices.html[index management APIs], the -{ref}/indices-templates.html[index template APIs], and the -{ref}/data-streams.html[data streams documentation]. - -[float] -=== Required permissions - -The minimum required permissions to access *Index Management* are -the `monitor` cluster privilege and the `view_index_metadata` -and `manage` index privileges to view the data. -For index templates, you must have the `manage_index_templates` cluster privilege. -See {ref}/security-privileges.html[Security privileges] for more -information. - -You can add these privileges in *Stack Management > Security > Roles*. - -[float] -=== View and edit indices - -When you open *Index Management*, you’re presented an overview of your configured indices. -Badges indicate if an index is {ref}/frozen-indices.html[frozen], -a {ref}/ccr-put-follow.html[follower index], -or a {ref}/rollup-get-rollup-index-caps.html[rollup index]. - -Clicking a badge narrows the list to only indices of that type. -You can also filter your indices using the search bar. - -You can drill down into each index to investigate the index -{ref}/index-modules.html#index-modules-settings[settings], {ref}/mapping.html[mapping], and statistics. -From this view, you can also edit the index settings. - -[role="screenshot"] -image::images/management_index_details.png[Index Management UI] - -[float] -=== Perform index-level operations - -Use the *Manage* menu to perform index-level operations. This menu -is available in the index details view, or when you select the checkbox of one or more -indices on the overview page. The menu includes the following actions: - -* *Close index*. Blocks the index from read/write operations. -A closed index exists in the cluster, but doesn't consume resources -other than disk space. If you reopen a closed index, it goes through the -normal recovery process. - -* *Force merge index*. Reduces the number of segments in your shard by -merging smaller files and clearing deleted ones. Only force merge a read-only index. - -* *Refresh index*. Writes the operations in the indexing buffer to the -filesystem cache. This action is automatically performed once per second. Forcing a manual -refresh is useful during testing, but should not be routinely done in -production because it has a performance impact. - -* *Clear index cache*. Clears all caches associated with the index. - -* *Flush index*. Frees memory by syncing the filesystem cache to disk and -clearing the cache. Once the sync is complete, the internal transaction log is reset. - -* *Freeze index*. Makes the index read-only and reduces its memory footprint -by moving shards to disk. Frozen indices remain -searchable, but queries take longer. - -* *Delete index*. Permanently removes the index and all of its documents. - -* *Add lifecycle policy*. Specifies a policy for managing the lifecycle of the -index. - -[float] -[[manage-data-streams]] -=== Manage data streams - -A {ref}/data-streams.html[data stream] lets you store time series data across -multiple backing indices while giving you a single named resource to use in -requests. The *Data Streams* view lists your data streams and lets you examine -or delete them. - -To view more information about a data stream, such as its generation or its -current index lifecycle policy, click the stream's name. - -[role="screenshot"] -image::images/management_index_data_stream_stats.png[Data stream details] - -To view information about the stream's backing indices, click the number in the -*Indices* column. - -[role="screenshot"] -image::images/management_index_data_stream_backing_index.png[Backing index] - -[float] -[[manage-index-templates]] -=== Manage index templates - -An index template defines {ref}/index-modules.html#index-modules-settings[settings], -{ref}/mapping.html[mappings], and {ref}/indices-add-alias.html[aliases] -that you can automatically apply when creating a new index. {es} applies a -template to a new index based on an index pattern that matches the index name. - -The *Index Templates* view lists your templates and enables you to examine, edit, clone, and -delete them. Changes you make to an index template -do not affect existing indices. - -[role="screenshot"] -image::images/management-index-templates.png[Index templates] - -If you don't have any templates, you can create one using the *Create template* wizard. -Index templates are applied during index creation, -so you must create the -template before you create the indices. - -[float] -==== Try it: Create an index template - -In this tutorial, you’ll create an index template for randomly generated log -files. You'll then use the template to configure two new indices. - -*Step 1. Add a name and index pattern* - -. In the *Index Templates* view, open the *Create template* wizard. -+ -[role="screenshot"] -image::images/management_index_create_wizard.png[Create wizard] - -. In the *Name* field, enter `my-index-template`. - -. Set *Index pattern* to `my-index-*` so the template matches any index -with that index pattern. - -. Leave *Data Stream*, *Priority*, *Version*, and *_meta field* as-is or blank. - -. Click *Next*. - -*Step 2. Add settings, mappings, and index aliases* - -. Add component templates to your index template. -+ -{ref}/indices-component-template.html[Component templates] are pre-configured -sets of mappings, index settings, and index aliases you can reuse across -multiple index templates. Badges indicate whether a component template contains -mappings (*M*), index settings (*S*), index aliases (*A*), or a combination of -the three. -+ -Component templates are optional. For this tutorial, do not add any component -templates. -+ -[role="screenshot"] -image::images/management_index_component_template.png[Component templates page] - -. Define index settings. These are optional. For this tutorial, leave this -section blank. - -. Define a mapping that contains an object field named `geo` with a child -geo-point field named `coordinates`: -+ -[role="screenshot"] -image::images/management-index-templates-mappings.png[Mapped fields page] -+ -Alternatively, you can click the *Load JSON* link and define the mapping as JSON: -+ -[source,js] ----- -{ - "properties": { - "geo": { - "properties": { - "coordinates": { - "type": "geo_point" - } - } - } - } -} ----- -+ -You can create additional mapping configurations in the *Dynamic templates* and -*Advanced options* tabs. No additional mappings are required for this tutorial. - -. Define an index alias named `my-index`: -+ -[source,js] ----- -{ - "my-index": {} -} ----- - -. On the review page, check the summary. If everything looks right, click -*Create template*. - -*Step 3. Create new indices* - -You’re now ready to load the logs data and create new indices using your index -template. - -. In the {kib} *Console*, index the following documents: -+ -[source,js] ----- -POST /my-index-000001/_doc -{ - "@timestamp": "2019-05-18T15:57:27.541Z", - "ip": "225.44.217.191", - "extension": "jpg", - "response": "200", - "geo": { - "coordinates": { - "lat": 38.53146222, - "lon": -121.7864906 - } - }, - "url": "https://media-for-the-masses.theacademyofperformingartsandscience.org/uploads/charles-fullerton.jpg" -} - -POST /my-index-000002/_doc -{ - "@timestamp": "2019-05-20T03:44:20.844Z", - "ip": "198.247.165.49", - "extension": "php", - "response": "200", - "geo": { - "coordinates": { - "lat": 37.13189556, - "lon": -76.4929875 - } - }, - "memory": 241720, - "url": "https://theacademyofperformingartsandscience.org/people/type:astronauts/name:laurel-b-clark/profile" -} ----- -+ -These requests create two indices: `my-index-000001` and `my-index-000002`. - -. Use the {es} {ref}/indices-get-index.html#indices-get-index[get index API] to -view one of the newly created indices. The index's mappings and alias are -configured automatically based on the template. diff --git a/docs/management/watcher-ui/index.asciidoc b/docs/management/watcher-ui/index.asciidoc index 69c33aa7a1dac..aded7a45022db 100644 --- a/docs/management/watcher-ui/index.asciidoc +++ b/docs/management/watcher-ui/index.asciidoc @@ -46,7 +46,7 @@ To manage roles, open then main menu, then click *Stack Management > Roles*, or all users with the same role. NOTE: If you are creating a threshold watch, you must also have the `view_index_metadata` index privilege. See -<> for detailed information. +{ref}/index-mgmt.html[Index management] for detailed information. [float] [[watcher-create-threshold-alert]] diff --git a/docs/redirects.asciidoc b/docs/redirects.asciidoc index 7fc8fe5114e1e..833273c7b3ef0 100644 --- a/docs/redirects.asciidoc +++ b/docs/redirects.asciidoc @@ -143,3 +143,8 @@ This content has moved. See This content has moved. See <>. +[role="exclude",id="managing-indices"] +== Index management + +This content has moved. See {ref}/index-mgmt.html[Index management]. + diff --git a/docs/user/management.asciidoc b/docs/user/management.asciidoc index ee85819b4fd98..503f97aabd13f 100644 --- a/docs/user/management.asciidoc +++ b/docs/user/management.asciidoc @@ -39,7 +39,7 @@ quickly deploy configuration changes to all Beats running across your enterprise [cols="50, 50"] |=== -a| <> +a| {ref}/index-mgmt.html[Index Management] | View index settings, mappings, and statistics and perform operations, such as refreshing, flushing, and clearing the cache. Practicing good index management ensures that your data is stored cost effectively. @@ -184,8 +184,6 @@ include::{kib-repo-dir}/management/alerting/connector-management.asciidoc[] include::{kib-repo-dir}/management/managing-beats.asciidoc[] -include::{kib-repo-dir}/management/managing-indices.asciidoc[] - include::{kib-repo-dir}/management/ingest-pipelines/ingest-pipelines.asciidoc[] include::{kib-repo-dir}/management/managing-fields.asciidoc[] From 3fbaf22ba65524c70185c6c9d1c59ba7eae71fcb Mon Sep 17 00:00:00 2001 From: gchaps <33642766+gchaps@users.noreply.github.com> Date: Fri, 30 Oct 2020 10:29:22 -0700 Subject: [PATCH 76/80] [DOCS] Updates add data content (#81093) * [DOCS] Updates add data content * [DOCS] Incorporated review comments * [DOCS] Adds content for geojson upload * [DOCS] Fixes link * [DOCS] Incorporates review comments * [DOCS] Minor edits * Update docs/setup/connect-to-elasticsearch.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/setup/connect-to-elasticsearch.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/setup/connect-to-elasticsearch.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/setup/connect-to-elasticsearch.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/setup/connect-to-elasticsearch.asciidoc Co-authored-by: Kaarina Tungseth Co-authored-by: Kaarina Tungseth --- docs/setup/connect-to-elasticsearch.asciidoc | 135 +++++++------------ docs/setup/images/add-data-fleet.png | Bin 0 -> 221736 bytes docs/setup/images/add-data-home-page.png | Bin 0 -> 226207 bytes docs/setup/images/add-data-home.png | Bin 0 -> 56542 bytes docs/user/introduction.asciidoc | 32 ++--- 5 files changed, 59 insertions(+), 108 deletions(-) create mode 100644 docs/setup/images/add-data-fleet.png create mode 100644 docs/setup/images/add-data-home-page.png create mode 100644 docs/setup/images/add-data-home.png diff --git a/docs/setup/connect-to-elasticsearch.asciidoc b/docs/setup/connect-to-elasticsearch.asciidoc index c968ca6f35029..03a728a15351e 100644 --- a/docs/setup/connect-to-elasticsearch.asciidoc +++ b/docs/setup/connect-to-elasticsearch.asciidoc @@ -1,108 +1,73 @@ [[connect-to-elasticsearch]] -== Add data to {kib} +== Add data +++++ +Add data +++++ -To start working with your data in {kib}, you can: +To start working with your data in {kib}, use one of the many ingest options, +available from the home page. +You can collect data from an app or service +or upload a file that contains your data. If you're not ready to use your own data, +add a sample data set and give {kib} a test drive. -* Upload a CSV, JSON, or log file with the File Data Visualizer. - -* Upload geospatial data with the GeoJSON Upload feature. - -* Index logs, metrics, events, or application data by setting up a Beats module. +[role="screenshot"] +image::images/add-data-home.png[Built-in options for adding data to Kibana: Add data, Add Elastic Agent, Upload a file] -* Connect {kib} with existing {es} indices. +[float] +[[add-data-tutorial-kibana]] +=== Add data -If you're not ready to use your own data, you can add a <> -to see all that you can do in {kib}. +Want to ingest logs, metrics, security, or application data? +Install and configure a Beats data shipper or other module to periodically collect the data +and send it to {es}. You can then use the pre-built dashboards to explore and analyze the data. -[float] -[[upload-data-kibana]] -=== Upload a CSV, JSON, or log file +[role="screenshot"] +image::images/add-data-tutorials.png[Add Data tutorials] -experimental[] +[discrete] +=== Add Elastic Agent -To visualize data in a CSV, JSON, or log file, you can upload it using the File -Data Visualizer. On the home page, click *Upload a file*, and -then drag your file onto the *File Data Visualizer*. Alternatively, you can open -it by navigating to *Machine Learning* from the side navigation and selecting +beta[] *Elastic Agent* is a sneak peek at the next generation of +data integration modules, offering +a centralized way to set up your integrations. +With *Fleet*, you can add +and manage integrations for popular services and platforms, providing +an easy way to collect your data. The integrations +ship with dashboards and visualizations, +so you can quickly get insights into your data. -*Data Visualizer*. +To get started, refer to +{ingest-guide}/ingest-management-getting-started.html[Quick start: Get logs and metrics into the Elastic Stack]. [role="screenshot"] -image::images/ingest-data.png[File Data Visualizer on the home page] +image::images/add-data-fleet.png[Add data using Fleet] + +[discrete] +[[upload-data-kibana]] +=== Upload a file -You can upload a file up to 100 MB. This value is configurable up to 1 GB in -<>. +experimental[] If your data is in a CSV, JSON, or log file, you can upload it using the File +Data Visualizer. You can upload a file up to 100 MB. This value is configurable up to 1 GB in +<>. To upload a file with geospatial data, +refer to <>. [role="screenshot"] image::images/add-data-fv.png[File Data Visualizer] -The File Data Visualizer uses the {ref}/ml-find-file-structure.html[find_file_structure API] to analyze -the uploaded file and to suggest ingest pipelines and mappings for your data. + NOTE: This feature is not intended for use as part of a repeated production process, but rather for the initial exploration of your data. -[float] -[[upload-geoipdata-kibana]] -=== Upload geospatial data - -To visualize geospatial data in a point or shape file, you can upload it using the <> -feature in Maps, and then use that data as a layer in a map. -The data is also available for use in the broader Kibana ecosystem, for example, -in visualizations and Canvas workpads. -With GeoJSON Upload, you can upload a file up to 50 MB. - -[float] -[[add-data-tutorial-kibana]] -=== Index metrics, log, security, and application data -The built-in data tutorials can help you quickly get up and running with -metrics data, log analytics, security events, and application data. -These tutorials walk you through installing and configuring a -Beats data shipper to periodically collect and send data to {es}. -You can then use the pre-built dashboards to explore and analyze the data. +[discrete] +=== Additional options for loading your data -You access the tutorials from the home page. -If a tutorial doesn’t exist for your data, go to the {beats-ref}/beats-reference.html[Beats overview] -to learn about other data shippers in the Beats family. +If the {kib} ingest options don't work for you, you can index your +data into Elasticsearch with {ref}/getting-started-index.html[REST APIs] +or https://www.elastic.co/guide/en/elasticsearch/client/index.html[client libraries]. +After you add your data, you're required to create an <> to tell +{kib} where to find the data. -[role="screenshot"] -image::images/add-data-tutorials.png[Add Data tutorials] - - -[float] -[[connect-to-es]] -=== Connect with {es} indices - -To visualize data in existing {es} indices, you must -create an index pattern that matches the names of the indices that you want to explore. -When you add data with the File Data Visualizer, GeoJSON Upload feature, -or built-in tutorial, an index pattern is created for you. - -. Open the main menu, then click *Stack Management > Index Patterns*. - -. Click *Create index pattern*. - -. Specify an index pattern that matches the name of one or more of your Elasticsearch indices. -+ -For example, an index pattern can point to your Apache data from yesterday, -`filebeat-apache-4-3-2022`, or any index that matches the pattern, `filebeat-*`. -Using a wildcard is the more popular approach. - - -. Click *Next Step*, and then select the index field that contains the timestamp you want to use to perform time-based -comparisons. -+ -Kibana reads the index mapping and lists all fields that contain a timestamp. If your -index doesn't have time-based data, choose *I don't want to use the time filter*. -+ -You must select a time field to use global time filters on your dashboards. - -. Click *Create index pattern*. -+ -{kib} is now configured to access your {es} indices. -You’ll see a list of fields configured for the matching index. -You can designate your index pattern as the default by clicking the star icon on this page. -+ -When searching in *Discover* and creating visualizations, you choose a pattern -from the index pattern menu to specify the {es} indices that contain the data you want to explore. +* To add data for Elastic Observability, refer to {observability-guide}/add-observability-data.html[Send data to Elasticsearch]. +* To add data for Elastic Security, refer to https://www.elastic.co/guide/en/security/current/ingest-data.html[Ingest data to Elastic Security]. diff --git a/docs/setup/images/add-data-fleet.png b/docs/setup/images/add-data-fleet.png new file mode 100644 index 0000000000000000000000000000000000000000..b6d49cfaf8d3a51eb2d306dd06c27f4b36cc58a2 GIT binary patch literal 221736 zcmcG$bxd4c*FH>fcXxO9;!az-R?>wN^Y3JQW~0{;2@riy`A525 znABvT*SR5PUjFA5d7){9=+n=yQdA*K|F~=~pda|3egZaS3y8Rny zlNho1hx1HK7;7!uzEPP@3=7j9lLB-e&=76(rq+>f8(iec`~SwyCxVyBOrSS?i3vzb zNEUj|;?9bhp4$2jflO|Vcys=P*ut6rhbKa{P1kSPhfjDWn4GQuC>drgIf4H#_7m!A z$(P{#+xzfI>Q#LCNW+ZSzk%E_UqC% zAE)-RwlA|QalCZCPX0I0{~xcz54KMn%!~C=sK(mb(|`TuK>tJv8B6%|wO+Z^aEjrZ zH*q$jUpP8#P8#o*>b$Zh3PC-N;EsU=QXbFc5Ftobaj!fnHo=9zN!}oJs^k$P^I@v^ z^>M1q(O7;uQioLO?|2My=kW`_+OC&RiTn<+v^k1k2((_do0SZe)81Xto=zjXQ^ zGDVy+i3|5Odlf~mHkS07om(=vj9CYV9aR6HgopPqxN~!Yleg+ExwCZs6k7>E&)Pzo z&)mQ0@};eCl1$|2)YI19KL#EK!W<7#6C-s^ssb8@?x;UkSHzVV z)qvJPY29!eebc2$ndbu+;mX8e^z4X3ul}s15*%2S-ckqn>g(uG?r&8mDXXV}0e85# zU%w48)>L-(c6CzmF>>0Xq4Sd0z$s;IPxGmibB($AU|SQf({RaD%m9VX_c0o9&4$I< z_46WQs&c+{ajuw_YlT^7d6Sc04#}`|Q1jnZ9joJgb2Q`c2_(n&c61=qc0c1(wgQkw zuIP$Wjg+0(n!jR#*8NkM`Eh9~%;3Z*%K%;@+ho$}`TcJ3x?_92Gw9@|;B4vn35^@w z*>}){LW!Cu*gt z)%lVPY$Nxa>r{&v9)a(jo%3+=L4yzKD;BxhWFMLO7+hr*xyL2uI10)?(8YH3!x>t- zrM3kN&_Otjh1;&d`&#i zd$2ecHL;e1DJ2n2k;RG%bj;0)n87PbQ1#II_|4^Oj-u2TRM{0fE%X2*#F+kGPAOhPGu@L zhrl%b1hnF;pE)9+a46f+>R*-i{el%9FU}5@uH)H_A+0=Xp08qc!)>zO&sbmFqvLcd zPBheyX@>C%^vwc?Mzdh>CvCNcq$7p@Do$&Yy;3E1Vgq26dHg0XTb4FxwLIgu)s%^0 z@5L`YsjS`JMJ}u%i$aC*oHqOR6B$Amqz~-no>C9spBYfdZxTIbbI}U4v_!=mGN*4 z&i;THOY{_!60)~QWj{Q%)pbE4M7ahAJo)b*PMobV(XG@$~lah(>Rf))Cp%$a1r>uii> z`wK#t%Q^a3x+F*%dY~Ae?;KbmY-A%18{hV2syrOcxs643WkrgJDlFP+>UPL7w#tv-L%MdR&bZ}9ygG}MU2ZV zB>lO;n7fmJ?)4ADz5rugsnw7{%gprM8;#>lc7?$BUF+A`WT#_J0V89Dw>jqbUR!=T z>}<+Kjq1+ZIYM?3Kgk^Z)|N(i!+j2CN{5}dN(Lttg8GLhpciZ*$753)!#fJ2Y;yMV z*{{89*~*3@fW3(KRa0bi%j+R9O96k#t1qAHeNVm9O^s@Bxor~-Qm8qA{NHz0$vg`& zh*(=cv0E$G1w14HPr?=bQZq}<0(AD?A|$N)}W1_@@S zOfLO*uhrC&ghGa+c&$Q#wsQPq7~!WEW1~g{1`B0A5PykKjkG&1ue{MIYQG;okh|kb99zBLH$_`NyTgyn)X2!K9bkr zfox5;>A06LeybB&6DN^nN1Y>}ss>jc{=2a1J7QUL%6j4xscw-9?dh}Mv%poPaKH8C z&hx(H+t4d0Zp1M^8SR+QyCLJ1z?CycLR*lDQD41n=FdQR<@sVoASi=N-x%y{czi)? zda_3)>F;B`U>cMm4evV=br|)glJaJjF?V2jN8Df@N&|pxq8eAI_&Cj%8$zCQMP2GF z`{7~QWKQ~KGo+^jyZPtBPEZqrzKN!MNnfMhi2JJ0r#3Kt9c5>V)6Lf=O=8ZEwP8(N zmC;WZ`{apn238uBVsbx1SHV>)7A$I+wJBmIx$K#q_%iUqu$m6qq@(WxJnhtb**) z#&SKU-TIS}t_ATOYTSTLD}HoQWegS`_zZ;0%?=Lp<$7;BG>y6}_q(mknI)oo$1fKE*5zQcyvc#`-gjK1elEZWqUt z7%@xa>tKPFsaFT`Jh=1uDw=vC8{~6>T~T9UwM_d>F%v6}LJP+NzNHgfB#p~0t-$=w zkrIphK;zQ)q-ON7Pa|GcOHT9rP9MG-@WLz~R3ynMto*iMsJmB8xEhU5o!+rLa{IMt z3tVYzi6Y$QJzuwgwo-GXF3WD+P_$9yt0$)!j2M#Nu1wD>j%Xex#1eUd z<4nl!6GpFen&Yz_OcL>5y`FBJ>$$1vQ3pKd8PY$~`YAXTayYH^!`h4nSC0?)vrmNZ zGA>HD9+n3y$wxJdvrp1X&dn1+D}ZtTsudsP27{a)(ZZ%Gqu=$Lk6i#4qj}k*60^1C z)8|c*ny&Kv-O-$}htQiU9>ca(u!2E_k;uA8$nB}L=tUt%bFgw$gAxuN9|~4iS+xdR zhIw;Ee{AZadFk*HLyN=kfKoqWgD0d~Evu@Qu5;LL@xm+-hWj-aHpU-68 zy{OZq3D^6UxCZxIh@jW!n0t##uoZqp|5%ja80o|+@*Bv=g)P~oq{|_;*hqg+CGjcD zR)fm$`@0LFoi13}JgmwXw3HVBf1Oq%3K6L>X~l%>2HFuUlZSi(eid~o)5v|UA;NUB z1VS~snHoo5+#A2c{AhX4=)4-iK{~5Ofi0D&s{&o#yrbFsiIX#oKP$~HAWJ5d)-|`z z*3yXrp()$(Y!`+*f)77@HJosujeD!%GOp|o>onQSrQc9dnikfbenZV{J{!RV%4pXNE)DD`x zNz*X95$cuZkajM+8%JGJe@df|bmHzkH%nZMdaY;RN<%lg(8uU`gby_kX8lSKv<1Mx9SDUh5qah;NUVg%yd&-;2Hw@WXp=Z?{Md7C0*`D$*v? zEdBWFvo965D_-#l9+eEH4=G^5+%Mxv+O>qosB!KP;vWMpBJaX2mVV9=Cb>Ng)GwSb z*KN+^$u(S;VuQOwLc|;{KhA9hUat(Vg{UX4*4DnS4o-@Fo}KDmN-I@8k#OI=a-uFs z3@*5kag6qIl@GH0otlhalSszrsBg9e?o%toFDfl9brCGMcjhzp2!5qrKUei(j8dfh zjFogX`dalr+aH@H3_TZXCP}XxOc$CRAMeCl`$7amlS2@7eD0oZ@^sfNl1kryWo)La zw~sTyYvxX8|9QEn(Auz!MpI#6P(4oGozFeT6Pv{{T%dMtL>(jI!e8w)EX8^dCyA@H zJdFQGVvfr-jlBCw$|{{EDWOiH_VVas_cx)Ti-`^B)9~g)=aMZGFXwOqh+zj|aC?@e zZ3&n%jYiyLzqIHzhdEZr)F3_0xSG%p$#f9Cd%D;VHEz0!%i#GmQ5~@eMz=D9Hxh5( zY*{oDt0+>#o0S8WnR|nIhR(Vf3bE*w$VM^-+k|;=6brvyy$$z5x#O4Wp-j@Rpch66 z_&7wqDppsZ+S}%jS!oQiGBG8{%n_U8Ku!GpfyZ>1XT-`HX?gJG zK(u*y6=6$0aM}Jf%U8wp#|qp8C>C;K7IadBPIY4uV&~t4w;gmyX7j|YEwn9m@8<_@ zo`9viuF*FNl!<;D%`3}OkC7^>p7vchU^v2VVQiEcvz!~xDmT>IO5{k$@`NMC5Q||n zHM@JBqAgnfOLs@0rBe>S4gn6$cfQk#G<(HNmI0Zei~gBYI%nM>(O!jsp7CT-pH*kf zJ~t^L`*;z~tf}f6Tdvev<)F{T-;eb~?ZQ4YI-fdR@q;75ci(@Iz zYSdMRx;?yWzeD?sFZ<`{t3_gTa`hX>g?cJUGaw;S+ojBT&zdM*_17d8ai0hE_NV4t zm%~O1as*8;q|q{snR7xDVYZ&#%h@RypeJXey7kZ#U9b+yfeJ+mr9{u#Ep(1;{FaCbH@kOu6o!P?a)4*)d$TmY=!D|p*8qjS&Ihqu4!IDVA8>$M=;IieXAL3SK zt0m6Y%!KxWF(I2NPifGBO%_p423G)Qy}HHq-<=z%db=mMN!Ktg)k9M|gb?;L6wAgV z>tO|qrMkiNMkS)JS7B&YCyJ{i@lezJ_*BH0xfoaX!66Necr zfGcGBd|JxHFEN{cl9cdbQo z_+l|U%eF|Txbje9g`apBbjS`|r$|D;hm}_l{Pr@=9ykc+FJUGD}P6wAIY+EMIPn{TS7X0f6k7?JR)*HoB4-mpxw_RcAcxxQ2Ao7gkT>I1gX>6g3 z&;ZkrE>uZ(eb_v7i4L-9b{Y?FNmW3VJc4GK2QFjCdDUvK!stR>Z;s}hoT^>-Pu*h3 z{9oN?OZ#*`00}^SmnaX*$QFYnANbBu(?i#%>yE7=8Gz37@3%KVz!}2Ma7!Gjl$a& zF~h%*b`<=SxV)VK!y>hk(q($(drxVtsO>dbZ-Td#xlDe3I$3U_Iz5+_a9yDn$EAQu zKFpJ|x#Ca@uex^H5FFOW>PVd}oJsm=#F!V=ien)jmZnN=D(PZ|cFNw(nT|Cf(Oa8( zMI5Yw%t7bE&4<^H(_T-vGGs`F)fOH07lH#OYiCg^GG5|3xA*(zE4TPY6zLfOb}*~s z_X*(6_24CGtFBXcWW##dZ>>aqBUit+U7+U2wR#&WRt$4RNt4aVeUAh9nid$zj2r~$ zzPk!+jR)>BMU^xprL{dif? z>CAM>X0px#piehLhv~row4Dar^`|1`hiMfTKn`Tw$B`?{o5S1BIwppa;lreso{`1e z**|oE&p1a=yw!$`i@6}^;Yst%Wv0~PtzD##=xa|%24nr_|LlqO3@Y|e{ID1&K76{< zEVI|tezMEQIeb4{o;B_=%MbpRW%;uI5Lb3LrdE`~F> z*gS@Z4b{Sg^B9EOxu$3I@=~StyMxmKLOh38ig?{UUsKGk$XUZKa6GlpBWWY-;`tU-=o1BKD3 z$omjp&f@Lb+~^3yJSIumg5kkhF74d%wQG2tVHXzgo`62g-CD$-i5pqRjj1|?il-G$ zRSaJR(?*Vfm9-0-w1sF`5*aaaQr=s>LEAODP!_;%Rrig?bADfg@=K?vYq&4F0_PfU;}c0!G4Q$*w$uEGbRAWV?~+>bq|J37G{_r-<^%sD zLUJrpnGtFEO~V|tkQu==B}wEG@E42(m2IrUiQARLSk}PyO;`*eM%>pN!`QldXqz6O zx9(2y@pJ6^om6rt(U@ZfR9-BhiFJNh4$=Iy;m5t)m0SNxV%V1o*U5zUa^jlK`%`Y$ zS2U~}MLm>Tp(?BH+|I$T^0iN1r+QA9`EezjE4XL<4EB<`?i<$1Kf?>Bhq}UFt^STZ zGJY*PBf(+jP{(sGc_(F_j}?6`dpJQUT$yE$au{UT29J?H{-#Tyj5pL#YLSC;p}SCN zYDcV;bNBSoz&_gI)7bf|#t2H3#96m)_!3TE+v?iV!_5;q(q51N`2<91LKaSWl(PGp z0xJW;y4|v#6n?0Px4O-3#pg7SNcuh6d8(kZ*pGo0;mLR*T^JdB{GsmeU?8os zBpAn{-l($D>IG`>U+(a!;Nk-DAt5EOWpI80jb?Cq&Z4MQihX^&V&KP)I5^2pI}A|N zt)R?Yk*-xKLCQ<$S!pCb!Sa}IHQ2Om#U?F(I;+^WonG_^jmrV0wY>GT9&?^D(d`XY zQ1v(7<{yu-xTxvYw^9Ls1kBLrkTtaj`#(Ycs)F=D?E+YWfxEo>xT)(x7nX7rI!4*` zkHl65aP$jSJr{yvZ77nj)RP zAHNg9@3Vc}WAL4XKFW>{Ik$ENWb1lTW8QS10vT%w1wEA?d3QYL^;}ue>PATex{6^7 zIoQIRQd&EP-oy`mU?(0wdiEiFOGFeN?aoMFGUFqQ4xwgKB)`3?0?9@xuVZpyCLZgX z1rNy_tj!uKoGv#FuZP|;*^%t$Pu*rHVD`V#&buNF%0-gD-qwQ2)yhPTM4>`Yjcb;f z)@Z|Y{e0QL{3$FS*lDlXPJ8LI*b*w?eUu&67Z4~XKqK_R(9LdlBIto;Clc(fP8^iQ zYZ~5FniO(wrga3{jjdI1wl=oRxU(sA%gf&LRqvPWSa8_Y%sL&-;4+%{I$vcOskRpB zHkpS~4Zp5eR3ScCBm-CKOqd1T8y!LXI#fO)b5fb7Amx3eg*`&DJsK&4^vd>IL!V){SMKqx{{IcDHWZvrXD>KL++D zj8_McYWkm(iPAdo;PPD#RS(x6)~b+MSvV|idv`4PFYh>6H`$N}x9bO}6BjDZLmtT`gqjyB0{*xSV-z0e*&A}~~zW$kBx z``)_X#+xWN-F@BG{VCLA0Mo8_l&B_F0H4f{Gmou7<8SY!u-EQi?6IC(3*u|Cp&|8H zfy@wM6?H1h>uaa1<g6h-cABg~8%%TE^lQe2b^R5zC!yELw%9<1^{B&>JEoBh~X zxz7#QY@B`2T(i&*d9Im=?K#Xnpb6r?Y^hQ)eE->~uc{k`JVacgZ#hJ8HZ;su?nw91 zU3T|8V_LBd-Zs#OWdr)FCG2amUn=c0&^djTik=$=Rn;=3^p(a7&mS_`SPhJy2#nYEcWXJj zjk|Bd(}R3qQ23GM-OH`}cU?^^5K|x;iEWU0~hs!c}9wBQS6J%=$7uEdis)g|id5D!hMq9DNgcuO?#&F?p}#+_!O zm_O7_nqbwurdtuM1A|E}2v`P2jx#7;q@%M0k-oIU;ntblz4#oA`R%M^2qiF%vy2y) zCw{^C>!|Erbf>`!Ny@^tGNsp>A5gZ}01pvbz%3%$P5y(~AYzht_(7^gw7B6{*wQcK z!>m4Tv&xHbk)(Wa*WY%_U+V0te{P!W)F|Oww|z(&)DR|*a8ir=sd#^`u*5|?>0s_x zZaHYVJ~^2f4`G_}c#rr~3f~c?NbQnxCzUs1JwET`MB4BbJ#dnOw2e?Zn>#}+F}XKs z!g4^!Fg_X1&cI zaLQ;c=6^iRo);w$dsL8WbPDu%^C@e2Qy76pq2M^DO7R2$hBo9h;|hs*ZDsbBxQi0v zP~fF#J4Mjp=$C9eBUP-jqU-da;o0R(+WJDjNx@}hYHLjD1Q9(_I0{rGvjR2EYCT7L zstSlG8)i}{oHB^8P3aB+G?FI!)#NEbo8hsvkr`*McFEwXqY#eKk#hoI8%7-F?&$JL zr&;&`$%gs)Lu0U&0XCF?_*Lf@3?gpgAP37~~SVJke(E!bdVkv zDSB|0{d{l734toL;j`6rLpyZY%_m)^aIkLuHelpW+{VoC+++%&$>#otrswZI^zL2Z z^){X>SNmg5TGFrtFP)7Q7xR)g!(A6L2F^0q7GxlEnU*#UDEf_c!Zem#p0tMaqmwP z#k(63Y!67wGI_qXL=$ImubrK~YW4^uRuAJBx7y?8(rc{6Qrz|(D$I3l>-}1E?A)HD zIzFI{fh{8E^b!1Hp?WO~1L%9Qesbz(yg zVsfr%t2<>)pHYw)D`Pp6wSs^YFo*mrVC0XDt7p1R(e&iNTauWgfUQ=xRlB{;+t@-w zT&Xeh&@GON@LHOg7QX=aOm3v!w0iptAAfgn$}DE?$#@2di!2eh8^s^FxBuCSq_0Jn z60(lR8TP*rBk!BWoKo{flTBA^0r8nTFo@Z^X;L(8WQ&i`P?vhgI@f|;MAI=Z8EUVK`dxpWkBtG|i^txO z#!`wI3wplvM85^CK8IJpaW=hOssN&A-=*|u^`h6$1_Sx^00m4vF)?qkseWf1d-X17 zm=zSPNFDk2m^L{RwphLSoGl(>o+x7M8llU>^D$ORd%=i#P8Xu-aLr1jG$Mn~SfiXb z_jPb#WliHrF5B~w+B*3q`F zV6`#6h>!?Ta9z#f=rzd$_^~JNf12)~Z;NTU?OIuj`SvXLrIX5Kzby(DdGBB8V@QQu z%5U^tP@r{Z*y2Daj-Pq+$&mH-2^bz^mq;x`whSHfb2EWN;@^di>4zk8$2!PeQ zW`~g;X6e)9a)fL5`m2Z#q?{QYjg98Zd3d5*-Bs!D^CdF#Rs)~M1Vj|HFFNj}-<<@N zbun>x%V@a6$&uXFAK`h^z0vI|NsqI8df(ir!%AcDkX; zkN)A#diZ!hk?>KLo8h=aY#X0cM#2Ldi^>Q z7y6Qd#b^{0jGCq| zE{ppXtMG75tP8iKlHcw6ZlQK8)~xbX5v^>n6+(UbREd{G*?9d6iNlUAm`u<7usEvv z-tDBN>9{I{GZwuh&TqmK^cK15Qq`jTmx=eeTeh{)8t1M_3TVUGS9VWVrqx^S$WE;i zrZM6Lm?^fiNw<>%UK3aEm8v9rY*s=7rXw- zZZfOA$$X6!_0g!d3p%uNDh}=o<+n7ghp)CeWo?hLYH>YE#5w)_UT@R4_H7b+qH20< z?7IK7yJppOBZoCvZ_`f@>mBeKZEi-&hSk`0BE<>hVD#>JIL##e|!OG{IOtTR( zLHovM4edVh0KwEP1#fIDe7*874L#q{M==I72ncvZPe~oj$>`(g?!cf?#0!l_R zAj+l%wd|~<9F>;==JnPXe#z?gz&!Uyw=IC3@>p`-!0!~4Jt&=&{TltD=jA7l^cSG+ ze;vL%x_i z)KdC2rt1M-FVC}^!HfXd#?_xvGhCUY(+IN%yqw8l)OlCZMNkLPC>)cAl>(-3+=cPt|B7rpw0Je1wVv0q6y44 znc}9jnz_!rlXVjP#JQ$|+^5t{>SiCjtN$L_U@pH#`4b*z`mpf%B;JKt0@VjE(`@ak z%~`gq=AsZXO!(I2w(Ayn(@lrD)io9#1TgP=swK^wO~P2Abbg%O#UFxe)*|ownMhT$ zdw)g)8rd_|K9xI0=MiiyssFq)-wqCbi8MHQeu^8cHoKsqI#hh-rZV-WSV&b!si~c5 zc2T2xx)nFB3(iO+5l4a`q181xS>81CMXy?9fdzZXf6u&koGOq$wcS+~Zz&yA>k1CY zV<~Uno(Z$B8Z@Mb&$W1j7#tG&zPOx72a+-Wp!r&IJT%bA_kM%8CP+>DuOCxm-~&j`nbXAW-~ z-Wq&C-+P=rFWLv@B4m+B{ghGQE@X^58;vzIVohK*>EXaz=GyS`j8bqI#$8|?I+DT+ zkJ}Kyb&IZ(i?*>|0p8sBtpXG~giZgxwp2<>O;=3<9vbR;_Ht|}IRTB@5LE%o-Lmph(H3eI zfVR&<0?nNL`L!gMUoS#3VVoZC*`GfIOYR13gmjz*n{(`SK0;RYpg zAO2=-RI2;8be=yFWuv#x-G0J)D43!a+zl})k_$Heo_!ZM<(I#ydGTo_kz`OIxc2xO z;#0^mn?wgwE_5^5n6$%TL-Q&`o? zFdhbaRbRSz%(9+n_AVF*NWaa%N>)?@n=^E!zaIOWag*TdVuEcQgR1?%2S{4(Fs7Yq z=&`kB0$SRP*%v_rNlfp;_pIXH{d%j+u+tQK!wmnB7eo*v`ovl-R6QQ5zs(QwlpGc; zwbU5CVA=@!g+B1!NM|T9_pT|b=6rVl+d$_wP<7DFmyvD#59O@vu6k|P)kbL96gAS2 z#qlUgVXV~&-iFlWtuc##Yzzzcj@OrMmt#0t-=57S1>OavNmyb8{p=RI0g6J{7*2%= z{3E`VXE#8Cv$bwbb{BF%zCv5tlGuo>aEOFISk{Y~3637D;}=pyA{`XZv$93}RyVEV zAFapZdAT?PUws@Gc=jc?@W7_U>rL3*CYZ7(O#F<;980&W$Tyl=b)p$z>Hn;g*6oGVnVS(ec z!!k933ui!u;Zg3V`C67d?57#`{@Z)6oCo0Z+fOZ;5?E&hHBata9HB+S)xgo5n*s8O zjTt0==03b@+V*AJFaoms$s~#HlRt!UE++F;9^1eatc&}(cKT#bd4f8?{pF-ljK_A% z`?`I`Gn*~E0p;(B>^vsC(G}%cEf3;WmsRH71Y8)YF_M>@<3-jHM?fwR)*5z$0(X2u zf)aHP@8pE6Xr=(22T@-#|Fg(I>zyY7A>Vz{Q-_A0MCBJ##0&4^#duNQRi(I|i|T}= z6aThXw5EcsfdTP^Hpl(zovZZOY`gSeq7MyL9-L*KyM6g6S_6k7qVCiDemHG8dXfI4 z8EFo`B&-k4CLd~sSadxmA*U_Zm-_=&d*iPmVY!b>pnXNQ@ti8A?3_R<55cbtnH)UI zGgB?vh*ErZ&4Th4KCZZnwd4#ach>;BcMRSlw$CL2R*C5GlY0T9e1ITP)P~L7>?|)oS$wpy&X|Kf4WW=xDk9xg5TRVjY zx-VZ1#1pKu1$UF^LAv5khbtDUBQpXt2Wl%1vr_5V0xtl>=`#Lj8lYwW$JYdSWB`_$ z0*VqQqN~~Mnb?zpc8O9gBc!ow8&Sl>*E5GuA#S||I}oTtrEtLXXOt!rm|j z5!xYSq`}qC_`2{%ugXsF70t0vc~c#{X?0}sJl4kM4XvON4%c!9L50is#Y&PE-& zwaWmV-A`PW{~XH*Pb`!(G$;^CcURV)Dt3C;`m*GaunnA=mm$LrIk=QQ4CU^?Nu2pGMkK3Q zR7_AAoZA>}}XrV}PuJMmXTwTN#ILceD1ssvJ?YRoPiH{n_GU(3c7Ml+Pz zs;t-aLf&8Dn}4Bh=-*@~YYfj2r;~*}XF_FVkGlAy42Nua$2i4>``X~c-NNbqaY@!fl0*~=;ayLu`PO$a0;LtnFpfF{pIPr zCedXv@}@FSAsYcM2n#L1@VG!vn*EwNM%Qho)|WMSY3qfR`h=_>#2Yt+ANksHa}Z_V zIg~smqNPkfI^KmM<6!Dx;OES3c{N612SY}o6zEB$)<87M>RLl>v-PNuybnOX%&Ta? zE&nE2=I51L-Om7wFZ(!A1#j^FUcZ|Q7-!%*i=nFa$OKTEblrJs4ZO*>L)-j3O7aWX z*GKGayo*THh+eh79r~{Kb9Je@?6WYs-Z$e)Y{+MD)rVP^?b~%k{UpOI6fPDod=qq1 zQ=~dZ(W)+$XMyDtstukt(A#HAnU!YOzo=hIhm-sg4QCXFH!}XfEvk()i^KGOnAFBD z?89j!eOr%!*kp&vxeWXaHe;C+t)jCfDPX(2`;r?{v|(@AvL>!*UEg)@{u_|^Ww&o2 zOg*OhYKW$7*P`S6w_s*3Hl-UXs#4h)%G%~%nJKF7g=}5u@$`35Tvv(!fkYj=%-rCJ zWYz4jSMIm6h_Ae%%hI(wCc{6LDH4;oc9WSaoJ9I{yiv!drA5kNG;~ z(9)eHdNQntJQUou(s3rZ-MftGp_$YAn!koFQf@W)r*d)W5uSe1n+{Lbaz}yc%L5vp z2YsWDxVa5W%fRQFwbUZWcLA6;8K9ECOMNB^*PlberI5SeIcopT*l1+t{pZB4d%wPp zk4=sl`6z$oqv|)G_TooMRa3nL#9Ke%kbUtQ5lOlOjXb$%cc)lQ4QAT{>S$Pp@Itn} ziyfy((ly?$!{>JUv(R`jDfB-Jq^8pQUO8X$GEM)eZ$&>umKd{HC-J83rJ5h$qBQ8xJY`_p*{9o4xh9cb|b zMwG;s<2ezlrpHpbX?u)S&){)rPr`AMked7r7k9)?J3!j6j7tP29V5KeXKA*fq+HBVhUci=f8gc!x#XjyPZ_c>?Ztcmwl8Ug``IsEDQpH?taUqi1fw3rC-&-m@v z&ecA=P#c&Oy1rM!tXd{7Xx(0QgF%M>O0#&zt7fA$G5kKV(l?({^Sbm+2i6vWUXgPi z^OeSGYF)@kVFU}&QJUUtFzu@62ekG^Gnxfbho+$O%`K%@v$s;~Fa|}{#Yntc_md{i z-AhdioAK4vR)~JG4LKs~nT++yo)9Zb{5ol60|}RY`~H^&+?UpR2fohBvK!c;q}?kG z83FVg`LU~@v)2A{#$crA5SjGJ!G_;XHr+V1u6RY2Zk<=fSlzuXl{MWDc@5fj`TjN< zZHOd1+T3fU z=oS7%q?Y{3(i$Rv@?NDhF2JA7;5~@NRcZCl=-Ms5n6hKX(=W3tk0Jk&qrGmPHbov+ zVz!KV^e&~BgB@0;ezzve07$L!RnfxOkZU@^3zr~|Q8memir>N;?PI*GYu>G79`M90 zZ^SoCnFbQaa)95*RVF^QCc9pB{hHeG0bj5EYDV6ugZyIR??BX#JVVi`dJReIidQZL zhKB{n6JElf@_3;1kjTt8wYau2Ej?iR0mSv_=4(OH>SyX*|8f_@py$y`Hk&J7Zt|fA z7*Wgzj<<9vrY==8nW`Qxl-^WQe?czhmPE%H~OUW3W@l2&{gH^nb@#=FQ0 zSW#tn5HKbBMCQa0!1C<+GjH~H&R6`;f2IA__E4X(NV%I&r3;!$43Hx)$p1EL9aTc& z+M#z=raZBQM|@WKo&x2H?hQYb?ITfr)*@)6_|OuFm0Q|`$;w-ApHDR#cizpLtVR#J z6JWDyoqN!IzVAmdO(5et95BN*qJSkQ2IcY2SLlx!Ug^Z0-0ua6`W#}D<%b9aajbFjrE0S#=uT;UoD(an3Nx?PPiraz+sNz*#{o>&--t=tW zCcRP}VH&xV3!}`c{}IdMgY~{jHP#f1=5$;G=0ZU0`Vr9jKo|WL#=xl=ma&H`#oUHx z=t$S6Y(<4^v`i%^E^HU4nYDQDsrL>2`K-rhou-@8!wk0-A6d49$h#U1gKhJeJX(9G ze<{wz9NxZEX5m}qr)q$)FSFG7HDr<}i&XU)w5T%h7=X-0lrqrofkjLF;UcW`^D+j+ z1tkuodhk9iVj!ng(_#Q#CHjN9byK<>K#0~^=ynFlCrk_SP*R_;|xAz$t8%Sk*I zuBu0N-r4j*@|Xy3f$-og7oVF|{|p_kS^cVvGPYd|uXvnz9&sTBV|ZVAR&_@`PZ!-T z_p5g41e6Z^*&M`e?|~FsaZ;yPI#CPHvOwtMu>K`p?4mf$IC*aK70oS^vjSO#$@h|6 z_T^g3bfN&`CVSMERufWmn3zXjlIyuczWoSHk~@t;FM5h9;Tsw*wdbzI#^fN5^wG9zu-KE31$R-UQ-5dFNKA{*b`cO<5H=hAUOW1`E*SP}vPTG$S~{P=F& zurwU_lU5K~Vq5;{qsww*6xzTWF`c`CSw5r0y=0F^0WwcpBET=vzJ{26ZsRiH%E5-$ z#dp8<%{;J#1@lm))dlTFgWHaO97vv3+q4&kough0S{iccvAbcB@_N<*z39Q^`e5Sx zkCOlUT>)!y#77)0G1wPYF}=(CwZhNar!LgCvP{?}sl94z5xaDSbzR+wl1;1Ek$*6&4~M-GGVD({iCf zMFnGABFW$WfM&t{2_mDeLkhMWZ;9Ph>34b~`MZp|_v7Xj(Zk;~?p}=fF2c6KMi}Us z3q?3WK61IwkA*&9lFZs5OA9dhi3J<-yqIcDJq5mvZ2ON)EcyS#-dncSnQUF7fk1F~ zx8NQ;xCRUE8eD@03-0d0f;%kS-7Pr53GVLh=g#i#bnou{^mTr~`)#p+l38O)&8ix+ z-F;B#p)UhUe_I2~qXI_c{(;HS9v2qANsM9XNC<9{F?ogtgIC^~=gLyS7J78FhTeo% zPM4l9QLk>A+Pp7g6F#MG*f#5FHTM)+bIkR|P7_XQm*IV9iV?%i#9a8*H&>dL9N;x$ z*2qBz)RC>N(5`-ej|%XDyQlHfH1(&3!#kUVZnf~%F{+_2h_t)KmZtPw-XQBN@!KD? zqZ;Y0%Z*b>4aBd|v~`bn+(H-aolLHiNU0Z%S|BSH#M<~p%W+vtW&*-*y4)w4)ni36 zC+6egSx>iv>&DhH9(%CTKHb}*fJnMLoHnxr2AX-7vWr3ow+UoV{Z17cn8Xh?*ir;K zj_ccDRKMlX8uq|$hS6r|25snn&8nDK^chYeNYZpCtioB!m>o>8?_0U@3nb8Otc4DQ zyVuhUz^U@Lh?q0%{?t$@hEg}arZ)tC)pf9H2?3ryj02^W!D&oHXo+d{>`N?h{UB8? zuJ}AsbMOdbVM#9CgA_c=z998u8y| z@Fg<4Y(`?RLv=E**S^{G_i|++bd=TBSqiS@;aJbLyZUCZ?$}L42~9dW#69ZyQvbn* zq^vCeV|hcO`kJRB6Zy*C$%k{BCKwlE_}Oad=6AEbf;-g-xfYMHyp3E~u8qfUy^;Im z63rswn$z9ZqPt;`&(=FXrWui~DvGZ;@Q78zyH#yVU9G;;<8TcYJPf z(ts*%9_c;-r%Z*LC-gYcnb8T1yqV|?>#@Cgml+&Ovq;#=$jo2B{h`(t zmaBTtt@>VAjG4Uz^`2(wxOtoEH92{h?d3HXKjJ4eUikNRGpVV?*RH(ZmoJ@s2vtFh ziWCc0{ze;=>6Z>bB<5La^{i5+n(DxSb!*TpQ|r#P9CFGh#7As=Yc1mPYn;(_8R5IzkkWiba^FPc(YYiTq@0YzoIO8p@F7|0w%I;y zUzJZY(dlWq$|?Qu$8h2ziJAyaU1;oZIYS*;E5p4$HYh4DaLC4e0gg{@&5?t6Y z@2ii|Db16F;LmhlQdJ7hD|T@F9}zjU0&5-1stWRUhI`P=cIQwIuNb8;2+W>8v8domltL>5ur2RFJ!ujErzp?T^Ajb=vdoU^iqeN@vXLO+*!AU zGC{~PE~p+iUsntZSuO(aCHL-h0!AC~V@cD>hsJOX&scu+^FK@bpK#65^Er~~d)Sjk z(Y0)N9;eL`rj9u|YpNktU~Zmajz(^0D<8;7BR;U0ebsD^Hp;~sc)VUr!j4$&#<`IB zb zdJkLaSP{3JR#)S2$OIf+8ec*sD~fp%<1-ocQ*OXZS1s_@2-fchPT6M8PTuDdr#(*Q z)}o;i`62f^7eKRyFjF=2Sr=N>eZX*}`0R^VUli|fZxqdokU1NyLM6-oW&3oWMx7(f zC5bA=10L(q06B&~wS2m@{e}ngo~>(5FtVEJBatxcMF}3m$is&TCe51tAno(hA!l3c z8Ebn9lzZ^bD#|Y`L(7iXFuYPn*pU-bH5e)>Wr*3Csaj!gNv1lskE2H^iFcN!ts@}2 z%;Q5F*~JzwTj)Jj$&I}%7oB-l>tT^^?mmI^INZ4A-wLh}Je!hX)lG3*Yc&77G$+Qe zV0@iTIM9K|0iJnZ=^rqQR-oH>a}Ns=-mFQdm13R`z7!!LYqnpnQ=Dxf3lB1Hr#wa99gGXb_%7q;$E8k2FiJ-bgrqh*0u2F5Bj_FRD5~3eE{2QU6 zR;!&?0_Wpbs7HktF+Rjv&MvJPE^l9ONcV=#hYK>$`|_d4ZLDFUn| zXvEFOHOHtOl(3ZrJv_l^_dRNHzM z$Jomb&)=yuz2e}V2zZRu$AT-};+QmhkLTvf@uh6&=EexTX0{wFx6A`wS8&^BS;Ant zNfTqGaIf;S8(*F2>a)Er82E%^1Op zYfvk&=AJ0#+L13TC!spcNA%3pTFx1B*>4IA4OGgQt}<6^81NVboSmR9-ZZE!FwpVz z@nu;iopkp@9d-FH)Hd30eu`gd)h9R}bx5oZ_6v%|Qt?H9cu-9Dh-lNNG}pnQA-+~WfF!}7*ugO*>gJDsTTRXF;5B2||BMJ^>6Wv$zO zQ0X)6_vJISt16uoOO4J_H5|Pr6f0t=&ipU!q%E}feu64VE$rPn+Kk=GIl}& zl#H;0666|Q41Sl?SiCuSJd~|ht8;>(145h;;6(|uGIJ3-C>`t~j?!)(Q3(Fsza zNq=}7rrFqu%bcE0Zm3`s(#cs#v(T#BQd@~9OI|a&TYKmqM=0FJd_>t-qJ`a{qo%W+ zyW@%9SNth_`Nj9Bqupws;w`lE7=wODoAf+v6>tM?M%#xwA|Cj2lRjri1F2H|pXaw7uy;qBWGx{Jsb6SaAw%xmp zbF#Mpo>wij@uZ_Af4nfXZt0w5wdC5}b7dL8d{0r#Ux{RJ|AYKIh1Fvb(IAhD3JLP! zjoNL?tAVbuS2`Mgkfk_jUIxy~)zItrE!eWEjM0PYYIhz9n8#!p-fm2eakShHUj5}h zTS7Z+3z{6ZZZ!x-O%D^Ehp(L1W60+9L`~t5YT)~hZ61*ML#xqL`kyQ4fvrU@>JK{^ zQ{ty!G4ta4_hW*U!tI8pLbY7aA}`D4psg$Lw)1)z+29yUyn8#NP;Z%G#*s10Tx}TX z18Ws=vTQv}u`Sa>zaI@|9?B10qGBoDBRMFd&le!wQq;1Ui*U)eO#-fa4MlBA#-%Zs z&0mxaZRS%_jYnC@x_gkLW}$e*jiak$y&I$J$Z|fO{AEglG^I3#caDg1T9E#013CqW zjRWLk7snmT!H0ukIU8Nru!poN`w{amc+pg0Z%oh4FDY`NR6V~($zM`W4K^QhmN zu;2_eVA82N>DL~|$}hifkkLp~sVz0Qmx=1d&_XH98l^oB zt~HgZrfm$o<3nd{QE)D9-alh&FmTa=j=1LUy}sjF8hp7-88?zp@O84Ln*I?vWAG7* z$O928#bEj}(>2wfR+xV5>m~5GQMd`d!n*ZtQhg~eU5l3T7c0%r4_=q3#5W&(oQM%r zIVq%QY!~7oFMw_rt(2?iFgoBVeL3^S-(0cuOnC16-J|oVfk}=Yg%K+R+n2!5#yF% zqL)oQ_JU8wNQo^AaI#lexnU;j`rVycYAUo;Qc;UI0O7;XDA)OuebEn=1sLsy`5H4L zRju!@s-F6#@AGe9f5`t4ef}avBqoR0$r>FCI=wPeQ-iZQg4bNx&rFUv*Rs4Hd((2f z;lTdk3KL5;0dq$b**pslGrjR;sK;$@#xS%IfFu-iYJ~Gd9Z_Y{75G=$2S^5+jb!r7 z3|Ft#i)>O8H|PW=khL4@zlcnIl1IQ|MGM3GymO*gjGd050_yKGZp=uU?D>=D<&QCe z$G^b(YOJLlAU@=u2*P2LP#P{^b4oi)O%qiv`-ZM!_UWCIYXFJdTS0(m5eD-!<$tZr zFSu@pdg+7G7%Sf%yO0Smv#mTnjN)mhs{KO(zjeDJ4dF9d?c0j=FXV?{D4hS^Cc-56`*Yt6Z!G4yqYpUxgCA{mwsiK{s-$~I}VIr znk~{HvK)kvuP@z*&xtHG87j0wk5RX|V%k5K0H9lZgAH&A;uLp|I5{>U>6lA#9CE-# zqnzIwyYr3kpQOE2DV4iAw>3{y{67Rr?Cm9@%;p~pJv3jx9AEt7BPNafmr>(q;4Ck*xfyJzA!h-x`ynvPwjKjP7U zS{m>6pQvNn*UrWK=P&>GMw}c_gF=Y>u74X-EI=39UhEX7@vj4V4a!4JLHrk!2Q3Yt z?q$`IviZLZS_#nauaY+ZCU#;bKrIo5KC2e~Puup}OcZ{q!T%G`A8z-b%lrQX^#2g_ zPgMN=4WMFvuZ%1Hho*X0Qy}BwTF;>2;hEUl+M2n$Xv_X?7DjLYTe1zGEA#sAh7~7W zKwK^ga{ZZ0c1-bIB#w2J@o-Hak!N?M$*6HfMc?SH(I=tbje0C3yMXGpto@h4B{hsd4oAEUFE8D?%`X)LR7J()?%-<}8 z3^@>wDN+0&{d<#O5?+`f#jC^GK2=6$IKFpMHiob@3+D-%x89x_a!RapN>%gat8JRz z0Hfl&$WlzSY^E1rbF)gOKL`751#tbwC$LIaf3rj50bW(}Jh7(~7ad^?C;{V_{G1yL zK_Fx$xM5x6T&O1_!SBq*BqW%SdNn`UY8xG-)C=?8PfRKQCjF6@KjjDplA-?Z;o6*{ zaDHMPC(X{HgMN;YL{}6R_MrzJ4oSGX+kVVG8Ti!LlgA@?nIMmePw>&U+$|iu4dC>; zy3#DuoT9;?e=EkUye_y`_8&JTAVvl_hwQ1uGupp(A_$GohieoViC;r3D|ayndD&B} zzOv_05eh12A9mX*?=c=RtjH`keLuj;At;9sn1Q=NRuCVMaTgDv+!mi5`CA}@6Wz`Q z8xxBXTFUeHKuur(Moua><8$6KHNU~D1s2xHO6z5#xHdw|++LYLGb>cbw}7O&HkVc9 z!u`uNDCnep%wHAT8U5xCiOs+zc)((pe%@jRZ8ny6i0+GHm4Wi#gN+nPfP-AtD2x8@4HJVuL99h+ z8n*Iaf<<50%rRw~nnS~UkY`re%8y1?dM;n_6D_>amiEc`jO=4>!+NFs`wemL&>+Cw zhZek1M*q8;<}8EIH=utbYZbclDZFQ6@T1_3B{UrJC%OTjtSov&(jqh^xXmhMWL=~$ z42W>bFre)knNN2AX~i4vCviSxM`>ut-{Ne6SLDcO2GK#Wjaye&n6Z>te##J%2tpr} zAFk*Vs=&SVc<{^kYMMzSc)9lR1x?a#BE$qK;QgIB-y0qITLO2}=5X9$wX1?N zLLxeW!Tmr&?Ink<(JKG5UIka>ZT*9k973XFhR@Fl33&b7mSkX*>HiJwDFoigy>Pr; zB(^3uPg(c4nJ*lt3k+>ZIxr#Sl^LF~v=NE~ep|YJ03u)Eu|NJJSn~u2qx^dJQhbla zZ%SKva2;>V`_f#45*I3vnC>NG*%vSvn>=s_ELR>G{4fq`xoR&DH`WN?a#tBovU6A{R!fs+ze|ISXH%pI4UO$TO^Vue z1xgEC0Gn&`y8@_9p??IC#265y+3S{lBx;~H5MBzsWH0KT$A(NIR8vl2^Y8(IY8?RM z&;giu&i=lkYZsOFB6*RLK_k!BHEkDkaRRUDG*Ax>@dk`b9K!Cf=-{7f@#`Ct_X6=C zlW=LMzwb2Ld!*V$s|~dV?Xl-k^;l|NeD9ezRC@Ch$I#+{jd)r4L-{`r;IFXZj1w3- zU3XNBR+whhC2?~(a;tR7J1L$E+gAOhSiq)vDl`*Q`5z4aoKO&^xf)dVn6zKH_PIFc z`}2dmH))@#f1hr9j{u-NJ#wKm|HwL|kb(D+cn~JsxI~!lvHmtUELt#nC5MXX;(`B8 zYyFz}&kr^_KWjZOsyQh9UCaNRl{dipyztC8{Z+Z)?9sWX8DWs4&NTm7jd6paLrWRBc-WJnbw>~@P%2 zp7;Pm97j(W$A4T12NL#zmj2^zMs6s$(dz?VI6YxC@2HmRw21YVy54J^cdZd?YPB1) z5r%EsSfb-oNze92mkp!tqpp%YifYugrKkE*p;+FY`UsK&FrT!*X+Vw(tyA&TVB{GP zU%XJ|z=5x+e*N%Klo*^4V-VESVpvy?d4wtJ(cm0X^m;9;VvW-s+fM~Uc^Wz^*@`DB<6u`XHv#@w6*?*IfF;r(~^%p_+&d2@vKFY6Y!4GoIb976-`e5 z@&v~m@xKP}>jwc7Vu4e1sV8mSk0{&R79yY&(r7+cucpO4*&3FxmmjlHUw~mKJ7E7g z_CNoX7Yqu5tckg)h<}oXD24DQ#WF616^+~m0%lCeVbR03wRT(+rt!r}yQ83VkBR27 zVMXpl`W{MgHf9OL7l9^ZIr$oGCJT~Z4gMh}?=eaNK?iyH*5>2{|AFz>Wez@2uoH2M zci$4b(d(1^ZgK=+{K&u2A{cg z(=7nQ^mh%G%%BEW`$3?TG4iS{7xyg{m?iwyoFZ|Wd(UhR?BmdT&{}pkAMyJ|#!q7m zGse{30?+^op~=Iu|Hsf%eO_>QhJ=M9f=aCNrOauId?mA^yZi(oFmLqjX}0H!dK7*5 zB65(F6J}Rrr>4my9t#5`ILz7N1T=r@5PgAp+Mi4RYoN#;5IlszUKwBca&+4r>NM8*EbD59rQC`Y&ThSw{XqS7K{hsoZ{yrVg%a-aW0blz%Gdg zTKo83Ky<2>qWG5f&&B_%Ez6Yhnl3<>0*slW8VO;ulvP8$6IPI`aH*Uc8#s;Ti)GLi z3XVR}gfQgP*r9w$5~?W{U>$4WjOj)GCw5Vxslgpo3e!Hitlb$W*VkLBbQ{YkU1Vx}e5`w(|&rj}52=WGnV@auokV zxc@QgJ1Y=W1xK{;KTI$~O0jz{vsS&B$R*`?Xeo_y{i=xRP1yy`>?OJA;cIg%4dq&x+ug((QU^vL61E zBN|j`yrQJv9V&z1D48LYH5ICXJ_(Phne~YhDQZb}_4iSMr^Yfi2%A@CivZ$HIetnS z&zxTTZ<6*dC;d>Q2|FaI$ZBL0x2{ZGYfgvdsJimvk*0H;{*5*dOzg>G$hU8}KqJ6% zxFLhXDb37iw)lXIQZ@E5HOpQHC-Ny+z9h~PQY*pIoO_{BvS;@kwI^8;h6)V{bQ&PU zXiD&Ror4AgM;1RF-N~v}EBZmJQ1R+`{-hOBh(@P|>xLkCmQ!zas~2%qOo<*@_D9?r z?%M_iTWD6%B0xCpnGh>1Q&se;TJ{{FB5KL9Ts^kZ{I*)oUuMVGTEJ=2!wZ5wQ}Od= z0e>n8p`^qM9q1wd-!4}&!ye@XMIkj;pY}n=(rB<-0VcACpwY>F<;ddUQkO#B+np*Go`Euwe7pZxk%w0GxXt-()=jzM?&v z^h2MEhCJC(jXG!k{)l=|L4;zU3%!!E9Ipaz_9l&YIXQBC7AU;wcy+TQ2LGqG(FI3@ zivRRMt$wjl-is0IvG}icr=%gCVT^L;!>Of4x<_*3QrE~l1d$`opbQn#GMI$FVJ&1$#&^#yGgAr%9C(9PZ??m7EPk;8h z6NITo1Cwq>M1%YZ6u}qmIGlWr~Y2~L7^T%^@bI&HymtNy> zSjC`_iG5p-q^e%cVWXJ6%3r3igT^T??T)LzH;=4n-@+$%I848f)a+svsX0JXZ;L^vvkz{B z%e_^IuF9qBu;M}SmPROxl&(&g8+utOYJLXuX_^L5SlPGCASF=dP*GbMj z+o1e9vXsI?x%{j83WRfI+*D9LY9|f9J>8ny7v~${fGN;V|N8}yVW*^$(Yk47qs0v2 zT&sIvcOPZqaR>XI&6>T0%X$9!bUz+K?YxG=D5R;2F z>qOH$pCGAei=q~ru7zwo6=XQ|KoS#Qi07FYA4~s=nK2Y-0oF`54dvQdmS={mhdQ_J z$y$xWfHODnHe13yJG~_4ttu^1W$l-OP~Ive|CPA4>0i^B32s%;qxD_m1ukCWssZjUk<-FEA`*C*0mit$`Dv*d;P$g5d-Asal$B68Di{@sYw&qlZI(U3efupu(4&z%-F|o#nHLSX%J5Zc? zlVdVw-k*!A2(@Ua-Ou2W~;jaBf{}J84R)=kOIPsvz^tDfX7EJ!9p7m9Q zeg(RU!R#jtlu=&tD9K^oJy2jvwy5Huu8?(5N8U%#4kHvW-ELdzj$E_j*=n`E!OQ+v zw!mq7VvuWer_dB19oY$k+3{x!7roKb|eUK8x`R#6?#+BwOWHRcw?1P`m#iuH<$gKI%>GP}_G*J}i)_FL%nn4k4L$JgUV5)3rG zro_&UAagkG{9(Zf4~|cXpYI(4%A?9Ln~_uP^BU~VK(u*)N-?q!?M5ha-Sjv;phljl zls+}=R7h-9G^-hSUs%o+x89lEtWvb)EoOmHeEV~Ulmz`rTz(2QWj4B6XQSIUV#Vcg zAXuB<$zpru78 zFE1aHmhM?|_sNg0`V@e8PV0&!1#4TgvF$<1MARpm_r`=Mlm zh}IhH2WBRI_8Z2^BMI7skhm{j#6?B@yL)@Hh){<{Dmu1ih+QB5vW4+Jc`XnPqIieT z?LkuOgGBsw1+#A})q+6BmnqoZfQ!|{ui80$k2Y<#LoH%anMeL*4;nuz2ly$nQB0WE zzHPg{EN)x6X)$3+lR=E7M@YAwVMty|n~I){hK7zAgbJ;;x@b*O=!B|;8{O7*IJ7#C zQbKB+^m3fQ_Urc8%wF;lCzVhWCz28E1rtq`A_oQz(h(y1EANy1y>~BnQdX*`05ye> z%IFFPp~!t}y*aZ;;=RXVnX5l;)$K2c?jon;(B*qLF>rZ)M0!n2J9xvARWE*Oxi?Al z&1E~4a=kZ#Pej1LW0_HnDw6MxvwKvWnu>~5Hj>)UGY#Vd?xW#eZzascD zYP185M(Sp0q(AO@$yK-YZqFiT(E>sT_T%X(jNL)SyTOKSnFNVg3LHVksN8*Y9_kzq zfHH+b*D6O@Ma8&R@O8>2OPLfy618F;z6nIP@&BScV0jo)Xvv`U5fok?l;_W#fq}g%HHDS=_(*WvEmIy7c0`KDif#bb8N2rgDS&~AieN24=gvJYz6{!`S+co#}&elgkF5N z8+5m4gJsg{R&`S26BC=Q_fN74ii);F2zql2Wo@T<567PNVW9#1533$HoEe_(_qb{J z=+x(MAsfC(d|w)L-Ke>p4t(U)5lE-ZxZT)rZKqUibfd|#k{0lTec2p&_Q>S9 zn)Q^IZCY^IW;9&$t5ARjy955cGx2^b4DD`=lni#<(B|oOyMIGsJ$!8WOHCp9NU2(b z2H)+4eNy0XQ}cQ`=AmC3{f5(|yun6RsPVw}ce3ommNabv_!muo@ur>ez?s+{ovr0< z#jIo-^I9H?AX2^{A#5RZ^dd=$Ot(dhvx2N&)Q>)B5Y!?1(UeHb>8A^w@-Bvw@)rf7;>T|G}efB23bwZ0|;NIZ@;fsI;@{Uaw4J9d1f$9x7G5@m1eF;#P z?`^~8G`As8e@0AtLnO3KzBtQsa&u7i8ysWv>$;`Sp$l#k;cC&VOlWA}#yqfb)~&bk z6_th$H#g3)jzEPXG1d*k0NFTd(9^><2idTf?_I#=3Z)C75zpNY+U$-w)Y=4di&Np- zvXdc$%>m`JajCLzh52c8ZTE|h<7L)m6!bXMu%()9Fr91GMys8o$c#n9h66JL4qXA^ z$T-V!>5m7LcB8yb62`_9t!*Yh+9+fNvP_lu#y zy^fWoGWlrw#vv$gZhceXnS$M({AV_z-x0+_Y&Hgt6CB03~tZj zcJ5`P7=(@*_ap9>i`maoFY}F#=Z~9dJ)iH}#%fFQ7-uP4yg3?6W7aY`+W|mbZJn>-hk0mA1HY@yG49XR=YgbDr)=aFJDK-yrzVS7pcakvLuGt&H_6Znx_% zuch#N3$E(|xb~d>k_r8U44!BpHN^)Fnh};u4TPa~ldWY{le#~YUz6Ze;aM!javDb> z{&peM`fc)S-goqB?^6+}(2InTuY-ME^e@~&D(!9NeC*{}-^Cz);1g}vC^@XVni<8} z;~uGz%W7X5e{7+(jr8)z9AG=54|bj-M}Sz-HR5mjPACAy$%o@ulk zVW&2B8JKD)Z$wHEDlR=gP^&16jT~|sICxf=F4cyj?I%S3)+<$}!>dQ4VN^^!Q>-3J zekfWlSNw(l>2%cijotkrf1v43OQ+q^WSgg_nyZeb$W%%SzIx-Qq}^me-&g$w@?<17 z4Pjp5w&5zV(gu*Q&ghuWSCN66y3coY{pqK#kO=7vdc$I@78{c`Pti>i=rtpZ)|AhV znvU@*u1@=i;ws*STPc0Z&S-S&p$W3%z!MzRP~o#(gVQX<=j^w5G zyd7K)Lms|xzrTvEFz8Es%Fql*NwK`>gJof-Qq#2`jwES+QkLOA{33S0{-RDzE%zvZ z>dBStljHspf=UtE&}>mjN!-B!zIu~Y>PCm%SNF#;;b+$Pwzj(|#`o^-^PP>;lat@9 zkDh%|ly*yfNLjeT@VUmzzm1M^7#M*S7bX!AAts())$toVyh}cvj`H^Sub33Aoo8C5 zRURNmMAqz~flgl_X(7+F3idSQu+1Mvm%YnXTjPh1mE7ptrKY?J=eeX7tD7C+3%QPAz|#sOUQBty&l}R-h8ubnT^U@M)<|` z;1!9@)ORxZgBHbZzQ(}WyPPpx@q`DbuYwr}%HSVmGlWAxnCu||&$px5l^^F34LY2z z8IPk@$;2k_FN!<-40=N1%7q?6=`^apLED9Su1QR+zH1vG|Gu-H% zI09cezmCf#{cRV~lc9)oBlZVv>*iBR8;r3sKKA=4eFl2f*%NgDH z>|R!ePb|#$0R}EaKezyTy$#m)%i02H1MUq0 z(&S!;&M(ybQBtc{9UT0MV2`qY*(mLE>TghPCKOq%WXN*59-bu zojI!Fxrv`oUMXrdws>?=kX14xaAbeJS@j%Xv}zOmEFf32*WnaMCKSQ%5yEqQV99m6 zVP*_o4Q~ZQrS!Rkwq(4eli)G5RI_fW+S`LQ-DQiK?BPdrWE|uEM82#wblWvvM@@M- zcB^qZ8~CR80`7Bnu&S*s^Fv-59b?N)af;&}HELvdnW_B1vVwv_80VnTv#2O}`6~}t z*&Yi$dUXUWXpa82r`ss_z>I+#755t%y^~UI>p;2BH5Hunw6qD&dN{3&)_4Au&Q-F- zAKXi~!ykNL5HC6q)n=a_kDpolO|?H?FFN(>57#6RDcomP#*L?`sD_9Y^vRvL~jf`1N+F$uKV4tNp24MliuUxL>>NLbBNyM zBp+_&7GV>#mFdxyc*~D2CPOH1m243_g%@5D`H?9?gHqgZ(hE9^Xl*vx2=)0rr$vjlGnPg3=z)mM^fQ;iSG60h z>h+db%T}S&K)XUZH5tyfp9fM}qby#p@4c?z0BUow)3V13^Zur5ifjat>w)cDV0bbW zXbB*#ezU$%75-t?28|}qL>q{&iO(MAf-=$F8~Ra7-cyggIdShpEMp@T6+C(vK}h<1 zwPQ7YKOG5>c|UtBfM=e+R$IZuO1M$^er$4Qx;IVVwXs-Z@wGphv~o&jdGvev)x)8+ zCw+ppBMiG#qkzY0==>0FPC&CdcEVv5)J|Cq)ZWkoP+{@qH5@t(68yVmN7mvT<-mZx zS`FV9H>i;UCns^E2fgOJ_f`>JE+h%}w%C2~YOt~$T zhYAjgS=~)GsUneC-CDd5?K6nv#>68+UQ3ZkyrvbqC_6f}`@SH@i$dytJ2ZBt z>^2pR_>rXZ)@914>gn8`(=ig?uNz`Tv%zSTLKnv-y?sZ#t}EjtSV9GLpCWi8bdie5 zXLaL=7AOKDQ1*dcqLroNm5-L|uyQY>6|wu_yv~0q(%5S+38tsH>j!yDa^3YVFjaBy zDXdrUf-dILPfHLBpG1=4EOz5V@#6Xwd<6>De%Sv9xRm2ZC6HObt%mBjxRQ zH@_&#rK6J-52xOXK8~VKZH+vRL))U?=EQoQeUbjoyfYFVIBqTl0I;p5Mk> z^+3(MMp}^2)7Ut=q_stG#lVwCC`ME4lCs>;O0pN3NPGcfV^wJ1`9jZ(^$#fuqW-iy z>T-#&ujL>P=j#%JH8eF1{N72ez`k}ju&pmnmHGrEfQH0G!q9@Xp_5%J7BYncKlI(C z8KZWS-!CYI>T5tgxL7UM4oeqMo!OF6p?|mhz`IudCG|5ps?ol9333)GFE0B0Qj^}06r4Q`Fh(}6l-dpaSWjh?*oMxv~VOP8U5?y zQT8>uKIyJ@#|dl83~xT`e!pFEQo8oFzz>lQ4`(nMF>w!$Y=zav{d z#_g^Ag$d%s4<8e8rE$ZHe&vu^WiuYpOSbmMDVQJBFWFSE-4kn#zYQ&zRIc0IjPfO0 z0BK`VQ@gAkyD3<=J6_F{m5504UKudK{bnw4zZIAgPxN^899{C_Q5IqTA4*+$6UUP6@m7-kXL~|xS!Q>H!_Y4EE_8R$M z4mN=$Hp}N~6wWzHe;e{KwH5q?HYi-GygRt+sFt;m!Hw)lzGz4|Oi4#aM7QT9GFjfs z>WY+99+xa2WJfJU|BM|Sce``O;K_Pf|0|P$oCd+93Ze&YBl2HN!b-UpQMINS@fckys+?VmomLhOz9KTuTfO4VaZU|2_qtyTD89Y(Lz)$@CUG7XL#z( zo8pf(MtjI|MN=~}_65j#vifLc^vn?#_qJDl5wez$2u4veqgU6^Fo#gt60TsUdDCer zhGE(Y`~q3|WjKK|Pi?GNti^OG2kA<)%Q` zLyTD>_|p^G)AiPavhS~k#u|Y` z*pJ$26dW2vcD`g*8r|*33txhzYJ5{iI8zzcJKHNgayWM#yBN{IDV5*L=1N!lK4lZB zFz8ti3!s!`HA_ET9>3f0$I|)Y06YII~c20&*uPrDD_zWU*+uB}T< zCsd<~#^YQ+RBBK%oC+7t2|gP6wQsI~XN6&(1T}r&JQ-(2g+O|1i_z5qWkvsV!r7AR z@nENas9w$2k6KD&sGKY;imi`V+%6a2`!+5nWPRE831+D*GBiqR-$9w-{5shcm`Cv{ z`&@P4`P`Lw^U5GIgvpUh>2j?*Hv-^sDuR3&Y-mw z$q1yxQLzI1QMz09_RLpNZDsP*jEOre12#;~FvRbA*PS<<+Mcs{&WG%KKgV<)2BCC? z^N+!xQHb-aDLB5DVsVHJ&STm|h>k{Pe_31?mzR5-Vs$0JU%uPZ(}V0?fubIj^qt@( zJ$N&zi$+wTCShtPO;VcsG|pBH2g_i+yjrt!MX^SW*mRjLQ(ok~3bPim;!% zkXSfwA!ZSMUn%vk3m4vGk}p`;oG{`ap9znR5`7@4K;ya~dNHk+&l8z+O72bIkvF+g zcFm_{8sK_U{=@n%)*m28l-KpMQ7FOe#RE}vxu7DUJ4NH-5?cSfZt?`&tJ+H+)_We$ zmnDjQr>>rqlanK^Yb819qgBYQ5Vpzf|6^yzl=Sx#Okt2o<3jX4ogJq3;Re|HVs=$k*DPbADT?n%33I4-{2K&wEcTX1G zQ}2`6yB523Kd?Qpx>kIlP3PCFd_aKOepAo+P^@{ec-nhe}6 zL_4?zrjl@7>214!;1u;yn$zl~Jv4|wmuI7y3H2I60>(CGi5w=&EG9?DG(0>LEI|By ziPTxB>83@j-GPCeyn1*f*h_?{CNag|PYTCe00@1?c3)n|F+AIln3bmKg?35z*3-^gvc<&cNf98b6%nS70w+qyehbiJ$H7*CKBHT7Wc?dJh>7I%bJaSDD9kFH1&Z zv2K(%HOnX~)awes)h#PN4#A+^1e`g{x0u*V_p7;Wat_KFX*F5k!oq9vUZP1x`jUjU zPw1}O254pcPrGGyx0|YZ_?8?VRS!LN5&1cvVv8|6)BPGd3ZZPVH2J z>5nlC^l;SpX1k{%THs&V2p5^YHe07$_Ez2t>RZES$5AO}^;j{{D2-S4qHi<(^U5w_ zGH?r5kTk4gV7t@x+W2dnX!v_+Dt!ulRQuB&EF2UTMn+lSCJ9veOLv!8a4JY; ztE^AYkDgJQ)-A##Z};)n8DlX+;j1O_VQKr}7&wvAQ)7~oDX$mKY5RWwN5{Ei=8)5a zYE7MzK%vOAC?MaZEde^WH}5eEzg}u_#qo|F+*2*lnJ|nm9*r-V-wdWqgZ-w@jvL=< z8H<;-2Lw=GhnfnBs0Yr>9+g$K^@iO2`7}HU?ABI$n=-}GXoLuh(WgJ%9euHG>| z&aPb_j@j6@)!4S3Ow!n9)5f-KHMVWrX>6;p{hvO2@8`bX_v3t--!*fswa()_a4sFM zLb)uKK|uIa#$(poTk;yo&;>7bSL5%TlUBbuf}fjYTV9+*yS9nfIXsqgV)X2f%GbG7 z8$Z?ZqjNGO}ss4eUAUO8B@HMNzjB(^(#6jH{-x@XX2GS zO+&ANuxODpa)y_)lAm;R8dVQ#T|hx&1ZX&+<^A!8W!KF4;PGMsts}uu8P4&x+}`9K zx4N-@Ns$N#JOn9Ht&M#|P_1Vda2In?W?By|)ZEZRV&ud#Bj9Wh4J&|F* zL_0NFbxsTa-O%p{gDA#kVHiz&<1gH&y>h6#*~n2iN`|#R>bm$_`JSYY)q}rF^aqmL zs9<26Y~-Xm1MVwV{dfQwKzrQZk|CMs`&fO3QYrF;u5dPFhogHCh!zdh3YrY^3*kaD zevTBT=+GNS`>(3CAZwuu+m0%dW2-ojxzU$$)Z&B9Lm-y_pRm8V|n5Gw9_} zEmFuL<#)gPN{Y={uifDq*73AEUNf?8m3&N2MK$X6_)at?$0@+dpi&|EXoqui2?SAz z-QMpK^)$2hOP^{l_h)qA&<`o8seqM?G#cKf%UFE+Z^f5$Yxdph?uJWGRN1Lsu}{_q zYwe(nVqk%XV@29Hl^?gS>+41U*eQnoLG^K zw3Lb6&y&?8rx$FDn8#2ChZC~m6g~I9jH30xLue=r*@N9`gS4Le zi7CwWRz4d{UmOR_l3-E;V<~i02BwC1!oQ*exn3|cGL05Ao~2d6NmeExrbZvovojm- zW+>1a@h9{95^1wABs2mNH#L??1VcE54xq8XZr*$GpRL=F2|U6C{!q8EV`1+tezW&i zoI0rUe3k)9@rfayw6G!0 z3LCep-Vox=srbM^S5>UVC;HR?Z5jKFBM-WH{x1K-n?yuP&^*5h+KfeloP$=?o%c7#8 z#ie`;4-YRW8#{9jN1Fu#Lwwn5AEY?^k2Yf0CXFji#lvX;gGS?%xv)u*SldsNL$m>Re+K$w0ruD?l=BGh1SZLO`E`%(PgUYgoZgKQh+8_8i= zwpC~u^W>2X-NKXOu0jT=aO3@9^CT9&9y8ZgWJCab{S9qt@Gp>~x+L|5c;ufw3_`Ar zQr7?1l@qhU1QwRa2v52{_b;zsMioZ*`!4D5*t!00RWwGgauxnvSwLfCh1Z%)gr(SJri<0k&EAX8=KUnu*)f6e62a;?)v>%1xXj|%hc zi~Gr-Lu@v=>4%5QB}qNk9WB7L0KN0(rx4r?JP8+8&r$i3Ofnep;06wB(Kx}+Hxc*y zKZs}3+I#Scwnvvykm0#|!vsMcIn3j0or|e9(4GY%6S{RKX(;NI4H_HI8QpxNwmrVy zH|x&RBS0pPwz~5n*k+?`0f4LeHb_s%2!f9q5q4M*hGyvE0g0V$?3u(tQKD`7%>{Np z>;5h!da;@Listn(XQ$R}BNlP(~mzu!WHPbb)U4Q0$d z;Rq-853~lQKqiE+Nrl%iM4R_-uDycdUF5|3I@@a!(xpa0s!^$yu_Laj4HWKFbafDK z;W82v)n#<#8qz{I64ZSD0sn8vHHKItHSu~D;v>3y<>l6q)3ZQeM@XJ6JRVpApm%e7 zP9+che!00p-)pa6V6^`B24;LOd8TkEn^W{LH=9DCiEX>t0a-mc1ec%@eP_z;*`nEF zGm`miq@J*kg+A)u0x~i-R%R{Bo_z4gQUwAfLQVkU7oQ~}%p5DE9Noo%lUfBP>yF)0 ziW$!4Cqnuj2o%WHoaW`5Qx85r-;P9`7LrmH;G0c^wtlUwa0e4qn$k?X7;jHL_k5c4 z3Hg-DrZD!i__Ps@Fw?(2oRa}%=42GWl%gougRz-eG78IRtDzv_$ii!wOLdhaE>Z1T zlP#+VhgT&~CPwYM0oe~ZAvvA)HvdduPm}271}d$p-zjo{@uh|fAoX31Qb<$vc(EZ1 zIGW9ul-03e3v{Zs*sRfen{uLwo}UC0G&lJU&RHE~XMA009Qh3ZFc~6vt-*R59x`xR ztLf7COg1nE4KKszZ2x%~bYK-%P;8#cECA=N2OI`%@sjFQ`R@X1C=PPV^6jB~cNsD6 z_o2`Nv$7SftJSuwO9hvt7aU5mMx~*P?7Z6e>K{%jjY!i2^fUwmX}Wybyn#K?E>oB} zGstGgp$tDo_D&{}_8jok79J!vag{R| zsF4ePZG{aG-D^YN+smdYk@nnM|leq_SN2brZ5n zvN-GO;Mh&>PnN67TVcUPFT+-J*Y*O+3@4f^sKdP^)1Ps7Rl4aF)eAA-`5o44fwRDZ zUhXCr8fORGmHyjR0x?e}2w`l>L_Y+kQ7J=J+N#0LL2a+hy}4E4>KB@=95UvV=!mFz zl@?HglCmoHyfXX$$YDZ9l-qp>PV$xW7GFB13%SN#mAguKm1GUJC06+k@#OGvd3T8C z2M5KZQ}!XYs9&^TzjJ{ZQkB&~r=xAt*U~RShGZY(cqKjFkwYjVz z?ujOduqbHbX1jC1gnVl@NCl8O2hcvfk9FXM4iS}zdV}2ARgs~v1-db5KafJx_Y`W&%~mP_vaejfK@6 z1;(zgCHof;>k)-&FVf&cjj_wRn+u6bb>dCNqD}0fL_M*O38jP@V3jhyOMwdSoGoZStZ=@`XDQ2&$t!!^^LkVblU_&C!?!t<#h@=7H0 zaowJFy6pTZP5Q(8h$6ZQ9vgcpovc!~Sr}-uBHXk84e28@Uz|h1?_t8$-mqa(@cA#; z_gDAeAU7!20WX&hm7BCv8FZ@><)fkUKoELg-)=Tk2Omq<7Wq{!@u3-uru6nB>U-=Q zX!ho}kRO#Iy99OMrJqD76_2#Cq^OY;;PmVixx=93|e8FJosq8$%OCT9^`Dx4kl<0y-yBy4%%2+1h$1 zfW0{PcgL-Vj8SHy;jPV!I0%`)fk7kTuNpTm=}l*>Bpn_=#IvpX)4Ujs7Ct z?`Mk$-Wq$8Xa!?qw0~sujr2NNW~q*jXY+xcyARtR%}er8eKog@WB=lc77J*dG{ z&GD8~V!4p6uVcp1y!)6~z$G0S(;MuXB#|KWXsHB7kPgKAhRdCAuR_DKDf&OczTk1l zWxJnRK3}vyBWpVEpc2C`mZ#c~#v=%nl9G~=v#^M~+?_B0n^HPp2OD5gP<&GN`Ss7w z%DR8?PN%R!d^HCq;a&@#o;48!yZ%%H(tP~etUhG4$t$Hor&Wc8^>Gvkvw#L~9UyKk)U4KHvHA@ID2Yx6cD<8B zYF58+i?XT~{=sR9zD%HS5$ITdkTIWxIvb>H2FC}wtn*tW6)=~UX$c86=Mmd?vf=uP}9tuL^^WOoC@U0p!}% zHzcY{gu5q;ct~k4VN~n{iF6R$H$KU+E#(wpy3Ff$`+NSn6Gn8gUKlr zQ>x}hZZ;P1E%4PM8yVj|Vqh!5ZNn}gugND~Wy^tC+#W;Z?fWW5x6YZ<1cLSb z6*%WXjaY^{OW=rA$6aX|6va=J-3!hMm`XEA^F2x-hE1;#$h)`~QD8C#eP=K_)M1%| zpB=W`J{*T;M0+Y~*io{&2l1F8JWPmBh!s!km zY1PT@lRDR14_(?7WzD0tUnD@5G;%+SYDaVi{DgoJa=x@aq55|WVmpB{))_4tJcIEQ8lF6G_SlKl@Hsb4YWlZbWTF0 zxRSn-Fmja4{^yHe5<#lHz9)!afi3$CB)96~Z%xF7KAJ@sZ-y9+ubwyFgbWr!eFDRw zi$Y414AjiyK)-wvp6Xz4ai!_6v2mW{QKtkO;G1Pdo++0wKQ;xX?EhgK6NQFJeKRx^ zAG>yOcog_f_&aU$M^?WI0UGV~O!anqHtb3u;rbd|{ldy@^w~JJ>rRZ?mCht8V^Cr6 zz|aAcP?{~#=vbj%2S1TDb5Mql>_cro39DOVIB9VaNri+Pn-*!fg9`PU{gIXT_VOsW zQOcna!%Ovnac9z8*7&J~tyS%REh=iiXd&M`S`GupY&UK(=_jShb=Zh{O} zC}fyF)>uZZXBMIHH8&0P;huZ=wbLyGNEQjS8nNS_Xx9pkT#!A zT~`jnh+E|k=Vycbt_>~23K)tKKLL$5FX$3W=^T01RV~}Gz;i879TSZJgM=pR+R%l@ zj*KtemWnDj#(?J;WajW6Z3uV-2hxBtR`1i1%B+J2hu!w!4bIz_EK&H{C)E5&%FtN( zX&+3DBeP3*x?2@Yof)$V<@61Vgqw7*yfiqWLqX2^O%2y0F`cTa~7P_KKP zjr1FlGd>)_JB6y`e=QX(R-l+30MDS(3V%GDz!9mCl~h_(JXLlIZr*JL;T$R)lNWtx z%3RG*#P!zI|2hu-mIprtA>U-RWs@Mhs+MSOU2?`9r8C-r+Vf4L-5^Yq&3N8Uky3=5 z3@>1kjkp2#yM-;ix-i2gqG`Tlq7XI8cI#=6(dHP-la7}n>888LA70K~Y!kFIKE%S8 zCQ;p%Kiwq_BH`Dh;NFU|3KeUqW!G?k4|UNK6umw6g?yRqE7;?k&wld~?tgaRe;$fV zu?N-=m}=YTrwaFa<^$+G%iWWpFF)F0Xd=)@<>et^=*EbhyA8`5uSI#)uyS&&TTN+} z)ywcn7KhzQ@(6l36NH(ueWM&ygJV$$9sUwm6FLvv8A8XX+e2WIuDa)xN;CQM8VEw`7o&a@+5l4PtX{H3tNz)j% z$!(JP7jy?c@poLXmW2B|Li#!@f!{LgZyuKcoup;;8aC<}yRbOjWhE7Bl-XI9yQ6*> z=s%C_Xn*&p_Xs_yHLm_vTUUCDGP3H7fLi}inu-h8ndbsy3C7iW?z#Z$dar&k_eO@& z@(bg=(hdNW<{z1h!`i1o_=r!Q`e?;}pQdZ?NiJBMT>2p`aM{RVl-rrb3;=$!h$aK8 zE6EzW_CK=je-tcaa!>$F>%2!ee`UyWP2fGTqyMMYp~@Dnqtv8Bo`#c9Y|#r&TWwQMon^doz27% z9I_(++3>AFgHM9HQN>?;|L^(-Jc$rsuNVoEOQxKw zQ8LP>G)pm{1>IWiauySQq5i26ijcc0gP&XoI~8>+)hw}Lw4(-k>+I-fgItboeClGt z;eu8z2}JxrhM_;$aVu))k7G6i(7P*4SLDU&Nue=0eVxw6S?(W~d|vWl2)j#@4I+^$Sen`>kcZIF8KaS6;x zdU_~-drcj2C?kxkO}fgRAO+9~qNav0?LDvk|2b2rK|djkYQ*Z9#~Ga^@dtEkKT#1s zu@-~It@m1MH9$m|-tm($-GZd`dvC6+=Qy}?y_#0FuV-*m`XZ`h)(m97NQ}a8T=s_} z!3NVt25-a8Y>0o)TvDp9{mn;}?ii*F?vt{q%H!*d3swP7nijG+{{c45yhtnmR-t8n!vS(R_?YL!HkTyw4fOcVyJ4F2&a3s%pDV09shR6oy zNM}(RZhDW-DZ;l57{&%bsS?+T4;?Bg+`-l3T0{oq+&;pD-EqplWhEImTY=l z<$Qe!3GztcU4}?g#_4bg%=FpE{ZXh>hx$a?@$|NjIcpfb3AtQ}e`8&Y-DLdULXumu zNb4{Y6IPnU-e9uoe~d{V{^K9wU@_B%!E z%hoSM)lHLh6nS+znZKbD0z*%X zZ-=DhQHiA+#h?jjw6Y3b@@Fu?3qEyh^6x3eu#rKrTfa2u_Cf&)Tb`U74iB3AKAaYn0~bDC*wCRe=0G^>l%(;im$BYn z_#8=E1f>xSNh(~n)1P)w87}|3BJv;8;b>?X-S}28PzJax*+mlDMR1v1_P=-!7o8pH z->Bj5veA|xu0#?W60(ye{{361U?PNT9x~4=6#APQx#zM7pFd=Q){CMGC==d*h9Ytv zZH6>+BWAS{s=5{v*4l5e(BKx9`fr*z*hC>O?V{QS(gQb#I2&_v{G3AjH+1NnvwH7g zMrESz(xvO$dW_BPT?xP@0voB!FLTdOA{MjUqZx|4f{?ys2)8%B!6FM6=Ok7nwEO^L zp+(1af?2y3s($^$VMJM}vZ|EbTdlLWL2}o?)SU}YwNY~esdyt@1GWLm&*5v0ebf&t z!oNlHzjjREhd^9VE2j>TbG$anwOIw|TVpXDj$aF=6X`CjdC; zZ~Q%5kpgG@%`)jUkaGbM&ofZHzE>llR`74hbXEKRhCu7 zy}OC4D62D^?=bYEsyV~U)T9tr94kxO$%)ruE&Ro;LaY!xR|}PC$ss4x9mnEg%af3t zav2WG3qN{Ry7PO9%KN7pFj%*pLZt3c^ef8$;x&J&+@-edG)uU@?^XzywJy^B_<441 zi*a$)`dz@eTr=(Vod!ZM1Hn&8|C?5t8-bcQj4MY|AsKW@F~7n2B4MABwPC@5EiJ?c zqk~p1i4vIFCaGzjbG7H8yYR<_o8pW64RMh~kG>UED^^|LLaV)7<%!pYI!zHKj<7l+ zs+!lyT-m%Pz@>FPUQ>y-utvvL)-ZwpXvl@SyF|`v=fmH0){29lU7FN^D8dTZ_sZnr zfEl_Z?ZIwc4L-PF#>J6}%F9RDtk#Lr(w(fQr}XxK@68L!wm>X4*K%BJCeXY(JK?>b zOEpIs+1u%LO=NV731sssHrZ_8XiTj66H&ol6#c-ljSyj<4uEleCHAyiciq(7({6Sf zSD+8z*{1%?l{mrrpOt@%4Z$TT)vNMR#SgxA9ApRfqXLT>gru8qZOD!DqsZ;6AlqW; zlTNkD6(E)oq_4KWUpb+d04C5NrwdN<>RiJdJ1)0^mp@`3%}uLl6cbQ5XKqD>UPx1M z;TN-Dzj+H+jxDNlqnJ~g8S$!J!m-F70#n|?afp$O+ndnsDAn|1`&qg-MfS7vaf9&5 zEs7J*qBM7PwSm1mT85Y&KVxRqez=PNWUp-G?mFJy7tTU-N#w!#L=8-#l}&`0S{(z89U5SIU;H=r+7t zA$v-9EP8btgmt_Pc{r^~t2$P`{^Am~Y~S0?D4_YDa@9iwy4gBxP_^WdJF+=BX}>K7 zU$fpxy3*chDe`;?P8G0TL5s*+R-cs#e%;CN8^y;nX5VqW0>gmDnJbJH@ow@%o4z}E z@!n_#u;P^Tj)}Qtf2o)XPdPvw`3yefN0$VKBhj)4Y%K3i2 zFo8iOV-ZdWA2sLGQ*l5-qR^*XpoL3W$7Q_hof{cPFgC0GVXRS87ouF9EATQG3zUP7 zzq9=AY)#Vr`z7XYh#=Y7lP~)1yOu*Z9A+DXtm#DGA?bF>UDOwIeNXV{whgDf znCe*Ur);C{A!C)*ZXbJT|5U=TLhfI`7x0T^Q!3->BS&Q!`806DloH>UHzAu%yhq<+|CbLSx9BWx)0Rk!~*Cw+f?NWR!$d9o4zU!oSs!89Zu3xE)U zfC0pYVKv=KM-C52y@&^bopK9lIWm~hG#1-&W!(%7&w51<6;Ngl)lD&2h?{gIjIkU? z#wi1LJ8=;}ujDk#YD$+o{EaT5bpEg+M4{D)kEEu1-IN{K;$XzlU?8LMBVOKIhpRk+ z4YuNEAZtHbMR67&M2p1KRKF>#KX5rd;!Lk4tvA))WPp&|3?37d-wF9;H=Jq4rxFk}W)e&!-Z}!bu374mz)&bcXI$JNS zy8U~bPMv#k-Km6sa0<#wAq_y+50uk&xte;b*T?ZxuW*m8@vUh+yM2FXgp7tkEv(ZB0tDkC{Z>p!us7o@6 zkfz_QvcDhgOy}Tos2gpw@}uTS%WHz`%j80wBcRCMC%ty;Wl{GVj^zKYZr~^<1&)_5 zejs58nO~WjJ}#aa((nW;wTPYi+%nnN1(a_xS~`7th%i6A2Ev);wg&@Jo~Mj6dt9!R zqJDIxWH5;{7JmtkV#X5|-@RmN=TieKCSG`2(~tBhu!om5k)+@dEzd{^lpzo;Cq!YH zN~5Ue(NEcl#;-?FM~|G$H>z2|cTaxAw#yvC-_2ri_+!xVQ}?}bx&22<0U`JRD0c7m zc1N;+h8t0$zStwEYchmk5*=H+5jf2mVF!gL_veArXCA6u=AieD)R%@JHNGbct{gk* zk8}yx?;K!;WM$d}##zUU^7brpzhn5_{poePB;X>#qlndmsq!wpo=Wd7RyJB7QaOEU zYrl8y_c_;~d-x_MX^!SmjGIoj$*aIAH+eLFPh&Hzi1afUhhI9ZIad4rp<01!ZqUbUGa{7cv`+r)z6o}cz9_CBc;H&Ey2E?vMX#%(8kw}BxitZO3-`RkUEHtU z57R+5MWwmR*!LbVcm*B~^&tiSGl*AGn_vJckB#hC4 z*Wn3Oo}Jz-4=59u+%Pb_XGuC{%uBOak95-AguZK+v&nBlJJj#{;dSZ;c<&R~YBkUC ze7e?IfqaB$$n!qA{~3A3f7@|_tl6F_0BG^7tN=7h+}yxZuv2Ia8QI7Wwd4;nh#DHk zbv*W(v$!e=&QD!p(z6@?xrvx&eYd;^->Zw>VgLYVOJBybDx^`4YgQ)R<29##&ksh5 zqY+G{4}*oh-wQoILVdfOEsDa1MqhrtKe3!5hz5;z9MWoa@3ee$JIW4w;}}0>$8$j1 zX4~^Uzf2D<+;j1t$Ghx^S#W1&d5=_8B9bFS<_d9r?Tm>eDs%2#vC4R^y%0>UC))e5 z6OU2ysqn`^3!#hufGcwt-#*#miKn7$1?pqyTHJb^Re@hPn%7Lk3!hFud|UmhmzyZL z&w9xoReQLIoMQCJG2et`subpSdjQJ%ypiijW9%7Qww(E6(Lj#N@pi~@;x;RhHkCHW{{^tL)y;H&yh+9iyrNY*w3v-7ibQRo9@mGIh%7G zU2oP;{xvn~u;TbKIvj97>b$}IJV0|_;f7e*|MY%ycIlWc&#|;|KC)NObT|sD8q*t4 z&`Zg9yVd5!Sw%E%@~C$QO}`j|NN6!sd!XG{M)pa0Wr$Z<0IWz_k^+BfUZO6)GuIjH zu;|=2%Q{NaRGn>@jMXMMB0f}CXDsLg%kh6eoUIhdEz`*+k{O^=tnSCvsQrA<_2ueE zmg~7cyst3w*H{5^a6-mi`_7OI!kx?LH0s*yR1b$k^s+`f+eGzLUe9z*>RAJ1zt+HO z&DGT)d^2x_-?ebg1kTlAJXTkd#3Bmu1ULS#3?~G-5X`t4%IfXpV2i1QSM|ogar;MfK%{!11I29H=?9(7M$`C& zGPUnlHPHesXhYM3G8YMpf@LfMf-ubn6tEnx9T%-G_evDRdEz{!NbN7o!Fk7btO_jG z)X_?zze;4{av?a^;T_1j?e&`+1!tN$#ng4SAB2(LU)qBXB{KVj5XFM2a@?eW+SfR8 zC}GEJ@v@}wXNKYP$2Z-+*M;TLiswuZk(C?HpX0# zLp`uTL%nfnjFhi%`Dz5ks`uo%@p@xi^4W12IBAlHhQwqU20ApiJQcfMy7%rUWq=Upx1@V%9uRVSC5&6 z?uyP(!fnbXS0`g^d(I;WTB$kwN+QX5y1v8}Z%uD|sYA##P=fh*E4MF{l?lJ|Z^;gG z6!Wu(7h9uaQ!Nwn3ZLHDqd^J z8E8Z%Bl`92DuF2q=3|~H%<+2r|7HQ`TfRiu>NFchj2>0YE3lB}uKO2nEo`4DK{Zr{W5?WeEj?%Aw&b(A_viS>hwv{kl zSK&69cHXo?AMScYQ5kWH7q04=y22j8U|x!Ggku@Ss2d!=C?)3COx*e*(T-%DpQS^= z8v~B3wi*WcjEaejqx%UrSmkiD?LBsQAN_Bq#Ik>|ZqoGJ_(|wzj-#tJpD)`64iM@7 zAeqXMF5UIb%e?7DJj=|=pquV^YC|!b=6_W~ivhcK`rTSk@MZXR zqBRA{FB8f6As2yD$Af#w6XFF#Af;QMwz})O3TOC_dGu{@w)YC()%N{_{5?bo?PO!yo7EJ>sNX&-}v6N>+QgYCZ#Pn30by(!BxAUb4el) z(Q_0ObG^Qe+vA{QobS1W?0#7Bkw1^Rq-0!Af!=I}OyrQOKfThA>7EW|`p-&P1Y=ug?P>%x0(0@ZnNK^&LpeiW|9M;nya@XG<0 zKQs*PPyKFA9V_}`#1*?;Fnv}G7phLTvQfymSZFOZW4|UnaP7R+zcq(PK9XC~gw1Fm zE)eoaQd!dd9YPKq)0rgOXltn58`Zil*^2BccJ~# z2kJV46vOW7(PR{V{qE5hWXzS{P+kV*LKi^e4H?mZA__GcMuoq2OsQsr2Z=7L!?88H z2nNHnq;rCSY-#v_2$9mN?`<78H?NQlw)2NC6jOG;HD!w}xye`pfpwRtm|fqyUPzh?RJTS4&F#Mn!Uu6bp;Gu++V3?liis#F5MXj>?vZ@k9wOC>su%IqTzWVjUHK^>T& zDqEg9^_o#Yx`bhp9H;0X0{DmpI;K{TJ{y(_eL6WUboFJXyEOOL$))jtPuDNIVY1#( zBncVT%wHK(cx!yP4}JmUdgC#xHFcZ>2F}BZJ~ey$;zgK!@-4C;l&6d&&U$$5J2zoQ z(191`YP-+D)d>cUBH%TPSZvXTpA-%5nZ7q$T*>@t*t#-0NkjB{Of=FFoKV($* zQ>ruJ(REu_w~4h0W#%8Srg=qoVe^>e>Ok*su(M-yjO_<$ZZap=2M{02Ww?KTZz;r} zS!413BZY3vx|oe_iwCtBvFl91L9|z-TLC`bb>EG|9F2)>`0kHmp6YBm72+I4?AnVo z4RrHohjWOJ6iu!j&;UTYS&xhxN{Jw<(V576H;^2Y!1ii>fk#<9F>~;w2V6g+1eTRE zbdp<y7Vgm)?ti5ofTVRJ}Iz+^< z{SNs9tMbs<>E?QSn-(x0&0+MAvgL_n=+af|ZmPRzzYazBQEduSu}_0tyyK_NO*rOo z%cq?ijn4tGnA?Jxr^p56y1C`Kx4;6Dyhj*=aO9X+i&@zC_CUZJbx$3_K~yoL{hhkX z%ZubYD_h5+BP7T$$7|4eej(#@#B|partuRR0FEiCewqu#*s|R7WsuYC&y62w(E81d zliPhIH?}^!DLH+so87e`E<^1!_Zd1jQXcQ{&S_&tE%)N*L;!C1>;KxXa|vLtVrF}o zN#OK-IocnkF~D8CCeYt*I@@!a~P>aQ+&G7;Jg99{6|BC0qD;i3WW z0*%)MF~qO>a0C9A6R1jXXbpi4jMV5dPzIvqXtfXmlsrR#91Wut?#i9EUfM|6 z*}Yww-zx?TX(SDBd#Ia*fH|37V|0jw^$t%mO5|QM0Q%gUH+nLdGq*J%{U89-e!>!V zoMP;Y9arr2%h~q@*bXohr;fLmi*FP0hI*G4>f*9J@PEWiOikHSE8_g#U&fwU zr`UGM#A`piJjS$;>z#TGSW|xI*EU@3#eX;#=RlqHaV2yiRrFZIjc~j|Er#umlpUZ@0Iw z$cD=yI&ktRjkN|0rgf(im-u82sf9wWghTk1*f=T%?=qVWJq7AtUo-jy#ZAJiRim?f zneo6uN4t@SJe6cacjiry38`IQ1)z*yzl@GZabgbO-|FObg6<{SAyQ{bihWg#cJvk` z>^?Haw>SMk*`l0MIxHU?bcvi`jvhF{s+eI$s6As<3nIeyT0r3kwu)1%kg&D&GbGb} z7pX=KCgH2YDZ(S1G`a}M)Y5PFto2)IS_UqyBZx>8?ezL-Jg5g~&T8XN9iMyCV1_+% zUxrG5%T_(?m zmetS@9L)8X!%WUgY^DZj&(wbxz*~lU= z2rzz;$VMyyAkbf+@UCJ9q$5N24^ldoFDa&_Gap$xj{Z6mYXg`AYz}*&K%pQch}nSm zu_33MM*aL#+7^7_zU7m(x>0=g!$ouJ;|?xSZ`r10h_T zE8x0eWb~}sD~>QQ)AX4bp#MIWl0L>kyTIVQMpPxsR|2N*V7}>0;F*?u{2Af%LRUm+ z_9tGz{7&c;%7c2K(I_U{?)ECsIWq)}nYlQ}=edwndzzUAp9S59F>Z{o8M#D+d)VTL zkmfFiFpDid39tQNZbJnzzr$-qwyL%@ZQ&7={B^vlT>^>DnL};LYuu4+;_n z)H*62d~enLmk3yg*>K{?*=wkuMeE`W+2yVWSHFXOfgocgEw=Mrmh0S}clq6nTw~s^ ztmUVV%z#y6kt>akriL_fS;BmMa>@&_+Rvz3E1M*L?`0GR2n{iVXZ>nA%$2r)H<+#` zEv&$^0?&QYzB=9Hc<=W`-pNbKaf6)v!cB5UM6vLr7qD4SX(u&VajjJ#`!vlaf^@=X zsRvian*IFc+tf#kCx84DT5S+1>Sw~V_oAEoXDv*+>O{!S<@=5YeIGBVw$k@HK9?LR ztk6*Nae?2u)Xi7&p|s%?Cs^4&(F>9r^h?1~gODKJywAeZrm;EqC5R-+#Qnr!B(QDL z)I(CRD5=a~;e~r8;%jJbB^bN$6iw8V!M~RT=WkA=4xRp#j8KGjfs<;~nv49%qIY5N zW_N@}UIV^e)Qg66RQ-~CGO{At2p1#hQ#}}ow-tf6k^EpHTGeDO(FUdH#EYhtj7>xC zctPM*bIjd|z(=aOr;4Vrfi2sc_S&I4tbb_5(zk$o>f<)t5;zmQk4IXQE(wx8lJ0zp zR8?rA7(o8Y5o~VtMO+5c#Dl7i!ZvTA@{}Y+*=tv0M{S|B)S_hpLoUknl>T~n=_GRG ze19ByJ$N#jExXA$O>iRLnXTJ5isPC&VoTBUM1->b4%enwOd|*QKb!gB=GQMUISexh z$vugH@y^ups58;-)lUn|qbE+Jw4n1PYmM_(aRItM1~a-zIB{Y^hI8CkLv_It&ao_U zhJ#vtr{zYtrXEc`Zy1=Xx%3?kuWOR?_lmKX5T8orr|D$!rNn-<75Eg2aLID*CWDC| zGqzTMe7?Ub&NPAvmP@}n-{N@q`pd$f9`gB4@al(et~GSv#}ftZarcEkvlKydMz}IH z67UkgIZ*Yu{JEwwsh1Kx9Xt@dOR(ZNV@zsAwKdz^h4b@vwu{F$KjmfO|4|on24iK5 z{!CYRH1>J6bT9=Tbe{4Z!9(M0HKV&Gdy;BXb!R%r?}QU#m=5fViW zN)UZlk@9^4G+u4YEy`Bu-9g{&6oNV5Uc=SOw2w3rvG;PDMoyJAyB~;4c5@d|1^CA> zaChK?O6ESoTtNbPrCUaXofFA>(-}z7{4>v|!y}QF!(ig%5T?w{wbmlcyQolUPplK( zlG01E`dR4(_Fu5c9Dd^P;=m;K(K?tpB~9`B*81KMNFS4r^(LkVN1K4YKj+CA>U zQyAj^>NW)9Z74=sp-Za1R#zPHVlLT(a*XOXSZcxs)6A$l zNFT?Y+TJgdkSdKE3Kxb?y$HR~(g_OGH8(FPStT@RK{Q=p%A*^f+oGhxIbTI~58&$j ziMl(r>!NRB%8>=$iNWGuj>KCsjk;8|%*N(6r>$1l_P@x?HFw`fkxD!)$LqjAkIWy_ zp?e%pvnui~ydkafYp#x{3rHrJcyOF*(d^KI)V0yXU)Cfq6-n!ydM10~Tr4=bNTI#> zl_Bj?qDJV1w$|j6>bb)fFBEzl--2?NekMF_mK3fcg-_sPNPFZNLjCfet9niR9?1;J zg&uScI|sdXrPvmm_;Ux|$I$#N;3Z;^YHW#)5gNb|ouxl>b0o26rW*TEF@(&59&f); z(9{!&1;IJs@)Ci#3oR1rW|m?d038-6s2NH=MS$LaGO)yb1V;Xo zJdqnQ&JJ$wyO~#Trm@_K;?egChLesLMkIX{$LCo^&&3f>Pupzbd&X07RmP^BRmd@k zO<|qS>zqvs*&Pxw#W^+{NZloTZ+}*C&$Wd ze1i#BgMezyb^i4?PW|RHur4ddZr^V)&0{`C;yjP@NSGEe%mHFSJ)Xxq-Rv$5Nc1o@ z!B+3RA$P`g3@+)-cOe6=`Pk-ZK5h2+`Q7J7WUt13UGR6?M?~-MKf?fB>PwxHVlv*n zHKY!h7Xl8wy?i^Fecg1NW++&4T(SlH;kPYJiyI$$BS=BxOzmP_`htd4EW}!u3vNT~ z@z5MP0pG`)mFT@m4RDtVN?fCGu+a!rVxJ=6zuX9C-)z&Zf-4*u~4w0l8sb9)(GzcF%g zOium2Z+8@kjAZh8TSnzIKysGoZm!>Y6G;_3w|PJ2`nb*U*r*#Iel5hzPA{eXYEOy? zCLV~H02e>WU;l14Yp)1F*s`^Iw_K?1`4*hB(0S9fk^duyNHK%pE8M2IWUe{P7xYp% zxVV`xTGG&9^RO?zJzTC=v7}*3Q4p4rk?>Fhcmv2{7TWwp9t32tPbl8ur+)c;oUr3H zT5VqC{)Ix`d3ODrN2S`?uRQ@scsRlFh>!;9@J1(ZY4)!)qi1wGHNTB>G;6T(rgGj2 z-{JOec*vA$@Ve6=l*0ny$D3D>w1fp)u^&jqohW-vmSIR=?k@DbQ&6UBvamEj+4#*nNYVppD)0jYQl|Fad@7)>p2sHR9;?#1m94*CMCOS?% z{N=U8kjRN4)ICH7;jV+W78{G^75J6+Zr#1KCWFaNiMj-?f4<^8ufK^ycAp+b1EU6G z!iy-0u!4Do8#l0J;M+34JrccI1brdILEDlGXl=5;=H!qxI_N0*m&FsyN1_a{^!mC| z0n~Xck0;E(%I-ZDd^NiG1vj8*E_WBStxey2xC0*cKyr{V8E6tjJ&-kEj$NNU0J|rQi^t1wDM^qu@!Gnh17u74f>l~MgfI7`##@yJI4ZvHyx ztX7xqJE2(+(tW|}>Ly_(AH@G7>#f4#+?K9UG(nQ!5S+#x0>Oj3TjLruxVyW%1rJW+ zZo%CN?(U5ScTQ*RwfFb0b*}od-)GK}QKQDJqP-+~UHAedkytjK@Q7}Pk*F9e$xni- zq|i3DO$gOHQ5F?YMhWv?6h`#wkJeE#uch5QGuwp;-@40;YtQQQD$4Nm4?UY7J{c^_ zMAj~P)r8))e()c^bZPGcn^wecIW4h2#ry}S3fQ1-Am8sy3v+6j&z`M@gTE#@UwOr; zq^7SGQJG#0xKC*e?AF>QiOspF-{vBRc~DyuxSr(azeGoDaLL{(_s!j!bFA){zWg}t zc~K?*6)t(5o#Sz+gFuUI15l-}nG1+qNIVrLN?~A)q~YjZ<{gRwBjck4>Xmxa$bbQF zHIpyCbsZ;@W~rk$n@ybNfIX{@k$B$at{F`s>%b=ww7ayTv}tM#qTcwylYT zg0)XN^sgX2wAB8H7DbhKMz@=wO<|<(Ld`g0^+bfIY@vY?o(~}!|+2B_y+%PEvHL3!3pv!MaI?pnz3o=9T!pOC2HChM#uSs zI4}mYibLi04qfv{&}i$_W4b>!c;TSP1T{Yq(eubt_2XTb>vAx1#j(*7TFXzwo=_74 zED(3@sNI`)NAI9s2_)Qe!UJpzu`I zd>thn)ZI00{kpyPFZ6b%s9x{1`scFCi11_%1z|^y0C-Gh%|;vNkojh04v0{Q4RdhK z{Y?TgdS0_wUt>b~(F5;XoGQeX=;ubbI@PrS=#>jf<*y2YKfN7aVK?8=^tr@P839nZ zK7=b2$9bt8}1>Y&yb~ zu`t&L&C(h)g64T|24uT$+kF}24Gt7&lDaiv`gNAO`f$3p*0c=g$hOL{ z!p23&mp5xYYup~vjPD9EAlEKhoDi_vk@#1b9-AymXFJPAHNDUasl-JtEC7v8cpHe}CWVnN%pQ zl^%f#A$ISlX^tS`6^BaFgtPkHpLbTGSj~8wouaRi)A9*=<6I1{FOj)fdgh$#-uo^+ zZMVGoJH&UfcOUfc*|#r#%dZ+q7u(hTAcIT}^F%@W242F^!Q#96-GNzsfrBl9Gzt(q zOA?9`kb!&Akme>KuDnYWftKo|?0;~kNmgtZ`kdC$m$Z-#G(;^>>)5c5OI&B?Poze) zWB8pfkv{S5$>r$HIR%sV*HV!ucNvwcVe#ZcjIJm7^;a~qsq=ux)Cn)e+f&>ge=dF& zCG=)T*}Ga4Px97%FJh$mBZ7?~%6vYN-?M5ul<}8WLCFg9LN%`wx1I_+x0j=)C#LoE zc%nxUL2TwW^lcJ5uP(b07i}de`j&T+yV}Ph2rT>x&KM%dDi`AX*Uh#qRh;B()DBU` z%hJ|x*z}tBupP?hVV)75bUt^6*$ocg@7<5AT+Gd$^SGH(boWSz6f0lkn~|HO98jH3 zO!;4pMVZQja4;4s5*zh3>W1$xB+<6Mgz6LVo^OzCM(DNo@nHla5)@*3ZeeF`$AnkC z(ON-SVerX8In;Fe9kicb`Rm33c0AGeY~d~^#^AE=1{MAq+=En+Y!lZ;ck6jLc{$EC ztsQ5}*LDj_{60m;-R}Dg+lLy=FH`&DQ}MZk@LK`h;UUt+7ffE`qNJSrJt;ddu*(xX zk1}-j1rP5&-N(heCS?*|LD#cM?>FCMI^5u%s4)E;L!nIstv{UVG)Qgi&L6hqQSBdM z!JWWQsJxQM0eWBWcsYiHIvsYRe^}46CJvysUnLw3bF{mK@ZN1@@U|I~%^M>qCEv1| z-ktvNDIQFnM_qS0*nBtqD1EIEQJ|7h^m>BwIzxo_yzTO;6W2wxa4YxIs{Q0Yk)_HH z;T-jOt8@qB$RCxcT}w|%dexa>IljHJr?H)&J1FHSV#A%GKx30;wFc|Tyy#)dnRu!+ z`JqPF>GiW$cDoP^=IL+s@_N;I?v)YUb`Ke0Zel(LgIRC#-tm%lIwz)Qj0+#Vc~f0p zt(SH4O9DibwfrQ;Gmm4CvEkk4*SEN+}e*PY)^!6~KuFjj4n`)|97ayv_vopx~NY?@}|59KtxI{wr( zXnqBjJ$T4ACeH1l08SD%k`dDSH=9A>S4BQxr#(G3dmTHF>5`adXjT5}J{HY`At~7U z=@->iTgI2k-m}g0^*cOd&0ZGyc53G%WP&6zXkGORsV%XM8D+W8#u)9Yig$e@o2}L` zdY2_fqEo>9j3?c@aUK4u2kDkn5`()Dy$1s_OO3t9@y3p!(6CBL<4|;GUFl*##>+Uq zF2mL>RkDil6dz~ZZMhfEUI29%IhL3IyZ$$xLG5P~{Mc&%gY5#Pjhu0>`H6Oooyq;4 zY@aJ-hPLT9~>(i=Xj5tR*4QhG@!azIm5Q)>BXCt=?X znS5q%VU4U9Jy}7ck#fEJ8k~@MI(wd5wfs<>n)*AA(-`$OVDADNnrLJA#=|D>?P3&6 zFTp~NuFj!JEcbCg3|Zoxf57NVkPAfAs4g<2=Y3N-_TeUP&vP1I&+0jZgtFi<`S|cD z#oJD<6}-z-4W$GpmIs-vdYpXZ&+%Wdz^0nU02$I!r;hX|jcDPsx>Q?k@e z6i2H$BHHk$hx_`I-rHnjY7&xKc$>VUr4WpN zIE#Mzp~7u5sgUt0EwK^KyW0f86QO~}k+Bftx?OIcEPR~*>BBSf-umqr|1}=jSRQE_ z#cpiy9nvneL@VPD1+SxY>nakNCV=0uPlRWY_i1H^0UWCXd~LSNP_30`v)FGa>ddOt z5G-m^oBO?!!r(rW3XX~Sp6@&&t^=6Aw|O%aUQ9HkW|nx#sqSpB8g_mP_tI8KLtPDz zK*o}ts_oL%8!8dnOkKxZ9yBcPUWm||gK;NO-d02~&D=4c7N7b2&a}aDdrm1-DAJ2O z%3A$7b_SkR`jNoBNU$t^D0tqUaC6qE@0KD++c@s`y{PTOINjcdyS4k1GkE{OxVQ6I zXP(RJpI#?MUHprmw|I>5i0V9bQDU(z>n^vV*h6p)LxBjuP$SP}C4Q7aUH6lS?)Q~* zP65rJhfm0%sT^4l(ykN2-LXSMTic#HyyVUYpCjCcuafJ4n&n<+vx9B-M3vCLsYJJ9 zJg`rSdkt9L_BI|Qxi4f)x9PS$N3@TOU-GV?>h2%u)_J;;0+nuo6jAra+j)Bzp`Ph+ zB-ZjN=}oou-MiN1k;_@z#m28=Z+mP$ci>^h&>CGLEtLEo!3jQYd_VFSaxvsJd6!kw zHEx5ii&~MTD$qGo;v!Y<-q$i)QrGRpczZ@isbgUa@2l_ss3Q+SSyj~tM&?e>EytI= zyl>mD&fS)>?sBA=(`pEq#raFMwH0u4CCJdZZy62)a}$k^Ui=fh??L#nTndR6?C3{@o|6p`XcUfwp8HJ)R#_roZ}U$o@a7t zUrT2i_rn~$(m_w1#7d1`TrPFc+1aR4^p(6Pi3#tuhBu1hjN2BF#ftTZ#5*aT_6!1M z89>DB@x=+BI7xPKU$6niUFa&f`RLA5PMBfENOrJjuvoZ-NKCdI4h{hva^*-7E? ze@`Rd4>k#?#%Dip7f7OwMbe>-RkKl^mjlhy9OR_{yv94cr{wCvX!{K0Yl=}6m#D9C zcJzjXhb~pkzlF0gKe=k%rMx~?;zx_Lg&1uEV0Y9AIEMYuz?}g|V*MZUzVixR#tSHZ zQP*$Z;M*u<@|?x=?zo=tR`FW15==Z`+8^-#3Y9~!Px;;9*o?-*)Rc}?SG=da&4b>Z z7a?aMUneorGwf`t#(h|yXMYw$p10uAcF7+jv#e9;t_x0oIPTn3in+4MiihVZtby5N zA>eggnXQt<(k%ND6P}jOj{jyTz5Dg|gpch0j_VXZwCwpOfAYSU$$|Bk4xjnG;h#SD zIHPTy%8-dfsqP~!snPS{oUaPtDZZ}K?>-(Pr=KPa+MTDT*;xkw%v?Bd{$t`5TupBT zgC_2|8C{S?o5S>VnNbvP(3!*SGhUBP$3Mj=MA>KQ_Y6^G6<;QE7g~KN+BaUJgow4v zLO#o%_l?wBH14r%6AWbj&O4#X_S9@oj|RIdynA%2__QDY_JgbzH-C;>v_D~4RXML8 zKKqo3y*0%=)x{)#@_OUEU(|x&auaQ*ScT!8qU^-&H!|qa@8a5~O+*_l{u_wjg&*re zhq0Wvku0>sY|9G?#}O}Vy(qsL_I5ho5&z}o1b%CPP8`8Dyl$V@vD4WS^=VXC$F3wm z>yh4|+IOJFh!^zrIGBR17V}wI{@JQ&Gh|(=ePOEMfJaP^UHYQ3uIqMoxgh!r%Io2w zyDDuR;=l!7QRUIgKI_|SouTjb6z+Ep7XjW4s*mLZ*5(!97qE|+$}i=XiH3Y8hZV%9 zylMGEFu+sko8b$#lh6Gm6-ppajEosU%!!Ly`3CacS9siqh81%{Q!Jf&2kq40?rgOe z`c@hrmv426TcIJgv;A!f<+X=Q zejLgj|B$jIsI@Q@Z;+TKspDR}M#^j@zDx`TNT7WFs;ksl>21JZ?1{nlVzR$BC^G0AkKFqoSy~M z?fsmijY$PC&MOR=6@N)W&u6AtWnbPv)^INbMoXW|dc}z;y;Z2HUhbWigrPWDDloQ} zy5f!2Duazw*cbeGqCDe(?v<12ti|6G}s zD@s7SD63{&w|b2e$B<}`I3NF%THXE?qfAwc#57u!*ODTMl<9sCFVYcB_eQ@y>tDk}-qdNw4WeoF74+up(%ZSA#cO z0;bkpulKBD%l0Cc-`b`XYq?b{^L3GU9cwS!sc(zzE1}M~*^630#V11aqW6sGYW4{W zImKtra0Gsgs2>rOlDrpCHm-0EX)`TeCOO|rD>^a7usoE@y7e9 z-KCKQ=eOG2iwj}u8t*X%@i1G?++IWInJ2= z8A2R9e1_IQ);E7VjzJB_jpsyfykE{~;5pM$3zVsze48{}bom?CpsFI>@z|8RF+uO- zeo^;5S#)KATu+77OZ{z*7d}sNPlnfFop$rp@0*E{SxKTNm%h5>7c@^ujP6~rY-F0l zT?cs-+~ZsptpBWTRwi1`25XfyD!+XG@X6-Uqo~GWY<{TW#$6R}Th7TcF={e-w%>{Z z-;nU-^lx$o7Ov@)?~E%P)k78mGTR#|f_&<_ghA34)%vkDt0W7p`3$`x|Hkp4^4k z{>rC#&l+!GzcQkfj%g}O#A^$^YnIEg;fs6g(6*@RZ>ICzvhQ9j5zB(((Q?h&5Dk(M z_TjeiaOM1K${WYMX;DNVx^^KxF~uL1Zx$UGTRLYlSIS)N|MY(Uz(@i=SutNGb5LnF z-5OCh>_v+Am2Yw$&D3^@wdxTS{wX0Lq3ePZ!chpT|(qZzm1Kmd*K3cg- zyKf#iF(}?n7MUM2x&Zg3WnCJG%u&kGLP820pZ#Ej&`5^81AC>E&)~{hfcaoV`$MNE z>LOb0J+hU}#L$_am>yfcn1h*?8ifZJKlk>#D>Lj(?%E*FMlcFWVn+@L?rVLR_$&23 z8QcZtpLojCyXk03o?*XN$Q6_2YY+3B#!V#y8d6AKtktgD>z` zpkVI_HNcM)F17~yx*0}yjtl80REF{(ubeC_7mM^|8_I~l-`3qDoExWp@mpzX@KD_E z*Jyl6o15y0A}^h{X`cT}4D_c3daM9v3v0U=A>6bdje7cIaBB_a%DMC_ej(;bP1L0< z@Vq-4GY;@>H^kvG{&e;jU{%`p`P288R<}1+lF}qE!VJ@|n~D8j%Mp_?NuA+YoK@jw zId+JC?2pEMYM@)LnLE9f^^PmNjQK*a*M9jP(c~hBMFpAumUx+Ly&r6!mz=>76n_Al z8PD_W;l?EN`-C#m@Z(HgPIJU}lA}D{`zT@G!>@>0qd}P^Bjz%-ND{4+9XKAaq4Qvb zcZ@J!IIngP%5eQ8x~pEuBD=7AuX=vmRJ~cx-4t+4j-{{h&V?705{D?npN-ZR z%NESkI9`eixvsxrboXxdsvX&%Tp19PS9p3eN<5NixVhQGJ-|cHL~3&L-L7g0xz(YD z?`nS}VpuXoP{k}YW8rF<2IE}5o%^tv#dT*i2+ZF&z1i&Qbe?IrvkVLEFRNoKi7?-xXgRPY-|}0X5Xl z`xj=yB`Kid{t)#80pjLY(QzW~=xi3$%tlZ4Kr*GWb`dzM7=-aM&JDL6ubE0HspKiw z%Vu$_+X;FH={GRYvXkcEFoZ5`n zhio>MttLrH1lgHVWu@4gP%7HN@x#T$*BNJ+dauVOaVG(!Ld0F@Pxnpx^FOYbmS{dX zZB}~->7Wp>2*Z;p6-AE*Pp(oZ7mdrzjbi!AYK*5qw_5gA+^qf_1dke`9JpV_x3iAD zha?KWQ&d}}dY+6gDgQmGzYmQ07s5=zm-G^#XjZ5w+NY_Q*0qw1_b)(zDss3~yRP%w z+)8mcMP)*>IWT~XLX$O{qa$q0K#^ybgiqB)Nh$kwiyZqxS7r6PHkjjDpU)Ut3Ww%^IV1;?gJh)mCB>L>k8+;&UWJt&6hkJJQJRn zpm}WrC)u2cQeYsILEv+OuZGSe>2LvQb$rFWXpOVcF!bIn5zsboE{5VR5YkJqmt^X_ zrxlo8km33aP}r59MNsiq6)d4O*5p$KXg4}3`BW~k;Z-a*azs+6d6qtUtr{1ulp*w{ ze<1kKC@*7eW1ymJe>#|>;BoN6%%X`Tj``i3Iz{nIlhC)BeW40wBg1}&cQC+3`20$7 zo6bns=~S~%_wpgOU|hUNZ|@yu{e_n1=uS$&Mn0Gl`ef{Xe)X5`gcBw`O5i6q8Zm?RD)XLS%xJqKgl1_vnN@eBO;)NjQ@ zIo?)8^u9TAywVb|gUoeV#LcUy;!8`INW9I(yYZ1IMGNXHOFkDbLhoJYJFLqRRm9ZP zA>WqOKUn=85hO}{So_}G_xIQT_eVe+?#^mWGLxG=h!!$8n^X*Zeb3CQg{(reErF`p zV~p0}=3NrHiHFKK9x4B9HtfO>KC?F%3Q~#sp0G1_lT<(BvRq`s>C$9WvMR#^--0Pl%>2o4JJ2u}b!vNBCD+qLzPdqCLdT z#6-cqc6QPOa4LFo{EY{2(yvw^4w;w!>b)_TLpk+hSehMW*iEarZs_u{G+q$Bx zTG(}C>l!`>x^XX2zly_{XZ5k9nq!$LA)m#2@Uc6DcDjCd-1U-S<&*(wrAPk#4p+^p zc>m)*f@6ShLdoin9k+jlem_1js5NsCw~F+E=*lKf((VhY)^qP>Jw}K0END4E56VaD zAx2Myv{bsloSg2mcyi$dy7cqDiLKYKf&DS5LOVG^lZ*xn|AiEk32iG{qjR-LX;eu^ z#az`wi<}=`(-`&4Ek8f9Xr^0Vrm|$QV?zt3aoO7%9$hU#K16>S5WPS zssi(Y7$OHmjEoO*CpZSBG$ttmK*;^78$_{G7(o|nS|hr{P9)DPVFFT8GvCXKwui)$ zeoJC_7H?}2o@!HO-5ma1tq{M3G3BE$72A(2ba#`d%!2!~ktP-4P$%>KY^vDcFg(Aimw6e*r_i(24^dG3 zFE9Lwc64M=1CteUW9F%D8srqvS#=w&l{27OOYBUo5c_(A83> z`DcI&&}it(3ot2-{~@! z`$6jmtsz$9u6|B_MF=P|Q*2$K3Z6a4jBKDJ2dG692Do zB@zARP`|P&qq!;D)U8C&q9%o|$A{`g+o)AgVmyPw)!!+-56Sg^`7wt{B(3BK?`u#l zoC^o%&JW_PHk++h&OS{A1@gOJ4cW?pJ`R(fUhEmw3yU|pHXfAQiiCHCn3irr`Aw^S zOkiMl>PfRXc!--77>5W(&((!)Oj(fB*?4fo`h$-F2u5^*WfGT72nXArR+#nKYjfSk z*vPy8Fx~nae~f1%c=Y{0@yr4ULEvY3KE!C^S(X$PNof5QtINJqoWrBBnr*pg#gLH* zlzj-RMhB#UfRXA}$x;!kCLIlF^v@?hbc33ndZ$B#UOMAuB}eDlp5$&d zo>;a_kT!NibooxGp0AXvkX90{>=5WK6A`_}N@bVchkk>mayXf1W@ILNth+2Ntn54;@OP zTq>3pS%?gZWtugIOPf+k4Sf(vfb#=q6HF)^-J{{v{T1KMt*AjSFJxyej8J!xFkZ^&`vYRyhwj#A zn!gpi@0F8YgI?TCYG?w$QJgRVF_1VIz#qH@`;Uz8XB7!$E{~w%Ni1ZEi7Dx2*bEJp1&aq)8Sh*HsBLN-Bv*i}Szy1uyBwviFYGko|=P$(^2KWI8^#lDu_zMfJ@ zbmV|llW0Bg3w*J}Q}4G8(gsTgXAWoK-Yw_O1hOhp7*Y}BK4#CY_E;|M&-|c*IPGsU zJFspw*homKqQgUKm&c9_k*AD{u$j&7Tf+f{X6q$Qh=bC7+=6$Z?U z)v|ov=6}o5|79m3f!1YzZl{KZj~k#eD0yReUMUO*t@j_z*_0=T$BX3{k}ig$yOg~hCDlHsOcX!Gey7v6G^|KB~l0Dd;C_ckg6QL-h z!oe#l%GV5Uo(=o<_>Xh3{jpZICXdp8St|rLOo4%}_5L$@&&6_?WrYqu_{Y9M{?I%afa*%%9B`P4>i&mC8vIH)r3-7 zl`-*h`3=s+L&zElN%5s2=@HwCFt=$)zEsf1zHC}@Ges2f(bdofd{RAtI-OEE_LVJF z`u0~}&R6rE3#Gy$(E7fJ^7F*e$_O1Q;l6OjIxl=5oeKntmy78q5OG;MakP2;!?Ynn z{th(XcmZhk0s$b#bZx^5aV|`}{k%HYj+V%->Mabf!E5$20%@bu7Jskf@+s<$>6~I-rp5shM zNRTC4=Uo5qEP($zq5~JWrCE>|&>WH1sN`PxB;mtnk=9Y_kFyyFUlJqXLCWI8&->d> zrJLqL3W7$ew9xCIh8^N51vm?gZj6qiR*^)Zd?9_4IxD!6hT4lhZhjWa3KDu7ay$Un z*A{9j^oCSt)w_Qm(9b3}LHUaG1C+dOUnJ*^jwbVbn-Z>7$PL3*>AR`IL`?u+0giDk(<0>g4QzZpZ+UC=}{bkr#Wy$2=-HQ)5 z5yLFd{ECP3>`xSDR%TYd9`Z{)NZ#ubuBsqiFLEUUCd<-9xm2;n1u!t?zjux6wl5v-eB$gh8^BL4>-ExBQA-*JHuT}Et5>=bw#^mU^MGN}5;YCg`E8KBrrYy;qD8s0v8eny!8la)0 zlVb6gpoY;`rlheYVjcvG@D)&)1N{{wo6{71neTNZ{1pV{`U~#o3c>w-zI^Ggs%S-f zd;(6!K=wDIH6*H^p_-+6%5O-VabUCsTjGuABJub%qJ9;~E=FEpca#^>_o?`LIt=TH z8vLXbPrmu4cZ!lMgALBDOuH?dGA8v41MB1}1;GU`6!1Ruk4y&xNRaq|$UR?8j(3=^ z7V>hMe0qV!*AE$kQ%WpMS3juK#%W?z*k@?np*kCgN+M6>_Nb6lFS|;I0<*8_CP%(H(E)d{9$*`JbIE#dsSy{Aih39`I8~=v@^-IwP@yzNFRrBv8 zmja&_-q~Ndy1&6nxci3L%&t#EW&q-1%!Rjg6GY8b!V>(JPa*QHTYw=pNUVm|#>8DL zu=J^_WCEF-3^D^WF1NXau=e6Ok0?6gqv$7da&jX|=~prU&D0c_jOjYp(kd<)xtDU8 zAO^0KFCAvq5(`Zg2l`!@Io5(68E?5RxF;Bx7V^3O4Q9gF~s%KrFG`s2Ui@x`K zMK9&B2oFj8GPpkXE}^gD8yyd?Qxw#`itNtQv~qo{*Ix72oyjxYQEGX7r?_l9>$OsQ zK_$GQ5E_O{(|i7W@YQ4*4bapSya(g!s|Ht%H>LjhD%wVc5^>lA?CYo#k4@Pb-xl!G zPs$1C;BqDjzM68-x8>PQhE&%A9FX+B^j<3K?}uuCH7owhz1EXL;ZoO|U{lb-kuA?^ zekUfDH%A{bHj3$~Ti#MWObdE><)L6$rO!Vsr z$~A!5eJU&ys^HPF*vu_bJFN1sgF<&dUSCFsCl;*KjD>36CB)-#S$i1G>>cxt1Ai&Vg>kS9z- zsCT;;^S&v_d3v6}vy<|rO}?E7=UjCXVlf@kqu(Dpqm_P8EQj%`PL!6I4ctPh#fnPu z*ZlqCjT0@OS`yg|))Ot0)6u6>C?kfRu=Ipt%aan==VZie1XEqi?h0ORwRnfTbs0ww zh;9AgKsZRB{JZ`6kLoqLGnn)j>FartIoyxIJ`>%Y&A}=fmD&)LkjR--`Y0RoA%1TK zS!3Foa2Ms;3yr{{dzm2hnJITW1;k0*AvpxG73f%$q!M%~H8M`fx{YmBj{9mve@wB+ z8Bzu-{>N{y_KB@hV$ni(4H9$kq!^Fq%V{-Td|H56*iSP4^cXajZuMr;FV$VTOMVP> zZ|$V`tDtk)+7l-pM7+^Y*nq(zSqm{nF|Q{uexGwRQ^G&fB^jUeP76Cd8AZX5JnjYw zfmK|UHWaN$VQe-2EdxoZE}ouAxuC$2ZBAu*;Zs$ZgUuNYAj7MA zoWZI8k3k(%!$HL5ONu(TG42vi-sj7 zPazSdH&Y1{s9EI#3Yt7tf#laegxLJiX6XWHBNIdW0-IEHVzX>{V$%r%&bx~adjsn& z*bk~0K;jfU+-Z021-zDVJieB4a5Q`xcJF<8V~b-ui@&;k-OtA?7LO^39F&V+s($iJ ze$I*JfsN~LLeO{P-=T6sKq-}Wn&u~Sav~^`nUvC4ihTZoaxBb%j6C2Se>1VIJPSEO zdii4Z9$OIVO(-*=_aeR!n=(rh?eG*XNX3-$cThTFPo5~5kSS&9=0R5~gyAysRsyIY z_hm%m$TV~3yTRHGUzMutceiRoSLvwv(yjrN_v>sVtf9?Gb&iIovp#~kXucWx{}|vn zvJV4Q?}ptYFZUH7X34HN4-*lxKZF$?S}S`2;XWgm|lVAs^&Tzbsen1(0gaYr^7=KXM!Dxn)_eZa_q?|;X z;A&puOTTcYnaNdA_y(po2tbKnX!qJd5}Cja+T<7E_ATjIe^s-lz0Y!}g;C~Y?}lE@ z1y5nm%fsWHH1jQU^6x3_>kGHx+G;{zK#cnM_lEv6vip8Ng31c$tz1a84eztsSvx{R zZuFdWoX6#b?QIxALJ(T(0pY+!AMYltd6e|g!LQxA|;C!N-Ysp zwc{{y;Wm?lAujwKJC!qc0t-Sw)|G|I_%{W97BSLf^(F7RGCew&U6>Y_U^FByuhf1QQUd9S9Nb=}MGLSMe z93*|vcvJ-rEY6uKr{{j501;W>bYqIrUQ3Hg*N5pCDfu#7hjr=%zcp8nD{N?8_p~mV zN;R7;<+J!1b_OK#2nva7G{;DR%a0t6ufoA1gQLHGFBRYR9=7QAjl$3l? zhBhG^#M3^Jd}s>H)~qp{GaboqH41?bpf`qvVVmoD$yj+OKwdib4oM)C8)6ka7WV)T zfI^U!QtDbK96jk~iOzG@!8AM`{>FiEcpxp(Y>9tr0pjel$AGB$)@y??wDQIjPDl_gsP>D9KlR zlpJtk!zE}-f^AEvlbWbuKQ+7A!Qr#z$v%tQ8MPBFEOr)ttABB^1Ati2>~q|3G``bW z)jxcw6H*?jY;7WfKK2PkzQ+-k9Ik;kC_qu<;#NUa0e!BD4eGLP7(N+m*T1jVyrzp3n`>pofVJGf>?~4H!u*K_WdlGoZHM=NZIxM_4 zrI3h|Wsx^09B@$1*iJjD<0<>G{mA4~vQl)oTP8PY;|D1&nlSNQWt9&EqaEN$*bAJp zzz4?$C1kRTws4f$;7}D{Y12Ca$W~eD^U~kEN=4zWnK**!Nog~Qppxtpu9f3o3W^KZZ@z z)mnCs^5vdzYJ%4lbMT^m-I?Y;jY2k0f8ASFDkIAL@bfk%{2gI~J`gpJ4Zaj_ zRVAL(Nw>lU5-8c}U9qI*4#UzARGO_(Y4nH`eQDzo#CO%O;<38xX$v6mBLhZJ1=A?} z0YQo_UrmD%Y7aAzR%u9)g3b=i|(3 z<+wSxEcW<6pj5Cx@fFE|Og`7MZ0NZFRgdsafo zw0KPg+CdexL;^BdLQpW`Y}DsOeYH;{*q?ojYiQXla!G?e21T+_s^k~P)s-N#IEh`$ z%Maq%rMF<(*JUcyi(S9Hz*d7IC-N6SztmI;8Fm=G=xUmJDP7wfd3n$Fx{Yvb32DBp zE^b3skN(?({*;jmln4Z9IpM?xp(1x383>&iyTbLwBxb9$Md_q?A(b5f%*s}FV1epx z*PCGlF#b9R0c6rPvy>Z)^v^`Q3K!ek-Nw!sS(jsJ;rkEHpy(v$%u(Z9m25M2a;P7p4t9MYdngcb{vR1_FZE z(!T&d!JFyske)&*6w48&Ce5%0PVyR)$pLr((u(oP!3jU?8!+`|33;i5j>!E$JFM5g zWWJ;2Xc935y3weG?4;?dGs3HH$rGa1(2o=mAr}`Yp;i`b_EwtfzQ~)3R?V3J)Cv?- zbi_u(1&mX@Wv+->u#L+K5F*(*-v~xb%|azaiH)1TqLZpVD$d8VAc5J_*Rj%Up5B&^ zHY~sXDa<~ILGS_Lm%BBm|6_FjGrcAoO#oop4s;9ojoP*Ohrx;#)%R1dLJP@Yq&mh$ zCfkjt;f`Ub9wtHusoMd|*CaFal!_@Y$`e0lBl#mv>88X&J? z&n^z7(zw%#t?naHG$gd~Y-nxOezV!2q+-ZplP!~)5AFO#Zqxr^a2IlJqyMcq_^WDo z#|?85Nc+6V!-ppp5|f}1<@@8jb)y+@Ij4uxV-H|%*BUtz%}?_I(uj`1`yxnwmxa)4 zfpelVHS|6rz26jjk0K?2gX##tL=d%91cf#l92uLNZFjq7y|w>j27HE6C;f@(5HEC9 zVe}mR239`(4%LKear*9^W$kgcz8d+BGRMvNcmy0S@=*Gn{49%4T(jZN5%XHJz>2t5 zxE!T$Z-e_t1MKT#Pth0M%E!al=9~KVV`BY3Spl9hsbP6t(2jY4H-;%+i|6HD-?esicU2cZT}AujXKQZefYv%%bhRCMS+|O*nW5ef z@=j%pj=Rul_g5Z8!yU@r<$tB45CI4*Vx)iLx&JS%47l68_=G?bqQUKzwSXd?W~_dDRO85P2S5HtM-+RKpoen6qA3e z&eg-+ECWehW-?9lR*s)Yj8_hXiy)~4Hk2(uJNhXYIuAn&W?x>~qAkM{n%8S%uUy;( zKw4J2b%lSMMpG)MTk#`W8DN7{{i|#Rf$k$wF-bD;zX`iDFtEdWs*fxG#ETQIQ^q|R&n#k#345Mp zn7|RgZZt5#bcgAbI5&2Du~WZ}*bJ9+RJ6hkI2j~iBZqRx*h)VlKFEzL!-lL_+J^!Z zFaS_g_WjN5|B74wWJ$}xfmsL6)0K$i#RK>;mTE0;Wm~$rEsVbZsI-ca$XKX74=GWF z&IaR{@QeljCMHP>RhjPYLrPy2;;24je9{-;MIy{fMg9WOZ`UY~4Hhr$lqu|LjRw7i3L6?FCqVk?%zRIzD^}jqMD6U$ns1%ausyZWwsIMfr91ym2jej7WJj?s`xkxh)K0oRitzsf9!om zdM2zqlOkf7RHbDQ!#($z2H1Mh$t14Z<$tfF8%{tc+P##K)8QF;py-4aymp0_BDQ44 z$ka8(OLk{)Nd8x8oXtj*Yd@;NNxTTv)c_AE?Kd&O9ZE)2?Zkazp9;h(IcWY$Tg%{1 z_yB%dggcXF4TP3d3kv17ran7%kTSw<9P{s3MDOS$iY`uyHHGVohUn`cDE3@eX5FU7 zFE+wDr+>gbr`3;%0D1YZ{Jx~H4ua@{Doqke@nUw7$P0~lVW9|5e2G-PJ5SeX0a1!rxDKP08luGBbz$-hq#+VgF!?n7(74JC)&Uh zm0*RigUldA8;&q~k;zBBx`+Ov7*#Giu^X=yw7_o(KT8^2`ZwsRAHr6eRsS<*;1cFTriAm#&kmfRJ^d`Watu}qV%gvF&Uf8~z}p31ng^WRU7 zbcown!wuCCHC1+fBMVx&=MEeo8vv)s)QQ!F_8)SpqfS5{oNw9%j33ekZcqwhl7mBh z(oT2F(>W8GJgIaF_+w<}EHer|LV02Hl+Qy7dF9i9xUw?B{UNsiUSV5QnSdp;c)1E(RdP1%qE)FZo0xcssMtTXlPsi!%OKuA6}b9#d}3*x)v2PwfHU&Xyr>iA&a)HmewoCf4N-Nv?|iPh~qlJ^hTe9rjk zPqWJZ%-rat0f3n&C!jbZU&!Q@hf3FQbl7=#tZ0!7^LOhFK4eo`VTb1rth1*gTG+^x zlR$?a?_qqL-)(Ihj1b%gBD+EUte1BO|DU;_^FL6xj3L%oM5#i@LE{SHaKLcpC$R>@ zeLcla;p=k|8M?P=xK_pnY|eCza|n{Dx*4ec(-oqY)O0tSt~T&x@L;TArC4`F>6BM@Zr=nSftMItzbBMK+q zw&$%?fz$Sx8ltCY1jx0m-27Cy^}e%d#!M-~8#4#%vj+bdI@RQ_R8j-3=+EATQn3OH z#>S?gs7?jxheg~sMQ}U*!SVm25qk;0$<`33u;&%8+}?(X&km{e#L6hvDs0T1Kw-!h z8+^zo#4{>RAKd-~h*`aIO>|Qz&K#IDnX+=0a;E+sV(?NIKwm^Ncs3LV;Q>U7^FnLy zK>!e=p0ibMQvH+js$hgE0Ql7e<7)NKtl_fzpEUsVeJDG^P73NGHc_+J7ns+a}(-;xH1@%eSgVoReTkmdAn+1U;Df!7$WR}!Dw;Hda#?>Pj<(}(eA z31Ui?!_K34JOswl$AEjuC4+6;sgUhv6Uxl6ee|D%F?tll;xfPJrr>B3us2{H*>Zeg zV@X1Yz=^sA>#b+LuSm#mDXwmrPfrFwt^KU<6ajP*B@#%O7kHR|UV9R(a$*7zM`S6m3;Rj2~ue^v47tlwt z&^=+UjLs7-D*UP0>Ap6FI_VTVACMmvQ~15joFfI4VJh~mBIAY;3!dzlOv@X(QM|41pSxh=%mfV2spr|7jJJA>+%pK3~7UYE-Z`B$WAjuLjyIpr&X z6GBS3ad|vW^zbqiSXT2{q*$3>TG;h`{78!o4?Yv8K5*)2o_*sxIUvBN*#oJI0_5fPAr$J&Y?Xp2Xy<~y3+yCCXFK0Dzu-cl|I6^}IS z1fzt+H1pf5Q0}uM8Hkr|_QQ(g@DZ!RxL`(}Gu=Rj-5~oiJ{T}TRW`sNK4G=An)RcU zE^|_7H$FjKhM{1VS}>ZS-@dfCNmx6=l3qk}lRrJCMQlWeSNy_N~- z>iX?>E8Ns?s52mdVcY=rJJbAwcKmN$gNWx{4RTzQg29|7CpwBYuftXX8=@;;F%iJ; zIjpr}J_Dsd%%~PvA+T&-cn-Ri7)%u3jqpo=mF_ocjb?(qRS8qW9sUBdhq1Df zWv~bCR7}C>WWs80s0O@ZDOCe*)Br=o+D7^tZrf(*uZHKIzNkr)Yl3_FLB6G~F=}mF-nkg`BNF&4`A01xZeCQ%+0(L$eK_zRiT}EZFh2m4 z;2xe@?*HeS(tATChgLPPW0GL_mr@`WT>PwBl)1tcsWWu|;$Yz=ElLOp2YsV_9j5`} z{+2|j@mkgxqE)?WUu@ zMPYgJPd+$9c9BYU>5-5}i&ivy-Z#O=5cWih$hto_klQ0lm${&&N(htDb*(NIKDfP>0dN zQx^YB)H`B;6f5SXTFbQIffDgSv*b%mocvVS;V(Q4WYiTApAjA4pY$bN3H&_91koop zAU-v_7g`pw_n5l63H>{y^aW3}$N8T#1~d{E2U7uo|023;CpC6JNU&nmlOFpM^qwWQ z7dA1ejQEa>_7l*3(ciR#8~sovl3Rugn_9mIZL0*eM1ic3QjU)$ygw3*rPO%v|K)G0 zaX>EQ9oQ89Jq_VMY{nfph>&&2yRVF7Troo2PZ3T?Rz4UbHIM8pgi^L=WfDbG2Rn!D za??vl3@4pJ%3Tk40Qt-tpJcwD9Z(N*K@YVkj!2e0Dz{w9%XO5?Ku?EZili+nAg#J>svH|LkO;9ii zOlmnrDU$C=i65MJ*tDu)5iR{uR`98hlz&r&!0;Kcx(2@RPy1gpvW5&iECi*Ps8^?u z=5I@1L~kgMaxYF z6AkBYAO&$SZ^nR90$&j}?N~ATth|@n2L+^z2q$r4`L5bEI190NBjA6z#PH4om+WtkS z+ZO7~SuTOBzn#6{VefoxEMbgF&xp1G#iWIE%?00Mswn-!>ZsFkt4Tn0#^YmRBILwR znZ3cPC<=G#=wQ{j3bFy>Xi7>_N8nRd;y?RHfB{>|%9u}1Fk85Aexr1vx%R|1prl;< zt&NKGL$!Y66Dl?11jd7vQ?`aXw^p(HS!Nc=9%@(5v-p#Pu^WvM;^)oO*gJaYPU;{C z3()IB_?Oo=kR1FC1{iDQ4g0^fCajQ-@TcvOVYyryblv?y7SJs?N8X+yZdAxy!s@Q$ z`c&J-)iLSiB0fIMBNwxQc--tz+w-_BspVHlLS52_!is^ag$`+{0QE~AW0tOCeZT1< ztrb=lW%vZK0n2IE83_HJi0x~noO@TU@ySVA>ID5~cK9ueTBF zqoz)?v8qK^EE&(}VG(o5wXk;`&o$gFxFC3Z?u#1pp@pWur5VSEPZ)?1I+lUkt{yVF z_0c5wiRfAeji+p#6@i1nc!I+UD3oBJRpYJ(h@n`)@p=l-XIbHakCwm9arrD53OQJKe<*iijy^t&Z zeg0`~=7YsU!I+BRUyWZKaX>f{6()`;_BW!W1CKt|s{Btsx~hUe;~Gf5k^kDs2{C;N z`Lq{*s)*XMKp$^S+-kq+@?dH|m+nHnVc*PjX8)LgjPgf+A5!mK+j_Nl-rXs2ajQIN z8X26}+7mYH%Q;T<@S)49<9V?4W022)j>0STryPr|m&E^loA$XsX?^e2OtStw9RohV z>!s4ctaN4YS`+2P-hSv{_0?(1BWj``q8{w*v~|bxq@<{Ce0)6h2=1Zdaf%zk^U$IT zA=C54d*xBt%R%0G0@e!dapSW)aCr=N-0PXH3*Ynj@?9)BIk_62=N!ZO=d0KILl^Yr z+p{)W&C5CS1TKAYYAPcPf&a?Ik$^Tl4l6<=4qK}Z)l$B+#|zUBxUNq~uU}#zo)>;= z|7SMM(LgwRg=;8G7dr7<$c_f>8dsqlJT7lLLTjT5q#Z&CWgKnkc%Z%@3g>!%15zfs zqkn{8&m;U`7x|n4IKp&VxfV4~)=i{$!huzY3J^pguzAm})9u7~t z2JLya2@*jM{11m7eeBC{IXP_&#zM0a}ShxUJS znhni8pE>3?5NjsV0S9j+eQvV!LQgK^e(Y;b&B;ILqt;}M&Uv!aBvmb(@i#ViXly1^ zZ1NmyIf(l5e#}4OL3h1;Tn55_=27)Ipaa4t=#$&BtOlNR8XT!jMYU$kkN{=VFwPm$ zSM!vK3R!B;@mJG(TzQ=^$827AG3`NeetkW-8)EN%Bf0g)2!jvmq^O$aqfE%Ys?R|l zXr9koD|jon)3n4aj*=d8>`8hG{+p4ati`w|0aykaTQoP>q{bp+(7G-Ut^8ZsL-7Zx z-$MJ-Iem_q`L_d8>7dG*4uZoJHz%TGnfWboI60ZY;^j=1L$x|rJ=i=b+;1_`{*P}X zUhq@SgA|8p)Ob;s8KXmc*BxBis}MK&O>4J~rNkFUB|lh9y58WuxHQ~n>Uz6A&bR8X zbGwc*+@zdG8kYRUXTd-7K*3DCbo#$~__dUzs2YQ6Vr zLp#MHIhCpGRWd%k?<;LT!!TX2vdGfnXT*;jr~8p#DA9NDIQn|{T{N?=yEPN;M{o|d zq_S3tU%{dG`!S}J%+SbTP>+VKXA(!&tnlw4<(hN%7SuFpvGRKpK$@a|284yG7&LSh zy6txC>HqLdTgj5L@bOY$o)kyZMCuu(Lq1eeDCT#yx_7p(^(s0$+Dy1jfBi_a`bd)@ zM*+;B!`{4~%z~ck+La4IgA3StcKVzdq{$i!sGDSGN_QO%*+I^FvVZapUi7-P@}%N? z&4n(1L+`vgxLRF$%fIN*#<=j>_PMh1JmOh?f86Y7>rGJBFto&9PD+9fhMwf1JKOA7 zyQ%ir0Y5VHRJLf-stVA43UDeNx8wMjT%p+8d$$L3Bm&`xRX8{_6JjyIe_KSpNsymK zzA$XQjvVSut71J*X6u%}coH1#c{sNRw!D~JX2Icpd#tQ>kFI^e`;i-sjTDUE8E)2^ z;_d#6Lo)rwz|*)8kMtLI2qUHCm$ZuZQ8|dLg7s$WIeu)00e990GHqFxX1-#oEn5mY z{uH;Z(9AP=vV#ew1hY|34gBgV@}g(+xuRrNM-hLfCz@{u?-@%xW0o*!lu)GK==+6b z>&vElJZ}acWU+PBDXKW=&n23WZw0V1liF_@_V_&Bqnm-ZNvUI1miwLSBKR4O%Ld0R zw^a=5S+yA8e?n1&O_9wP!0t%lew$Abj>KEIc`3Ch`mFvYb)|y6Pxae`gL`<^j&2ow zY`|huKh)9NCgYjthAC?vl3Oo!fT! zry=CpM-H5X6lFbYKpVaW&GD>LCaB7L)>_S+1VwKSHrygbji&BsWs$Jlceow^5nPmsaZyBfxQ>e!Tb&t z@~%DU33#rP&VsPZwjt3tm5?0tfvAX~o|xvefBSzAlga~uwwQQ2F9|7{KRDkuv|W=B zF^=8B7e<}DI8_(ND&YCb2+o8A4;SotQlm9fzF8}tl6qgtb~3emV)*-491ik2`cZu7 zr@inWZBlG{nG5n%hrI@b9EV<92J)+dQLHtq1UpWQ*X~O1mt5!*5@M#^c}N&i9%DbA zuJ7$O_UzJyTM0%*TF7gD&qYr-$$t^e8Y4O*RG#~0`ocn3N7(|+)5yIw=LQx!pof8n zw|I%QVRR~#w#D*o@^NS92BZYb%PrdK*RSP^h!ONLbkykZeh5l*Y%4Io6|RG8e2i=EBvo;6NQ4o*1BT^zvKlzCX*lhC+1c_s+`QV} z5o^BckGZm=b2fBdu#=hvXZM%(c)h;L>azA?&3)7M*cNf#@cM9VekabFCJhJ^^2bS= zw0~FgdyVyyew+}Hw%x_%6?_#JQ@Rb{0ijKo)TVw@m1BrqBC1a=gViE6B>{b>N&QT&-rEnN1|l{(i0f6?AZnF8UMi3 zsnJl8Zzwn=1yXK20f^iz3E>7V^cvrL))5!Sn8Ai%zh*o1W%s7r6q_BXC)49P+my>u z#&?OSlOT7YUUp|>4V-@B464+`plD6L0lhcUkx>hZo7pP^+oO~O1998JyAO-Je7$UU zp#$>c_0HDsuB@5u;}6nCE^^+mc&P5 zZEPP_j7AEQH1c~7yZN@pf)VxWmx+ZV5?ZcCR<3(*4|c=orajaf&69SBg+|_7pbg;t zmr4~WPi+c!sKoFpHgUeo5a6<%pr_E=Fc!9%CyAj_4!0aNCf!bQa2Rz@-7vm!UMN4C zoYB?V>$#1?(-tXHqWQ)^AuAM#ljq>}Tu@p4y@C{*#UcSeC@K~l+H>goTZvLdsK$Ja zUp+@zgy&L`L<;TJ-39z-31+SH2&2n(4_Sd|oRIBjN7Gm>YFUBNl-2%88EsM`&E#}# zjmGUE-RuvI8odNC-76=xIa1pL)FiydVep4cE;lo5fMw@6UbD(B*KCs-ji>N?FsXWO z>+HWAEn=#(85#wq^wu?u|$fBGiqzjbXp>B6-sb zT{Y~xg+3M-k+vVPq}3Z9CnwC=?r{A%!VxfEAMSC*HJY$;?TxVq@zE$-oR^*BslZ@p z+nZ#hJB-s&Gr}|SDv&PjLkrH$1i!k&z_gqJ|EdJf6k0Ko&Y6*`V}D1ccpZwRvt4;lU9g%2Urxx zN5Uu_J>f^Hlc0NXiVM+fP%IFB2nB+VwjsDzowK3Ser0sH!t$;?K{iCG#u&vLzB#!P z`voDO%Q)=KObqF#v3{!6{KYwY>#`Q{0$HU}5TV-2=W@YFhAyKvfRUtE%;|S7?kuXq zZ+3U^a(Lf){)f5|?0w4p4n!gb$Vq#w&(&g7TdtF5j+2#QvG_BwEi(8ARdTvWl|mfv z-YU?6MnG%7f>+_J5hHDP64~UBezM{%I2@uWfEV?0o?}3_c0V`eDyF<%UasDxbuwR4 zu$WBOc~|OweXz93LXLE!L5DLtWv}0_#pFiNH7AtpSZmK;Sgm`R(C$U933pn*-S5VyFcel}E z?ckV}Zqzp*OksMQj^|+ul}dSJIcuoQN@Y<0*$a;auTyC&)@F}XY#LBQkk{oyx=In;mm0+>7SgXd0^ z<~a}WaY~M-)f5BYY&iWf3Yxt5$+j8~EjbT#x#guzB+b2`cp9)<3?!)=zh%y-zt+MB z7-`)<9(I4ouvz}W_@PX5O1DQ=B7%d21Ck~4zMmtUDQBZ#MH#cmfAzjIBx{_fOkilG zq!cy{LD&9733jjp0FaQ>+8=*)x!NH+c-8GA)JTf0MaVq$L<%>*ucFRgQuMLJb z!1M(HwFOhOWa1uL3O}v#(bxIV-^L(BN^B~}2j_~+b5QyUwxEw&Wx^luwmX>YVvsk) z>ODe+b0EWQgz{mTnCRi3OJ5;BmKYwpTx=Z@36+2XHEgfQ%eVY|VGvTE`CA?B->XZv zjanklJd+rY#z(hG3RKK1@O&02K|rQX7!?xXQE}RIQes98jBGNy3QCc`V0&K)kb#Oc zBOvm$)%@Ag<>3&FM%1TcL`s%OaG zpl!eJ+H8N+@Zew$8%sQeTtd=^^>sOW;O02r!B(`7aTalxzQU@FP)l4T0j{GcMZsT2 zOnjv%kUC+Cv@(H|Sx+OT-aUxGvGHeT*4DDhZZB7s0tEt@QI&LjVRb#O^OA{NkuM9~ zQ3eCmK?oWV1R!3oO!@ zc7%&dsDla&s;XW@+})XvKX%&W3T(meTkemII`WOGxaF8ST{Dl{GSXdt#>Bh_`h@>R zBcT2+(CTqTD$vck0=sh!&=kYc`hz)@EW}l%H(qr1F_s%Vetj>O`KNW#Js_yuiZ*!9 z_NN~d&N$IgZCzwEsaciqz@*Y2lHfa2UB5}Hx?W;Kt2;VR$h^Fl>ZUkpo7U}VMrAY- zKWacgY?PZ7hldflRe#W+7y5TRPMXc)n8Y$$`3g;Df`;u;yA+NgUs<>n+!TVtqi+#e zsl_y!%*kOf`xcxrvxw#e-p34*Lsa`ISu<|TrQ@K35I=oUoH+2W=AE6Z!=MT|BgX) z4u%@-cK;?YY3>qu$b^$P3EGKEZ9l7>!_Vd;kGNq)C)5pv0Zgm|c0;sHReaMlCz*2) zzq(>~SW^8mc>1ZVgI4yIA=v{1Pa8bip4ZDjf)1a6DK}Sl=c7X}u&`e*fhyleFSr5T zn!Ecniw{ckgJN~&gaKnN$&V0ht^gSH@fwlsv>&{M8U+vdA@Y0k^w%NQ5SDLkkKe?< z2`q@*F+qH-w1?fMntqL&t_Y|{2do5e^`DfX02hDRc;N@;F2LQh-V7}{y6aPArxc(a zntu#XsqiGE<~x?@AOQ97`B98Q)6`U%J0f>=;&1Y~P?NksO6@QB8Sw-@1pg4jA9$6#bH%e$bqI*rHWzR2@(_MOZl!E@YCA;IyY6W z5v8#%AT7PsXF&dFz${gPmrcijyQ4;A(Mof*ID3>rgj(7C*qU5p;MeJ9A2$d56&M(| zfzhz%+|)&Y!8wZ&(+#}elN#hf&mA?n2#GH0*o%L*`@5l)%}m4i5+8x3W?BA=`mVx9 zTAFhFbTENxC(S}wP!AkrPD$~pRB)YpI6gSu)}}+CyNjK?1Tc?A{Si8C-YUY^1G%e|T@+>Nn846v^K=!E>dig15eac9-J1 zVVcZ7_hb44qrElH6J-YAdtT^$iIQFP=;`=U-bVHJ(B$!mV0A|{arc|Wvm@FAM)JF_OuAjTlyVOmju6cyjCxHsxIN2H z(FcCywPtulc^UCpw2$MjtM*OZ-FgK6brFGWe_r;@wd_cZ^FFRp!q z5#n?$GMyhM@@(hzq^nlneLMcTEdUuE_T%;REe$)ND!1Iyl0hp=w>*~|D(tdzt=sQ2 ze#tNL7Nb)9D6BOnWSzW@gZ`lPl!Yl&q$x_8TOuE_!Z#!YKUl97=_tO@c^?+KDZ5s;;u@=m~No=O4*4{2w3cV`8 z+*C4H-mYw(hVzdKLdD4rc)W^Z}5~r{}Lg$P*U>QQ0{8=W9}F z7|l}YYBtGW{W9wGq;SS6u`B-?gX%zA*P0A2vb^#_(*x(wOWV;mAZLO7@M)Xi)qOKn8n9b_{?}+iYR$=v$NM7SLGU$+^;+*eUB|i z+KIp_Yz;1TO#3h@{47>B>^HrAxLW4a|4+udwZD{J#N+6qUW9Er!=jZLe6~a>h8Eme zjRX}^RBuWQfl7VV=JO%MDgO=c#VSA#@ez4Cj?{nu*linV>r>SC6TU&>AlVmw@fc}) zyXT$#c4+HVPGM{)27ahXLnrLfBBxqTa%fi_vX1qTGG{LjDjYltjg{MusUi|>DiZUL zWeV>e5!{YPQgkq71M3wnL!SS7PWtrpYuj4f0ZgI=7tU;o7JXg;Q2`$9W^5+VRgD%( z?e%JCrCZgRr`R`#%=IehwHCr4Uo^p(hJ;4%_z0ygny?s$wwa}vv;F*age;XTb|>Vs z&zkD$z8)3{n(*m6HIjo`1BQt_u~KI@is#l-=kfl1N-p-8lq@Y2=uhpQz+QUDLwi(S zD)G>v@Tq7w-rXDfA+}|g=UDbxD3FurXZ3?7hY&{RNi-MK#VRXJE#(VK^?PZhF0Ijz z#}gOsdkSSo169mzx&W0NoKe0P`r*8nR2F>ivR~JNS z$>%#7GA@?Dzb$=#@>S8Hd{mVUJWrj+Z%cb->8`Qfl$WXcZ{qeAn zkNFl@iZ4^o3?5UXG90qIt`JwGi2w&m@CB-B=cS=5V0AQp zlA`S?tv2D#XS4n&ppnstTPyQLjDlLKb}M-0~aWZKFh4A;ys`rNb-M)0?GqW z-U}BskuGf2Fi_+WTa^j>uFVk3&|al;Glm&m>g8b?4&DQl=(n~P$nIlm^W1fS7m6N5 zVYD(!Kq#lpjPL5z81MN*NwcK}&=lI0_EHV*koNoQZI3_=^KVyvO%BX1n?N?(!zR~j zjhDl0bf55@>rV@m1|Z!<0kd4Zj8~qy)><8cz9vyAmCs^hstvVLJew_+C(O^^ zby0I@V!Lm&@hs!SM{RdCtQ<@FL(A0+YLrv5u?48&Bf5{d_WPW{eocSX(G?3@V{h1t z3hqTsJofwXsu*=}u|oX-JKpUo8oz*{Jlm@4-W6Ffs&^9Z zFYO~G2y!B4^i27DS!Si%GurUN8;i3}9lS2_^g0++?vpGx5kT4UTYsrix`c}0tCAOs z^_g&3PyhaRsIq!~SXo47Mw~r`aGLc?iXrYdTt|RAT@EkwX&FdHz&)Si1!kYB5012}fta778B}?MDpcI*<6w;S+1#0mXB+=2f_uXdhq7Cc2={g^0De z`m?wD!r_rFZRN9Ax2{aOJsr(4YrK8|xb{t)HZkYQWuV_{cs zvPe2vC^LOSASFd=|M!d?e02)98*WdAVwv7P>V6X&Bv> zeKvJh*9zOdw^vqHrAVejr&WtniLQj(vvwO5cpOHNnFje@c_f9hCW*xoUpy>A^OJI& znjY^{sZuSB;!S^^neSjU`Q;LeGU~g#)65n%I*i+S#N#(M5>4fn3ZD;~^9JS8wU7kz zBJh7HGJ24fFIOzgM2!5c_AVMPcOU$&_irlPpJzXtCqh2sszU7RA8nx>L& zw*4M=n_5&RLC4mQ@y8m!=38e7*d&+{S%-_B@{<)Cc2A%Niam84l%Y3wN7vEXzrG!0 z?6D`td+j9ePPxwTGsE5w_xBlRcm#Ujyy_bp?1t)T_22+`!B-q%yR`Ij%eZ3HHTDXyrdJE;*zP`7v%BTm?@=uaoD zy_NPx$O#)J%3O{`lb3W6JyHFT57fu^?Nej8Z^C&XTZEfIwV~S5vFJgwMAaY*WF zx|fxiSVoQ)^z(m=T5~EP1ldtNN#jf(;my0fexxT^X{ZrNrE*FZUCR?hRLN>4QforQ zIFw7ZR4L3L&r>RqM-4>pD!9W2NKgC#G@2%jz|v`WWg@VKi(A@qM(<>jj?-*&8UtVy z7LtrpW`k%nJZ^u5EO&MubmYqmV=@`0w?Dja)EZ8(cc|v#D^_AipRR;43}jf$*A8IL zcD{RU_c_44MF)zeF{$h26iD9CxH|>*X;aT}sXfWFS^HYCxlc`WbdmN;z*+K~ZGsZr zq?{aPyFWA9j!i86O9n zXQU<|ko+~btB0#k{nDL$Vn*tycZtH!s^es_f<#$kQMB`ziC4?{7%(r|*KUF5#M|fR z_N;D{y~_z=aOIAvPg%gM?9D#jyEyc24T0*J|U(*bm#|)waJ2 z6zpKEQZ(9ddq-b4C1}6;Oea@68`x*+)4nKFC^tp2Bu)i66&WCzGiHyms z<EQ`_Qqr8)?uLIbQ z--Q&2i6w4G@^?8*c6-Z>7^?;L<|wPj-fCsDQ2w-J#^u`}nzAZ?YCcdHKJszh6vU-B z3|HTR{YU^qTe$jpzT$Ky#^3-Nthv5T7%4=f2hzl0BIvB?gTK(9LHEpAqc<-r7*Fq5 zG;MVdt8$S&VNB|>zdk3Y0`sia-??LV@?QpJzi^j}8|fofgy}G-VI?+zUT{igzUrp9 zvs?JNe|NzZDnMW+l=5^o;5wdf#wje(aYc?j@wE79BF7--sZy=kY^|tB4YvS0_w>nO z8elFmK3)EV1Qx@F<8Yf%*jrR{Pf+S1M%fP|!AJDtH}CD&}d4d|182c-OxyzT-kRv1~tV$Tbp z!1`@rTiX8hAtM#-_Diq4Q{vDUFP!~49BTNVY}EAEi)mHaI9YrIxVbEX^>8^PqhWNM zdAl^P(g>rEySJJ;Hi)D=@86|_BCyI>*jYC0Gt{CdliA3~;3Zj?#k8S+u!>X?E>D?jVW2EzL|_QtL)^bQOR;YX-UWCVl>IOG*kfceiSf-TN-``g@SlhMfb(wK;+NkZd-(=cQZ?z;e)?2U1!{$FQ zhUfa5TO}rtU}DGgddy6*#n#}Ui;jm5mqROhZ`Rwx@7fmfV#-8)|CN50!&;~7jngtW zJSa=6(MI*D#qHpr()Q!o=(MkJ-DJ7(UpEp1_-ihT5ayHmunmw`+|AeZ%N7WzVHPQ^ zBU}q@QbURBM|Kc?;tI&RYRz&C>Myzrn7D|!29#2MQ210JXz+sfZQa+`p56HkG&Drd zZTK?2?j1o_d>Eh80l-6aICkpf?jZI<2xv%PJKv>VY1h7esdHVPLf%Fq_`wd+6sKi0 ziiej6-Q&o4-)#1?HL86~(;M*91# zTzX`yyO(bnql|kcKbFz6UGjBPy>Q$c*mD$^dZCN3N%9RxS~W{v?%E;Bja0WRtYHx% z8D;4Wwh0nwp&N5JPq3Lu71&5}-}Z;?(v8QyGgTXRr)rvvHrfA*RuF!6NOg5Y&!;au zlQm3&ytR?=n}Lfd#s;0!ce4bFLYYsg{5mRVbAsY;%5yfW;gdNxo0q%IgO(W6K9hY< zG*F44!rI!6ji%-)SDkk?)Xh#(ls|%|5@_q{mcm$|o1i8KuBxWq#+w)tGE!@IL^}~= zGwj8aS#Gt_ipzg$8A63gRc~pa%Bq=humeO7%dbN^iUDhrNTd#d=CHdfS-+@|r9JF_ zeAx#JGsZ_HnpmYbaDxO4t*`{Ciq-+l%k`r#=w!1aL`^Hyo1z#LJxmYp8J4|8tRpP% zVEAy*E`55KvzGoKRQ`yV0X61h6@$F0NX=4hn89-or%Y zIFU+OXpf@|ldj7is#oJ0b;~YaxGd?I>2UZx1K$sRc4&VPyAmSJV^s)+isI=7Vlg8z z%YGudngbX*G$H=0PJC$XY*qQ*gxxR`to)0r){7PmGz)m8Hoa!yRJX0oRj0=*?VH8Y zhkTA6ILrlcLsc90>V7=Rx(FT^a+T!$uXge|YU`kZiljucc&inVN5nR#9@8KEn%@Kj zd*K;6IcT|@Iyz8qfn!IofFC6@&|FLiNy9SW|kvDfeyEfWyI+T0&7h4&p@VO~&@ZGxLxV z;JhJ$j-+F?$Bkw?o*u`ol)f>Y=!z5kEBw+yOd+uBBP_bl8kxCVC*7TjF}3kmK{ za18`^cMon03GVI=A-KEUwf8>q?(?1cs&3sM_s?5J71h;EcQbp=F~@kuGoJC{PrBQO z+csFqdi(qNT$SBn8*t#h^>F#>RXxO^H$dW1A87z@YMQ@So+Zf2EJU_o;8wnF?LEIE zzS=7>0_LGqtYrHwqoTX9?*)vAo++p~bb24) z5tqNsdAP2ElQ(Y^_J>+!fnF$CHap9Eg0SPo#I!j{q2{#k>Gv$=Fc_Cai>F;n{hPicVER7kHZ__6>$y#sz{V+uD|oR6~#bB7d~Ez zN-D(Ma!${o^j!Ux(~jZ2)+m>~SFTcs#mFLm~z{G8L!g8Pa0iSoiN#3i5QK?aB<+_UH(MXJ5mo;4CC|RmgXo6-pj~Gkt zc-Yr$!!rL>qqj-`5O&bNHR$P)Bw8q!94HB-%ZhMD^Sg6_H=s>p-~F7JP8a)KwJ&0? z0GtC&wIhV9CCWtpSAco03ssy@ zGEDlhB<>?>)HVa$FC1dd==>u8D;Ehj9u?nxB3t1op7^~!|Lp8k`W@Btpy#jgDD(X9t{dOl3{JI9UmoU;EcYyQ zMw#4n9`?Fl4DcTg1|1z^L9l2w_xn)77cy=JEnJsfVCbWhoH4iP+>0_;|w5Bq++l|4Ts(p7V`OmG_( z*>(SwW{vU(VQroz;i8G!3xv@v2UzvtgMR_udt`{=!fHr;3KE`Hii-RiDUNV8BU_ts zkisd!@R0`ZM@a^zI5&KT&Umh&mUK=;WxeGOr5YI8Bz7g3PYPp`p}%XDw_26#a6T_e ze(WKG_%OT}I+*=oXqq)LV%zuqG98xCB~VZv)QJ)`aM5~Z0`%bVcIe(lY zV!jN@L?dIq<50{x;})2xZMx(eTv|lIiuw+$ zIB{$BM>?5D9U-N}6RUxvQh<^b&waPu-Q)N1A>Z#^)hCk_jfsFl#4;LXQ(bkW42a?# z?h?a~1lzImh(x3_#q`i?vP6-EHBycL$V`L7rJOFrg04{duMxU<3w&Duo#b)n?KWgU zFPd&sYscF-|427maCNq(PN|9-YQMAJ=?1*R_(RQp6niUmMBtegl6S?tFC#16=Mo)D z)IqL@2n2P%c0j!w&GbYWP5d-9G;}MG_o;;mWUbLqko$0>Y1_rBi1)ZZp+5#fRSR^b z)&Fv9Z{-Dv^TSJX2+B(S7 znAN~z`i+g6{N-7SOi^|@n25q)qwvlbKqV5d3N`6toXHEqAQw&#&<0ni-K)8{AQUO8 zKVKD$^tL=i8p`E4n7b72a19X2Xw|S2m>AfT;ot;gQ!S7h>3c-I3eh!xHZj&FjOB3* zz8i;Co|&p1%$B0l3yMIW9Z8JprvTzFhhbu6v>`y;@O@CVOwpwpGf zA4@S{hq6mF{$D5<4JG8`Q9+jyMgTIiBf0EjnsWe!B*L>2j#&;y-xB51H!h#RP*YFP zkK+PZGF;bT|9jD+@pdR!45ZW+*y{Feoa@eKMu2t}#@?@JUM;Rx%Dk}QODQ8!-QTua zJRC}OxA41+VQQ0mKduF!04vjzq3q;obs)*^YDKk*kOa zxGJg#S}a*6@}&tO4O_a6@WQ;8>%W9^p(XrIq3x(@Il;4`DK7ZUdyGC;=7~IEWpZl* zPRG$n=HS7R7m;MBeEO2e`6qtxr$Y!{XxNBK&08Fvc9>K;I^hx_u;K{Y!@vBprNMoW ze6*D4+;S!{@$uul?u3_%CR3o~dNAZ0K6}it-i&;lgYzBn!OGLbH!jr&0Adns?q$;*6K(~@&kE{HHUQ7qvZeRezflvI##4Kw$r(P-hAde4Q`NrzBcRaL6kHm-wV6(yw(Zw+~?JUuzfm}u>EmaXzFc?Qp{9A^-neccwPTti6#+5H2v`a1sd7m7++t3VG$9-+~KPflAV}u{Q)l+ zBs1huFmO1b(!mF__wpliMmA^pi8Qaj(flds`&e<&{2aX$j`>?=hLd`9a3oleBIpCR zAed}g41+a}H_&Tou_HAd_=#*KM`V!1aFD)3JYrOYu39TK;Bf_;$E0H?H8QXfOgn>}mrit@!73$yiTydUQ!V8uA9E%rPY zx6>Wm4K7RqTJN!+YK~x?@w@65`yQl4h0SP&+wqf;n`$Qmwq?1qfi+z%S z7cetU=e}LT93g3(j57?_#{YdA_>y)oc@q4?-@N5R!?QiFKRj|2sZtMkBa9qGX_z)k z^0EViwAz)GgOb|( ziACEQTcW^7Gcxuc0||h+Z1uRii)iViqH|R?&l!~53Y!lYe^kZw30#!K3=B+sC(x|& z6pqvatNu$)IeDgD@Tljw^lb@t*k5FzRf#Wmj=qVmT`Cy9JVn+ovr$QXtC3_SDv%pi z>6RGWOE|o=&ekGNr~Fh#_N$$mohZk0f#a~N!@X5bAqA6muehLLr}tnNY*jrfuzT3w zwK&^YCz+kJkxf#ok)bJni`oAR0&Rw)EbkNJ-PQZdeO4AlB|(9XOcUCtcTdg8&p%)H z5YN{gl7a((A=}2#Ao%Ce_K3QivP3>a!^NT&Xt!EWj@+N{s3KxUGiFFORE^2MJ()j2 z)9>LBc0cJxn>SDA)`ad(V{n7r^o@{(P`*-$FkOg|3#iDW217_;svL#kYNU6fLDMOj zYaVZuu)tzj=u3@=CPk_aYokY)0h+Xal^`HEx^HBk?648%>0Rt)>;yPwbT4w+&~g_D_2Z)3)&d)QS4dBMbf%l{VXBY}-6 z^OruZ*ziC?2pd&@)IbO?Rs;%$#yhG)SrnK#46PWI;{rU-u=zp^0ZzY+5hvL`DRbn) zk5D=O1Q;rM!Rj=NswIV!X|80dGtq-MULNly)n02iT5Ru9y}X%mJy#7B1Ol);M#+po zv<9nfNwu~jTRUQ^Ty387j{Xl z1KOKeP<>VKLviBh>{Uf_6a6xJJ_(o6H*f3X)`)rQ6rac_Bs*)hs9c&5GXlsU>w_&I zJs0CYK+W9DOeMR%r^@pa?F=21VNgNJX)^|kswmbWRRE0gDa4Gm4{ro-d0Qc+Cx*r3 zuxIX%%gLQ@L;|ooH4o7IZ9&$GSdZJHboj&px9C6fv{HFzUU*-!15{t{#H1}i4xQkd zS?wD4Li5IV)AfG2*)(DhpY3~Cg-HXEp?u*jPY!KO$r%xPm{|>P*+?b=UFu=q$iF>3 zj@dTOU?x@k#;ErkCtmQgGNxvODn^5Rr>>aU*qHWDQpBG)eTD=KZP{ec6t|MSLtf-c zcErJ6R^oRWvIiah7M|DF@m5Ed>z@fI*c93Z5hZ}mW)pr%`PUsk8XN~%K}k6zbXaW* z8nrk&NoF|i%rtW|UmIwWe1BOsDge&6ah-2s__&MP6l(RdH!vF}t+73LYk2knM339M z5tsFYV{1ier5ykS$VNGKM!BZr#r!;PJ!de7)5um>M<6*WTq$yvojRYI`Mruy{`=!k zAtj^*s;9t2*#HhkS}j^*DHCM|q~hz?RzhUmscbt05-8Se9&AcF{S-=wrt#L5cVm(ppgq?ZUkcr+5FDNdaE8We!RyRH00a|;ixVxQl!DD^RW z^jD{zqPVc~Uva8MX|sd}l4T@rKOiJ2@9nYkd73qW)*5h-pJ8}Ro%BqVJVTSneW*hpJMjcE(%>r-}R-SNwPi) zo2Rp~=;Td5#$`Whl zH!zXn5@>+tI&jE}!J;U|g+Pi|s40@v8fkMwQ$l4xF*ZZ6T!Vc7E7+I0&r()G?RoXV z80-qk*a@=GDx( z`#nem8a2mqs{_JG*)QK*a%zsMFrB$YjFSSg5BQTrpBUE14wW6A`B^NTguWT`KQfmM zbc#SGqQ_X~PQXi{tQw*$a4+0GV5j*E=<`+hT;-cRMRy5P8pRgA;tTVy{M`;bGr-V> zBy^EN+huw562s)0ldjXzUShn_j$dS|rUP%JL2=B@gkPFYs?UaM77J)G5aZ%qa!a}< zT2=UNXIdkl@Jje6K~%-|UKB^h{PBS`S}qiczd{7!I+DUiQ)yC3{7WQ7liz5wPI^fx z%W@*zuq82KSL7$cO;WY9_#t$p9X(l&q(#TXwlIxACZL?7V1QQCd(%h3;_DgNgl*bB zRbLCRktpYfh)66np}cugLrN+Rz@VY~Qu{)ece|C?~% z;&va|PwcxG8mc0)38QfTH_h7*NafC&UB}uua0|)WLPfx>pYIR?T-buuZ>bHMnrRJL zain)RbKP&DaW<@DZ!xugz{3%Nv#-pYJ6@WS6Ny1IrCv$Z?QpzzSf>J9g63LoOfF9+ zYv6F_84-Y}jJx9ImEcZWm^#M_T?xoH^GP@EFXn6*yM3I_q zLgUk7SPKcfqW7l3j#r`mLEwRkXyHIMF#<|NvyQGlT z%1A40T8#2OH?m3n$iXEC+Oig9N-}<>Lp5ehs_es03S#oHkzv!m-Di|9WsW*RAV24` zuCB8(ogZR)>I{zcY_QCa>*juWk_@B?JR>TdPE+)cx-Ol{bnU8Ih1D85lI2DO_Da9g z$Ow{3PM^kktdygz{h!u9C?*Bmm@d}`nfcPy%%V!YsFg6RR>wHwR8rYk}WFQ zFU?w`y};^%E&b*q0{DAzqC(T0$z=Jo#8zrEX^3JVAk$ZUjSiF^nf`M#_$!X@s>Rww zWrs!EAT%@-O*}a7PjzT_*{g+yLbMB`n=Iv|fsu-Ete1}tO4P^sQbIRx&-Y>GE=XO` z!~yE0HtB353>PjpR5iO4_NYg#g#U;XDN<0;Jt&w)4-+omeihCC2B%VUNU2!P;>XZ@ zyi-|MbIZ~%qU#5Hgo{DEw>N;h5EHt`H!`GN-~f;nRBj7{jAgP@Z(o!-buo zwNZ60q-MDLAOt(1rqy@4o}MS9OV>EP%|XZc$w(6|85&66Sa-($Myr)tmpxUN@bFm_ zWo?9qR(QsQzt-%SVKmm*LM&dQ=Q5Fkm0il`7O1mo#;fmVn*AxzXy8m1OJYT7HZG8T zWe{vPHX9!O75(zey?994Yls6KqV7F1i%Mj@RD}|{znoOJS2e?19cy}@=ksO`p6d=M~4 zyHFz&U7ENbn}}IY7d#IQI*IU8k`z}d(I0Jq0$;oy9*8c4NcMQHEY9mLg0xQ^pE_VH zfsyqcC9RP+ySy3mnTVKCTN{=v%kAcxq9aO5EDAsAO0HiO_|Se>Lpz##G@mr%78i1N zhE}v4SqN0w`Zq7{*NoM#`fj*sk}OooYYJPC+M6_3s}}X%ezrFe?(?<-xpm29v$fY9 z79W3imru3ocDEgTdOAr*f49#C_ECq~K4qjCD()L2!%B4dG%bE9G(H&ZJ9u@D{%8Q` z7Q9$JinQ5g)VrIhMIeWD+sFZtTB<)neCB6o6{>!C&a}tHzqQ+V9d!Q_BYT2@TJ3v2 z%l0%GH+pd08Ct6PDK7xUp?vdGsY#C&DNbIX+w|?~?kub!>8~&ny!h-LF*i}|*;daT z4~vo8d5fgQV5#mFCHlysv`Z?_Lv(z&w|~Cy2;=oI+D+3nPbQ7)!UQMD>xmL+#GY2I znD6eN!8;}<-wZSCuAfPc@PCQ9{H7_^`E-5lJ#Ewu;_;nj-*n!%bzQn7x+~Up4{z?3 zd=zxkeN9g^_Uj%bmE3HaFg>+BD)RMfR}|J*{knn;!CIruOA*>?EF*IM`U+q|KbB*4T70YUS`c<0^LT(%6a$8jmYf_&>08j;(xMOWE z7}6NP$A4%+Dl)|VLALU9`tluATsQTm!*&fRfiPVXcJII5=zmz(KVgM>C=Ba{8h9| zLjBDWo+0@EdYNPp7~PaC$gN2En=kvH2lw#cu;L}3xB~E>XZ}Gq`0F76OsMx|IB_9$ zCVz`Q{&o%cV3QO^UhO8Z6$!x6y$+lcu4VX!LC{qMm2IpzK= z%KP7e`_FmxzccPX*X{pbOBLZf)&uwR9V zz-Dk=-N(5N2ip}cW4Vn#Od^=ai*;Kx-2D~)r9w@E=zn-L|NiVGkjqf8uyE4y&M6xd zY|3+X>HSEb|F9yoL{Rl=sHlkX{{C3O-vbK&%=7(+?UdT&L7e2_q;$$A;@RBj7kOVs zVgbDZ{NoJ+^5k%LOGu^A*oo%rA zJ=e;!v$GfAB}0y&g`$PSz{1Mf*i@*MD3O$FYY3hf^XvI(^0p(RD1L$@*Dp`m1@clx9E zraqD;+@6d(h90klcF|<}zVGn7O~PSH8=55Fkac%&o|wveaX6Z{1=9qpTZ(Qr(5d$MJl)D^Xe2?QA|oeGD!m4am@zTS$PBRqrvWV|w{3gHY^E;+ zk0AAC=qL0+Fc~UH14N_S{1y;e=#qYWIr?KF+eZDzhBA$PkfAe%0oOpRT3Z~nHnq-oY zm5ng_{29l7I4J|X*FIp{FT5Ma*(7aZ`mc}V!A1b29=vr%V`5^G7s@7$E~!`9XnVXq zc-DE0;5^)}bpOFZxFH6YuBtD!IML|ARV040ggTcQlE5-d-165!?4PGZuns)8@mtbPwBoQ(5IAukuoy(uYI ztCgyJEEtg%ND8{j&(A9`0GA%_pU5my`jL$h^Sen)+t;X7Xel3VyBi608oQmXGmRuy z&w2)jhRTfTa266AKDdc1DSczDe7M3b!_%(P(=Igxbr~w|Xmw64uqcqTk&l`!Rb9EW&&qZSI00J@<&8`$b0YM9PV4@C{JX9I=sK*ETH_rl z8AZ8dl|nh$H9nVu0>u@(^>%G8yLAd65Qv3`M;jg<&hB-qSKx+lQ|cBJ`SmM2dftl$ zSqEx-Vk+!B_9V_tkj8`uY-@^OaPI(3ao z117|_cT{|QI!|JW^oc(CmZUm$&ZPxZ#a6uZnpIR_qWOZeTrx9tBE5QopclAdR-db} z?i1X+`A~dee1zx6{Ay31VHhSusoR!w1SJ6`<@OXJ9(QSw7ad*cVN&o9cnZq)&SBHe zFFHuo97%Qm&Cv^ZrMhNJ-RAU?tBdd%Z-d{L}^-gcJNw)^!9>B#%A zDuAe6+s)^L^%tK8tC#y7#X`4iU$Lp!`IvwJQH-B?yWqOQB(N-!3RoJbQtX$$+XlL^ zYr4RBm(S(!2+Obf#WN5Kn6ld;GrhU+!}jRIUfbE@9%EXA^#XGXSlZBx_vcURsuo$H zlPUd?CD2SL{MI)X1@rw zC=2LW#pAJ*rap=nECwQOWaR(M2drzqp7t}JE1T0vGD2wGy_=4l7y^r3m0QFTKSj3R zPczVK+#bxxjSKD{Q>y4UpS!i(wx+8moIH1RT-Kq-Qc{?Fg#uPrcg9T!9nr0j+gO;H z%R+eXs08KiT_8^gBa_#vj03OsS-x?vdw+zTo}E>5(H1do_kM8fX+Q0JQixt@+JFE* z@QyRHriN9!**;Fs^zb(# z*(j3Z_mH@-yPrL<|Ff9-x)uZ{dScTjXpTrE#U*7J`aUE^*cjeCiUk|>53$&bR-+Pf z$?lKGmXI#Dx>zGekb&#GmCI+^&JGyCSLu!O7I(ZVU$51g!Y{_WelOtzmw?GgOZ$`I zG2`lc8~bV>zP@!nhA1_E&hdBGdEuk)uj=nHg@#9)XTLdH&^0kNo%OtZB>WPv*sfYB zt=nJ)c{Izznq7X8b@UjY;7@%<+_XWD&7k(}*Vx45BMnWl<%@NJJKu@cxRGiZG zWev{bYRoP805>#| zlsZ{&*L9^0lU5B15<{)2+w)~^VME>e44FS8@@$LAJx3L3BOL3|-*S2vcuot?gFWIb! zkonyuLvP*E{GT3SOt47YW$7@|lpSd$!$)yT0?tDkd^VE;@5K|!7RbD% zcxpe9^N8gAtfM@QFf@n>nQo2)X)U~IS?A^1@Wa@KHSM>!IO(0XGq@uY&6DK@$yVXP zoU_M~lx(TN6AWa_PrNRNb~P9;dQ37Cf_FC9=-~1`*eRFH5vWf6Vjw|#z*;cy25_vG zBIp&PL#9$=n`O(p1z0?LXeZok0dW`uUK>W%QfCQs2D zG3z$!J&~_02OIbLCKwCHOgiyxW@JmD-#t#HY&ovoXj*UJp~uzJ@HBT_Es=QL9w(yV z>iKsHsC^#GcrPe)5c8<^{m1K!R0J*qv(v9pRb2Q}0i=GtsOYl_(~%^mHF7U*s9-7o zz^!>({@qe$aBr+Au#OLdroKn%Y`HG-LWP#VWLOaR<2h~!Hpw-iug}9%#0p(7KAviv zyuH;MJ$Ihl^_4YT&P;qa8;mtI>#u+XcMlFcx(2{_~5 zWP+V%^Fegsp`$Zz#xs{EDD(`0k&XOJH^zY!F8wtWB0d%0R91Dxtxi)!0R6+h9eK6m zrwjpoI23|h5aNK2uwQv{;=tb>OmJxOvFq(L57(X-SuhB@rn3ukl1ZK6nI>1 zvV3=z@|l=gQQ)*ISDi0$PWMZpl@qNa!*L!oLTG!zsWBbrKFOj2-l$77vZ zrHUkz25{_g8+k%@W+tt~o%8ePM9O;Rd)wuD4Y^*Jd$E_7JIS;@S1rdXy%v>;a;4mi z{%jtHI+Faofg@%TX zWV)@sU+5uFF@kQyxXGg(O`lQ7LWOZUlV9R*Cv|ycURH}GfxcQ9xw_iVx%SJ zrQwfFwkuLC)W=Kt@`C~MJ*QG>ds|#jh`K?sv9ZZ_8-BV3+*SoRE#t$jGkv%+ z2#lHs@a~UMsRY?9)(c=3-xb!_)A5g$mqHiE@$lPj1R@&9TPGdE*NqW75s6AB{VY!y zbmPETsKlA4r6wTT@WeBNZexA>^YjOm^3SLTw^J5%q#A4TJMPdEV?AFpAiw%1e987^ z+Ig>#sQm+1I@=DE{N^*Os!^pKd$bRFa?&6&*XwkQ_U3j5Jj+`UIr$u{Ni&N!N%nl@sXDogCSss0ZB8^M^Q&!WVp!YS;w zjn5pnnjNQ(=^zVaT&C~ZMk#RId;=RJNM#90G5_gm6e9%$rklD4hF$#X5PP_EB>1V| z+fSVR$hWusDZ}^e8JT5-M844XcQ?GF?9X&&q|k9t5r0>(KUlP>{D8x1k=3h~)J<)( znnM<>ijhB>-X>CUcFDb$iSOksqU{HT-Xm`kH0 z<7mamWK0Le&S5nx@)E34(vIdU!|&P-F|(N7%U2)5oU|&aY-jW(X^^^zs3=RV+tKnvL15836U3$?{;~`zg}zcX9LWdJ^F- zc+tSa{S2qZEH2i%HxGZ5#R}&G+%(qvwya zASvcki6c$8$Jo6dQ@yAN`H!(A<;*y=QgzIJ*zRa6ygWP-D@M;j;r4DKLlFA#@&{ZL zjEqDYRR>^!)c4p{OP}G#-1)p4`jH;VR<2%K@k$*|PNXAIw|AY9SuIXrSEdwr(au&Q-ytPwr#y0CTZ3no z-Fb~QVIIIgupTX9jFEHBy`|Zl(RFuT$!!?$6peKsv-y~=xXBigfiCC{T6G=p(SopV z;P4-beSvR3GY~4?YfFDnOlQ;d&14s^YI&vrt`xNtfq++B2M=Q+4@GB29;XNJ)F=z@ zUYXCyk@`4&=N!r+f;#sK@dh~X^@uu;?2v9RyiUfQ4p^~~20qHA?>o4DX=Mx@@|=S9AH|I#wdDKP5E^;ztxVGD`4Q^F$$~mJO1|;J4qGv4r_GDAi}}& zo~XbsT`sz3bM}6VXWP|-f>g{HSZP=Z5wvZQJ%@DQp2s&~-qy-zPC0vdnSwm-xVX2q zzIN@c$%30bpgj*N`>=8xyI0P-Vv_941JZXT#7Se=hIt#i6@@_4M< z5gO=Dt~Sjbzzn!?b+JEK{6|IbzeE3G<^T$svT3XzFJLv@P}25dZlm^tt!pWTf#MWi z^I^3cFKzTlflRMc-sQUHVwDT#CQfrK80jhk#qK)Mubv*afmU;6zoP+tq6#xbiKgWm zV{=yDO>pm==3Es*_pPqLQVzd&NUZu~vMZc1Yk)I2`W+pgj^=qi1a5zepWi%$j;0DK z_P?+j;KoEmg(cMO4I?l~pS3)pVXv#GsLs~KnH$1f-0Cof^gTA`a5rIKx_=mkt&PWg zv&^HnJKovecCMvP4)H4XQ$h0QcRNj3!?4637VrA9(%3Nnl^G&FK3;8f2TDOca^~US zJsId*d^|;cf=S%LD_J#I{4sn?U>sc9dcyM6c&pWB3CTrLWMqAG6y;tfS}m8n+WB(1 ziBQN8=rT-rj9bf!>$7NOjFEc08ZEFA+ey*TUc=51!#-E7$z4q~XOg(jrX;YGo)X6H zi5$%-LORHxR<5DG5-s#DGaV9_1>zL_5=js5s0R(VL>KwCwo;3%(!0g+@M|IzbMQX6 zJocAM*~teeSXuuLpXq{9_rY1wZIk>rs=U2Kd?sBwK%>=?e2DKGWmT;HdFB-(@>PUi zy$@h*zG{Wa`~qYD*cHs*uMoj*vg*@J)U|6@!C}#_3M_uNH($NMIAbx^>-Is0sYRF5 zj()COeH;_@LF99PMR1)>pOs$rt&E4({A;m`lU9-`Ij?t9vRLzz>5{AfZ8?4s zt(R_Rp_n^`I&;H^%tjZa3qtE|=G$&AgYf9VM$8(<r)c}LE4Xqr)#s<|0mg$yvnf1PPW#R+}Xsni4( z^1TyM1a^pD#6@bWR~vltaUB1OeFz5XTq4{~mN|_Pbwi7-joL+_pUM>%hH4%&_$@k* z{Zm@7E;K8&sCW8b@_bc!GgsGE)w@wy^a-Db#NH8Ufe^HqLwXM{tD)?UfewlMN?HXj zOjkRzF1XAc1>aHd1yJ^Ma-m2i1NZJn(>1|cPs~GbMxz+a`XGs%`#T|}4L?v@5*t0e zih^)uDMt{tef0g|;iK_l&DKDCRR6{BFKrQ*9uu8f`y+dV8)2fwSc%(ilX^B7+4;;s zdVW~gt9CIdsn&@vTHm{oQhmO@&_egv83aV?u#r+lUB~VQPw%-zoVK0!AkU&R1V4CS zXaEu0&hPq$+joNZ^UwCrT*)^iPQbM+gfRD+n{IA%hYjZ&E6;Wr2a<)bZ_S49cRj{< z=YP5%6mH7I+2Fu5ebCLQnooNEH5+R5aViEU~gQKqlW4W52FI@$JkU?q~b*#oVmz=ua8Y5EjCZSm#dt;Eu5x|GjHBBwu6WT!PTZ zLAH|#5JAqVxYc|~nd%`O>$>k1r=#b)h!_fO_wxnxFNk92Yr8EwGzz`Y_3D?4;%?i< z8u!^e1>#zJ4Iv9=I-^$~nAmX{AH_X=t}rOEK z#=E-{eu#c}YGU(c(8d*Jo7EWHL%oF`lPS}zAFsp#Q2Hr}uquewt5s)I#r|~7ujFUH zM7ibT(QYcAxgYxHc#fb3M_2(Ky%wv?h;?%EZmdxELZuM0=NMIlv*^a~=xCJy_nT!@ zzRI^#{;Fgt)WZ^l%8GOQDD*m7#u=m=^swgo5TRmyYjbY5Zmb7_JZl~a?T7<8@^5ck zPRzp|u#e-w_~5Gp$F0o@@fsAgggPxt+ktU?c4&c_Y4+Xr+scb{dl5J^0%lOIygVg6 z1rf#VM9Ny7=&7j3Jt45C?8yA~%inXz3ZI}t6MuZqd7UfQ{E98Fz0~NE{+K&UzxAFQ zgb`gDsJ9!=Ep^=iUT6^~fDv~msq7pSiws`^?`nU*fU00`O)m-_ifT%?G*Nj zzDg++Qp8AV9a*GRY>qMQXamZv;F(ps)(g*<9Vq2L1gLypIuju`(9}jI*E^ni4sSUd zQ1+tD#_rQDPuuKTW@3*radN>*_ubb+Cw`ZGEylfYnbV5oU_s`1-h(EqIkD}nB!8$& zmYOmq!`ybAI`46hQBi{jl+^yrYE&dnH!v5A1Q?b?{D)D2J0h7~?j)<;s2r)uBg| zgce%uL+_~m(wpq+sy4F5pWm3bzz?aH|ImyohO z^UURoX^2QOu!e(7apM(%_=qg?y&4>a_P*DbeolUZ$g@H*gku`vm`7M-=>GCO0m%Ud zzD%%eL%k;E1}1_*rm zv_W3yapc-^H%>T*#7)hqACgDH_(qAoTD96jhI_<@(nHcG^BD7)_v^*@r4pXmbZ20h zHG_dLnBCp&1>r0`Q!pu?j2KB)<9q30*TCFyynVGhpI#MzC-kfb`?+Y$+7gEZ1+{P6 z$k>?t^4j#y(igx53ZXuVrS#M2PJ1z1JkKsv>ASp~^l1W1tUHXo9*_8XesWn*5&D+j z?9~I5JiVENaG1p_E3Z~`lG`(J-V5qe= zrh<^kb|?m9jK1NQ9?@3c`m!4-G+ZUxu{=9m<&gTz4O82 za>&B$@j7+2FjB#R?{0(zl!Hup@!pl`IfXp~aU%_Y@{2_)tgja5NN6Lu8gxoo-G15n z{Cw3ctXumi_0wW~b{hUS8DqsRq5D_i>nBnUQf7bk2@3*n58T+k8a#{9MThBPMZZtQ zwkz|8BwgH@tJxkuz#4N5)z9Zs+!qTnA0@~mN0>oUX`FVHcA%H4h*lYl6lMLE%ZQOV zs3pX*>l@kZl56c0{u&#zU2E-89!dRDUP6AQ;1>TG zrVOff#uq`}#iW!XaX@3rS^5ls#iONAqN+q^Fss|6u=-&!!MmN22o|kB$IMqtG4d-9 zlC1E4;U~f5U4VNU@56PQZT%FWv~hH_PVg0{9Gsw1AMxzQ`QX;_fL1b?V{w%?|`mkXCN}%<94mI7&_@$TzDTM(K$?S0uMvCUS zWY3ky$x4mGkN$mU*N7&7Y<@n)ZlKeIih~!Y-iT67p`WeJfd-?YR5hj*eVXR`mfH)R zIjkrx=0*g4Bzp~!7;CI-u@?3?h6j~Z6iMB9rr=-wsE0j*Vr5jD0kd#K#rIx9czqHd zty+d6X25-4wD(kNn7_gsj44>}j-d=P8y3gxi!gTJgHpTeh#xAon?zRv=i8qyj7E#K zS~uL%W$cr>`I>!=w8!E3bAOd*h)YnlQWnWTih0AmLe&tIy zJ0Fnt0Jne#2cAwI9zM$csJOOvojMzZD;L>hKbQ;y&=(;%SU!wKHuLv ztu<)&#+d*{pU6H2W?Ls*_grs_j-Dpl&Fs@bAO0<2_RKvXX@OGRDZ=}|D+pp+J z9xZ}Id=TbOR$?Rysa%_rw}`2vc5LF+Xz?U`bS3E3{RqHDrY{MTW(l13f~N}*K|1Jo zp5RU={E~!9MHR3%#!cXQmqZ8hx;tLA8_$SqJMB~i=eS7uP@e%eNmF=E^g*5HJq(Ab z>9mv|(UJq8;ZvN@?$8Bn)_u;PcSQNj2C08-UB282&-Q)u<2dUVC^T6#(u*$qK2`DaFuu=IiAWqH3+R$m8|3>H^Xt3f-MA%aL&E(P2K*#tk(W9tQ0gM@~Y(vmRSqd(f&6sPt4&_`0gG7~G! zUi1rt2|^AfL4Obj6i@r-&<*zvPaJNwiQ2KtRVS7~d2B24D6#f0>lLX{Dls!fpB6%Y z6M6j39gt@n`b-~0QAFq7dxX6(mn9X|tPH!cL}0-x*^PdN?~M>m+%Sk{~YiAWbtuj^CVoSivd^l zfQi)zLPLv|{i9%T+%~6FrMjKB)L;rkgYKS;8(i6alxc;hslC(wX~(Zt+x0wT=|fIv zwIGSGNL7|qdMe?L0gN4jTl@=^O1@2Oj~w}4g^?aEgcs=;zWd+4ew00VpAhC)ZGKB$ zW_r?qDh)=%&X#2aGvO^qb$(_sx#}4?3B8d+Vv+ripOS1C8%5qzbO>}lcmE*n&1^rW z{;NzGj1txcKpp`}hF#l9(k1r6MNQDv`96Jj2Xiue($8_JkULtm#yXEagtpNI~N*26tKtmwDLOG>&kV4bp0Zdbf36 zsVvV!ZS4-vXmHad*6{G?snRuGsf1oNKlgsIXYoL?iy)*@a2~Y2La#+uDyn_%r(&=X zWG9d7p^WxLI=V6)}to+;8j|HN%CIt zaa{h+Pi$npZ2K4K;m~tGp&g;3E&>8Zt+Egfam!n0+X$}DVSZLW7`ayjC(Hd(d792* zpC&m_y%qRR)DD)e%*J*`kj5mR*V#;^tY6P8SC?EIZ#cOLruY<1Z}LzIrt&|Qiuigw zc+C3%!;$v*GuFvS>=aRX*~C{upGc7-Ze|u+<*Do|5K0cdUBPALuiwN1Z6?O1ODRoK zlJGZW=^@Eo$5(~rX}|jkJ=i~#9VZg`E{@&DkR>1q!1tu3ZFrC5qR#4!%?)zz{DTrFj*Z6gU}@Z4_|Kq6j%48591Qt z3GM`!V8Me2cXxsWcXxLQ?(S{_1os4&!QEkSclajz+uiS7`ES*&n#)wprBC1PbNX~Y z{hUc!%kYS5-aXRUH;hc&TC{bq%6TSbzjo`GI{IFX|KbQ_0iL2gCSqy`CE%kobX8>O zgdQ$bxH#3sN5Qq3KbuICc#LNz0?r{89X#&T+mo`x&JI6Fy*CA8G?paD+z+7@TY|I5`FAs^n07v`z2Z zQShS%eoUOVM68>-SXlFqts{bQ1Rja$cW)DXJKvK({6SYu=s^v$ zb9uW6isRhZ198`!h9rEC=;ITu*YMl=+U#T-{!iaJ3 zHATEfUwpqK}r{-q8~Bv#jSkH10WcF;N(|hX@9}=*qtr~w!gvRQ0tUyN^HFCW=vjQDEH9S_1U(=Qv+^vjlhHhzra|lFUiF_msKhN z9X5^4pQj>i#%3#PUGr0se ze@3k??GS+L9+K%Rze`HJxhRK(l?~NqFgK(1;0#VBr>~`#3hvdAu`<3Gf3LeViNIvV zJeGqhxddfz|3WX9j5&LjVh${BqV#I&cidvj^^WrLd)-?zn~j?0OZh?Is}LR^+|G!C zqbKwk0%4tjC>63`ZEjX=0X-(a!9A!iF+9Oa;o&vtRq{7{dsW19k;kn2PDH!&Ai>dU zy$!5us|JS99OlZY$MS|KmAsr>D)p%Px5-3>pCoGv9Ddip^BIYl1f;UR$d<7 z3Q$zS|F|~OVfZCf#j8foY2{hbMDGst`4xMgVbR(r`e>OE`SHmcw#gAyx*23r^<2x5 zNxTD2rpxcOp6tWQ-y9q+>D@W)JwA{y568U^@NbG_IZZrQFw`mr+(S7rPhR3UL8zrK=Fi0U@c zh9jDscMmgeCb!z1+nh6LHQR; zB7MFtpxQLEn4jU?g28o3BCLV}Ljb%AjE!0#*)xGs`c!7kpCoyg#vo6Xz;3 z--XiSFKdjxVvZLz?HV3gddsV2X1NFfEG_&H^~rBJ+JjxOG`Mj5L7*Ymja6u2 zyRq^W-JVUYGY(+#lqED)6)aD@ViA41cC~WT<{0T{G0!NEw@S}y+D1P)vfw$$cDHkK zu15^bva?UX=RLi>cQu>zaYhag3?2?V`aLCRph~Kv%2bQTt=>gK=>NO zj=-HAlU)TpVbE}{@9bc`eA1nbPO_7~X5?}7aqtByf&&Dk`!OK<>Ur#uKoZc-5fjIm zQ~POFAKt6eaI}7N?mn@!qOMayz&TuugxxB;h3tM#}#mSI;pb zk!tX22e@AHW2&dQ$D_4Ew5}r3B7~ppXS3}b$bLy}@qn>t*-eBa$il4%h8$mI8Em=1 z-kIEXW^Waa9k2MZPQ$s$WE}m^IDV4S=mtWhLcRRK#$T"U%`VAg~bc1j8oiqOBE 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%0D@xPf!Ob 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≤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%0A7$o@yg1jsMSK1hU{6eq3w?_i#3Atq&8pLzP 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 literal 0 HcmV?d00001 diff --git a/docs/user/introduction.asciidoc b/docs/user/introduction.asciidoc index 91f149d5cdb3c..9d580187edff4 100644 --- a/docs/user/introduction.asciidoc +++ b/docs/user/introduction.asciidoc @@ -26,30 +26,16 @@ image::images/intro-kibana.png[Kibana home page] [[get-data-into-kibana]] === Ingest data -{kib} is designed to use {es} as a data source. Think of {es} as the engine that stores +{kib} is designed to use {es} as a data source. Think of Elasticsearch as the engine that stores and processes the data, with {kib} sitting on top. -From the home page, {kib} provides these options for ingesting data: - -* Import data using the -https://www.elastic.co/blog/importing-csv-and-log-data-into-elasticsearch-with-file-data-visualizer[File Data visualizer]. -* Set up a data flow to Elasticsearch using our built-in tutorials. -If a tutorial doesn’t exist for your data, go to the -{beats-ref}/beats-reference.html[Beats overview] to learn about other data shippers -in the {beats} family. -* <> and take {kib} for a test drive without loading data yourself. -* Index your data into Elasticsearch with {ref}/getting-started-index.html[REST APIs] - or https://www.elastic.co/guide/en/elasticsearch/client/index.html[client libraries]. -+ -[role="screenshot"] -image::images/intro-data-tutorial.png[Ways to get data in from the home page] - +To start working with your data in Kibana, use one of the many ingest options, +available from the home page. You can collect data from an app or service or upload a file that contains your data. +If you're not ready to use your own data, you can add a sample data set +to give {kib} a test drive. -{kib} uses an -<> to tell it which {es} indices to explore. -If you add upload a file, run a built-in tutorial, or add sample data, you get an index pattern for free, -and are good to start exploring. If you load your own data, you can create -an index pattern in <>. +[role="screenshot"] +image::setup/images/add-data-home.png[Built-in options for adding data to Kibana: Add data, Add Elastic Agent, Upload a file] [float] [[explore-and-query]] @@ -94,7 +80,7 @@ and dynamic client-side styling. * <> allows you to combine an infinite number of aggregations to display complex data. -With TSVB, you can analyze multiple index patterns and customize +With TSVB, you can customize every aspect of your visualization. Choose your own date format and color gradients, and easily switch your data view between time series, metric, top N, gauge, and markdown. @@ -124,7 +110,7 @@ dashboards in one space, but full access to all of Kibana’s features in anothe === Manage all things Elastic Stack <> provides guided processes for managing all -things Elastic Stack — indices, clusters, licenses, UI settings, index patterns, +things Elastic Stack — indices, clusters, licenses, UI settings, and more. Want to update your {es} indices? Set user roles and privileges? Turn on dark mode? Kibana has UIs for all that. From d8eb4143064a7c68925582f7fb6677a297fa3dd8 Mon Sep 17 00:00:00 2001 From: Tim Roes Date: Fri, 30 Oct 2020 18:30:23 +0100 Subject: [PATCH 77/80] Cleanup/codeowners (#82146) * Cleanup codeowners * Add missing readmes * Fix typos --- .github/CODEOWNERS | 6 +----- docs/developer/plugin-list.asciidoc | 12 ++++++++---- src/plugins/advanced_settings/README.md | 5 +++++ src/plugins/management/README.md | 5 +++++ 4 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 src/plugins/advanced_settings/README.md create mode 100644 src/plugins/management/README.md diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 36e9f4220b35c..c179dbadac533 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -39,10 +39,6 @@ #CC# /src/legacy/core_plugins/vis_type_vislib/ @elastic/kibana-app #CC# /src/legacy/server/url_shortening/ @elastic/kibana-app #CC# /src/legacy/ui/public/state_management @elastic/kibana-app -#CC# /src/plugins/advanced_settings/ @elastic/kibana-app -#CC# /src/plugins/charts/ @elastic/kibana-app -#CC# /src/plugins/index_pattern_management/public @elastic/kibana-app -#CC# /src/plugins/vis_default_editor @elastic/kibana-app # App Architecture /examples/bfetch_explorer/ @elastic/kibana-app-arch @@ -74,7 +70,7 @@ /x-pack/plugins/embeddable_enhanced/ @elastic/kibana-app-arch /x-pack/plugins/ui_actions_enhanced/ @elastic/kibana-app-arch #CC# /src/plugins/bfetch/ @elastic/kibana-app-arch -#CC# /src/plugins/index_pattern_management/public/service @elastic/kibana-app-arch +#CC# /src/plugins/index_pattern_management/ @elastic/kibana-app-arch #CC# /src/plugins/inspector/ @elastic/kibana-app-arch #CC# /src/plugins/share/ @elastic/kibana-app-arch #CC# /x-pack/plugins/advanced_ui_actions/ @elastic/kibana-app-arch diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 4387e168f412d..d0808d73151b0 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -22,8 +22,10 @@ NOTE: |Description -|{kib-repo}blob/{branch}/src/plugins/advanced_settings[advancedSettings] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/src/plugins/advanced_settings/README.md[advancedSettings] +|This plugin contains the advanced settings management section +allowing users to configure their advanced settings, also known +as uiSettings within the code. |{kib-repo}blob/{branch}/src/plugins/apm_oss[apmOss] @@ -130,8 +132,10 @@ in Kibana, e.g. visualizations. It has the form of a flyout panel. |WARNING: Missing README. -|{kib-repo}blob/{branch}/src/plugins/management[management] -|WARNING: Missing README. +|{kib-repo}blob/{branch}/src/plugins/management/README.md[management] +|This plugins contains the "Stack Management" page framework. It offers navigation and an API +to link individual managment section into it. This plugin does not contain any individual +management section itself. |{kib-repo}blob/{branch}/src/plugins/maps_legacy/README.md[mapsLegacy] diff --git a/src/plugins/advanced_settings/README.md b/src/plugins/advanced_settings/README.md new file mode 100644 index 0000000000000..a364348a8e99a --- /dev/null +++ b/src/plugins/advanced_settings/README.md @@ -0,0 +1,5 @@ +# Advanced Settings + +This plugin contains the advanced settings management section +allowing users to configure their advanced settings, also known +as uiSettings within the code. \ No newline at end of file diff --git a/src/plugins/management/README.md b/src/plugins/management/README.md new file mode 100644 index 0000000000000..097ecd95ea8fa --- /dev/null +++ b/src/plugins/management/README.md @@ -0,0 +1,5 @@ +# Management Plugin + +This plugins contains the "Stack Management" page framework. It offers navigation and an API +to link individual managment section into it. This plugin does not contain any individual +management section itself. \ No newline at end of file From 13858ee9081d85d4d68335b76d0b1d563f61af4d Mon Sep 17 00:00:00 2001 From: Kevin Logan <56395104+kevinlog@users.noreply.github.com> Date: Fri, 30 Oct 2020 14:01:08 -0400 Subject: [PATCH 78/80] adjust policy test to drop test for server addresses (#82120) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../apps/endpoint/policy_details.ts | 256 ++++++++---------- 1 file changed, 112 insertions(+), 144 deletions(-) diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts index 1f6973ae0f988..6af9ac2650e89 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts @@ -5,7 +5,6 @@ */ import expect from '@kbn/expect'; -import Url from 'url'; import { FtrProviderContext } from '../../ftr_provider_context'; import { PolicyTestResourceInfo } from '../../services/endpoint_policy'; @@ -20,14 +19,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { ]); const testSubjects = getService('testSubjects'); const policyTestResources = getService('policyTestResources'); - const config = getService('config'); - const kbnTestServer = config.get('servers.kibana'); - const { protocol, hostname, port } = kbnTestServer; - - const kibanaUrl = Url.format({ - hostname, - port, - }); describe('When on the Endpoint Policy Details Page', function () { this.tags(['ciGroup7']); @@ -114,152 +105,129 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { policyInfo.agentPolicy.id ); - expect(agentFullPolicy).to.eql({ - inputs: [ - { - id: policyInfo.packagePolicy.id, - revision: 2, - data_stream: { namespace: 'default' }, - name: 'Protect East Coast', - meta: { - package: { - name: 'endpoint', - version: policyInfo.packageInfo.version, + expect(agentFullPolicy.inputs).to.eql([ + { + id: policyInfo.packagePolicy.id, + revision: 2, + data_stream: { namespace: 'default' }, + name: 'Protect East Coast', + meta: { + package: { + name: 'endpoint', + version: policyInfo.packageInfo.version, + }, + }, + artifact_manifest: { + artifacts: { + 'endpoint-exceptionlist-macos-v1': { + compression_algorithm: 'zlib', + decoded_sha256: + 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + decoded_size: 14, + encoded_sha256: + 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', + encoded_size: 22, + encryption_algorithm: 'none', + relative_url: + '/api/endpoint/artifacts/download/endpoint-exceptionlist-macos-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + }, + 'endpoint-exceptionlist-windows-v1': { + compression_algorithm: 'zlib', + decoded_sha256: + 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + decoded_size: 14, + encoded_sha256: + 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', + encoded_size: 22, + encryption_algorithm: 'none', + relative_url: + '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + }, + 'endpoint-trustlist-linux-v1': { + compression_algorithm: 'zlib', + decoded_sha256: + 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + decoded_size: 14, + encoded_sha256: + 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', + encoded_size: 22, + encryption_algorithm: 'none', + relative_url: + '/api/endpoint/artifacts/download/endpoint-trustlist-linux-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + }, + 'endpoint-trustlist-macos-v1': { + compression_algorithm: 'zlib', + decoded_sha256: + 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + decoded_size: 14, + encoded_sha256: + 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', + encoded_size: 22, + encryption_algorithm: 'none', + relative_url: + '/api/endpoint/artifacts/download/endpoint-trustlist-macos-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + }, + 'endpoint-trustlist-windows-v1': { + compression_algorithm: 'zlib', + decoded_sha256: + 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + decoded_size: 14, + encoded_sha256: + 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', + encoded_size: 22, + encryption_algorithm: 'none', + relative_url: + '/api/endpoint/artifacts/download/endpoint-trustlist-windows-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', }, }, - artifact_manifest: { - artifacts: { - 'endpoint-exceptionlist-macos-v1': { - compression_algorithm: 'zlib', - decoded_sha256: - 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - decoded_size: 14, - encoded_sha256: - 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', - encoded_size: 22, - encryption_algorithm: 'none', - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-macos-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - }, - 'endpoint-exceptionlist-windows-v1': { - compression_algorithm: 'zlib', - decoded_sha256: - 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - decoded_size: 14, - encoded_sha256: - 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', - encoded_size: 22, - encryption_algorithm: 'none', - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - }, - 'endpoint-trustlist-linux-v1': { - compression_algorithm: 'zlib', - decoded_sha256: - 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - decoded_size: 14, - encoded_sha256: - 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', - encoded_size: 22, - encryption_algorithm: 'none', - relative_url: - '/api/endpoint/artifacts/download/endpoint-trustlist-linux-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - }, - 'endpoint-trustlist-macos-v1': { - compression_algorithm: 'zlib', - decoded_sha256: - 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - decoded_size: 14, - encoded_sha256: - 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', - encoded_size: 22, - encryption_algorithm: 'none', - relative_url: - '/api/endpoint/artifacts/download/endpoint-trustlist-macos-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - }, - 'endpoint-trustlist-windows-v1': { - compression_algorithm: 'zlib', - decoded_sha256: - 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - decoded_size: 14, - encoded_sha256: - 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', - encoded_size: 22, - encryption_algorithm: 'none', - relative_url: - '/api/endpoint/artifacts/download/endpoint-trustlist-windows-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + // The manifest version could have changed when the Policy was updated because the + // policy details page ensures that a save action applies the udpated policy on top + // of the latest Package Policy. So we just ignore the check against this value by + // forcing it to be the same as the value returned in the full agent policy. + manifest_version: agentFullPolicy.inputs[0].artifact_manifest.manifest_version, + schema_version: 'v1', + }, + policy: { + linux: { + events: { file: false, network: true, process: true }, + logging: { file: 'info' }, + }, + mac: { + events: { file: false, network: true, process: true }, + logging: { file: 'info' }, + malware: { mode: 'prevent' }, + popup: { + malware: { + enabled: true, + message: '', }, }, - // The manifest version could have changed when the Policy was updated because the - // policy details page ensures that a save action applies the udpated policy on top - // of the latest Package Policy. So we just ignore the check against this value by - // forcing it to be the same as the value returned in the full agent policy. - manifest_version: agentFullPolicy.inputs[0].artifact_manifest.manifest_version, - schema_version: 'v1', }, - policy: { - linux: { - events: { file: false, network: true, process: true }, - logging: { file: 'info' }, - }, - mac: { - events: { file: false, network: true, process: true }, - logging: { file: 'info' }, - malware: { mode: 'prevent' }, - popup: { - malware: { - enabled: true, - message: '', - }, - }, + windows: { + events: { + dll_and_driver_load: true, + dns: true, + file: false, + network: true, + process: true, + registry: true, + security: true, }, - windows: { - events: { - dll_and_driver_load: true, - dns: true, - file: false, - network: true, - process: true, - registry: true, - security: true, - }, - logging: { file: 'info' }, - malware: { mode: 'prevent' }, - popup: { - malware: { - enabled: true, - message: '', - }, + logging: { file: 'info' }, + malware: { mode: 'prevent' }, + popup: { + malware: { + enabled: true, + message: '', }, }, }, - streams: [], - type: 'endpoint', - use_output: 'default', - }, - ], - id: policyInfo.agentPolicy.id, - outputs: { - default: { - hosts: ['http://localhost:9200'], - type: 'elasticsearch', }, + streams: [], + type: 'endpoint', + use_output: 'default', }, - fleet: { - kibana: { - hosts: [kibanaUrl], - protocol, - }, - }, - revision: 3, - agent: { - monitoring: { - enabled: false, - logs: false, - metrics: false, - }, - }, - }); + ]); }); }); From 877ad5ac6dc83bbd03f4e81c17f93627aff3cbab Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Fri, 30 Oct 2020 13:21:22 -0500 Subject: [PATCH 79/80] Rename "service overview" to "service inventory" (#81933) To remove confusion when implementing #81718, rename the existing "service overview" to "service inventory." * Rename `ServiceOverviewLink` to `ServiceInventoryLink` * Remove service inventory test snapshots * Rename `ServiceOverview` to `ServiceInventory` * Add `service_inventory` to pageview tracking * Rename i18n keys for service inventory * Change "return to overview" link to "return to inventory" on settings page * Rename `fetchOverviewPageData` to `fetchObservabilityOverviewPageData` --- .../cypress/support/step_definitions/apm.ts | 2 +- .../step_definitions/csm/csm_dashboard.ts | 2 +- .../apm/public/components/app/Home/index.tsx | 10 +- .../__test__/NoServicesMessage.test.tsx | 26 - .../NoServicesMessage.test.tsx.snap | 99 --- .../service_overview.test.tsx.snap | 690 ------------------ .../public/components/app/Settings/index.tsx | 4 +- .../ServiceList/HealthBadge.tsx | 0 .../ServiceList/MLCallout.tsx | 2 +- .../ServiceList/ServiceListMetric.tsx | 0 .../ServiceList/__fixtures__/props.json | 0 .../ServiceList/index.tsx | 0 .../ServiceList/service_list.test.tsx | 0 .../index.tsx | 14 +- .../no_services_message.test.tsx | 37 + .../no_services_message.tsx} | 0 .../service_inventory.test.tsx} | 56 +- ...iewLink.tsx => service_inventory_link.tsx} | 4 +- x-pack/plugins/apm/public/plugin.ts | 8 +- ...m_observability_overview_fetchers.test.ts} | 13 +- ...=> apm_observability_overview_fetchers.ts} | 2 +- .../translations/translations/ja-JP.json | 10 +- .../translations/translations/zh-CN.json | 10 +- 23 files changed, 106 insertions(+), 883 deletions(-) delete mode 100644 x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/NoServicesMessage.test.tsx delete mode 100644 x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/NoServicesMessage.test.tsx.snap delete mode 100644 x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/service_overview.test.tsx.snap rename x-pack/plugins/apm/public/components/app/{ServiceOverview => service_inventory}/ServiceList/HealthBadge.tsx (100%) rename x-pack/plugins/apm/public/components/app/{ServiceOverview => service_inventory}/ServiceList/MLCallout.tsx (96%) rename x-pack/plugins/apm/public/components/app/{ServiceOverview => service_inventory}/ServiceList/ServiceListMetric.tsx (100%) rename x-pack/plugins/apm/public/components/app/{ServiceOverview => service_inventory}/ServiceList/__fixtures__/props.json (100%) rename x-pack/plugins/apm/public/components/app/{ServiceOverview => service_inventory}/ServiceList/index.tsx (100%) rename x-pack/plugins/apm/public/components/app/{ServiceOverview => service_inventory}/ServiceList/service_list.test.tsx (100%) rename x-pack/plugins/apm/public/components/app/{ServiceOverview => service_inventory}/index.tsx (89%) create mode 100644 x-pack/plugins/apm/public/components/app/service_inventory/no_services_message.test.tsx rename x-pack/plugins/apm/public/components/app/{ServiceOverview/NoServicesMessage.tsx => service_inventory/no_services_message.tsx} (100%) rename x-pack/plugins/apm/public/components/app/{ServiceOverview/__test__/service_overview.test.tsx => service_inventory/service_inventory.test.tsx} (79%) rename x-pack/plugins/apm/public/components/shared/Links/apm/{ServiceOverviewLink.tsx => service_inventory_link.tsx} (90%) rename x-pack/plugins/apm/public/services/rest/{apm_overview_fetchers.test.ts => apm_observability_overview_fetchers.test.ts} (89%) rename x-pack/plugins/apm/public/services/rest/{apm_overview_fetchers.ts => apm_observability_overview_fetchers.ts} (96%) diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/apm.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/apm.ts index ab2bf20b36ed4..50c620dca9ddf 100644 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/apm.ts +++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/apm.ts @@ -11,7 +11,7 @@ import { loginAndWaitForPage } from '../../integration/helpers'; export const DEFAULT_TIMEOUT = 60 * 1000; Given(`a user browses the APM UI application`, () => { - // open service overview page + // Open service inventory page loginAndWaitForPage(`/app/apm/services`, { from: '2020-06-01T14:59:32.686Z', to: '2020-06-16T16:59:36.219Z', diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts index d8540c3f3efd7..452d8b719b3cb 100644 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts +++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts @@ -12,7 +12,7 @@ import { verifyClientMetrics } from './client_metrics_helper'; export const DEFAULT_TIMEOUT = { timeout: 60 * 1000 }; Given(`a user browses the APM UI application for RUM Data`, () => { - // open service overview page + // Open UX landing page const RANGE_FROM = 'now-24h'; const RANGE_TO = 'now'; loginAndWaitForPage( 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 446f7b978a434..c4224bf676abb 100644 --- a/x-pack/plugins/apm/public/components/app/Home/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Home/index.tsx @@ -20,12 +20,12 @@ import { ApmHeader } from '../../shared/ApmHeader'; import { EuiTabLink } from '../../shared/EuiTabLink'; import { AnomalyDetectionSetupLink } from '../../shared/Links/apm/AnomalyDetectionSetupLink'; import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink'; -import { ServiceOverviewLink } from '../../shared/Links/apm/ServiceOverviewLink'; +import { ServiceInventoryLink } from '../../shared/Links/apm/service_inventory_link'; import { SettingsLink } from '../../shared/Links/apm/SettingsLink'; import { TraceOverviewLink } from '../../shared/Links/apm/TraceOverviewLink'; import { SetupInstructionsLink } from '../../shared/Links/SetupInstructionsLink'; import { ServiceMap } from '../ServiceMap'; -import { ServiceOverview } from '../ServiceOverview'; +import { ServiceInventory } from '../service_inventory'; import { TraceOverview } from '../TraceOverview'; import { AlertingPopoverAndFlyout } from './alerting_popover_flyout'; @@ -37,13 +37,13 @@ function getHomeTabs({ const homeTabs = [ { link: ( - + {i18n.translate('xpack.apm.home.servicesTabLabel', { defaultMessage: 'Services', })} - + ), - render: () => , + render: () => , name: 'services', }, { diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/NoServicesMessage.test.tsx b/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/NoServicesMessage.test.tsx deleted file mode 100644 index 21681f42d4b52..0000000000000 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/NoServicesMessage.test.tsx +++ /dev/null @@ -1,26 +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 { shallow } from 'enzyme'; -import React from 'react'; -import { NoServicesMessage } from '../NoServicesMessage'; -import { FETCH_STATUS } from '../../../../hooks/useFetcher'; - -describe('NoServicesMessage', () => { - Object.values(FETCH_STATUS).forEach((status) => { - [true, false].forEach((historicalDataFound) => { - it(`status: ${status} and historicalDataFound: ${historicalDataFound}`, () => { - const wrapper = shallow( - - ); - expect(wrapper).toMatchSnapshot(); - }); - }); - }); -}); diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/NoServicesMessage.test.tsx.snap b/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/NoServicesMessage.test.tsx.snap deleted file mode 100644 index d027422961c99..0000000000000 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/NoServicesMessage.test.tsx.snap +++ /dev/null @@ -1,99 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`NoServicesMessage status: failure and historicalDataFound: false 1`] = ``; - -exports[`NoServicesMessage status: failure and historicalDataFound: true 1`] = ``; - -exports[`NoServicesMessage status: loading and historicalDataFound: false 1`] = ``; - -exports[`NoServicesMessage status: loading and historicalDataFound: true 1`] = ``; - -exports[`NoServicesMessage status: pending and historicalDataFound: false 1`] = ` - - } - body={ - -

    - Upgrading from a pre-7.x version? Make sure you've also upgraded - your APM Server instance(s) to at least 7.0. -

    -

    - You may also have old data that needs to be migrated. - - - Learn more by visiting the Kibana Upgrade Assistant - - . -

    - - } - title={ -
    - Looks like you don't have any APM services installed. Let's add some! -
    - } - titleSize="s" -/> -`; - -exports[`NoServicesMessage status: pending and historicalDataFound: true 1`] = ` - - No services found -
  • - } - titleSize="s" -/> -`; - -exports[`NoServicesMessage status: success and historicalDataFound: false 1`] = ` - - } - body={ - -

    - Upgrading from a pre-7.x version? Make sure you've also upgraded - your APM Server instance(s) to at least 7.0. -

    -

    - You may also have old data that needs to be migrated. - - - Learn more by visiting the Kibana Upgrade Assistant - - . -

    -
    - } - title={ -
    - Looks like you don't have any APM services installed. Let's add some! -
    - } - titleSize="s" -/> -`; - -exports[`NoServicesMessage status: success and historicalDataFound: true 1`] = ` - - No services found -
    - } - titleSize="s" -/> -`; diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/service_overview.test.tsx.snap b/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/service_overview.test.tsx.snap deleted file mode 100644 index 49f30910ee0f1..0000000000000 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/service_overview.test.tsx.snap +++ /dev/null @@ -1,690 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Service Overview -> View should render empty message, when list is empty and historical data is found 1`] = ` -NodeList [ - - -
    - -
    - -
    - No services found -
    -
    - -
    -
    -
    - - , -] -`; - -exports[`Service Overview -> View should render getting started message, when list is empty and no historical data is found 1`] = ` -NodeList [ - - -
    - -
    - -
    - Looks like you don't have any APM services installed. Let's add some! -
    -
    - - - - - , -] -`; - -exports[`Service Overview -> View should render services, when list is not empty 1`] = ` -NodeList [ - .c1 { - font-size: 16px; - max-width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.c0 { - width: 100%; -} - -.c0 .apmServiceList__serviceNameTooltip { - width: 100%; -} - -.c0 .apmServiceList__serviceNameTooltip .apmServiceList__serviceNameContainer { - width: calc(100% - 24px); -} - - - -
    - Health -
    -
    - - - - Warning - - - -
    - - -
    - Name -
    -
    - - - - - -
    - - -
    - Environment -
    -
    - - - - - 2 environments - - - - -
    - - -
    - Avg. response time -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    - N/A -
    -
    -
    -
    -
    -
    - 0 ms -
    -
    -
    - - -
    - Trans. per minute -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    - N/A -
    -
    -
    -
    -
    -
    - 0 tpm -
    -
    -
    - - -
    - Error rate % -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    - N/A -
    -
    -
    -
    -
    -
    -
    -
    - - , - .c1 { - font-size: 16px; - max-width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.c0 { - width: 100%; -} - -.c0 .apmServiceList__serviceNameTooltip { - width: 100%; -} - -.c0 .apmServiceList__serviceNameTooltip .apmServiceList__serviceNameContainer { - width: calc(100% - 24px); -} - - - -
    - Health -
    -
    - - - - Unknown - - - -
    - - -
    - Name -
    -
    - - -
    -
    - go -
    - -
    -
    -
    -
    - - -
    - Environment -
    -
    - - -
    - Avg. response time -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    - N/A -
    -
    -
    -
    -
    -
    - 0 ms -
    -
    -
    - - -
    - Trans. per minute -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    - N/A -
    -
    -
    -
    -
    -
    - 0 tpm -
    -
    -
    - - -
    - Error rate % -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    - N/A -
    -
    -
    -
    -
    -
    -
    -
    - - , -] -`; diff --git a/x-pack/plugins/apm/public/components/app/Settings/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/index.tsx index aa71050802215..e770116ac2759 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/index.tsx @@ -36,8 +36,8 @@ export function Settings({ children, location }: SettingsProps) { <> - {i18n.translate('xpack.apm.settings.returnToOverviewLinkLabel', { - defaultMessage: 'Return to overview', + {i18n.translate('xpack.apm.settings.returnLinkLabel', { + defaultMessage: 'Return to inventory', })} diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/HealthBadge.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/ServiceList/HealthBadge.tsx similarity index 100% rename from x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/HealthBadge.tsx rename to x-pack/plugins/apm/public/components/app/service_inventory/ServiceList/HealthBadge.tsx diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/MLCallout.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/ServiceList/MLCallout.tsx similarity index 96% rename from x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/MLCallout.tsx rename to x-pack/plugins/apm/public/components/app/service_inventory/ServiceList/MLCallout.tsx index dd632db0f15fe..67eb22d48aae6 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/MLCallout.tsx +++ b/x-pack/plugins/apm/public/components/app/service_inventory/ServiceList/MLCallout.tsx @@ -15,7 +15,7 @@ import { APMLink } from '../../../shared/Links/apm/APMLink'; export function MLCallout({ onDismiss }: { onDismiss: () => void }) { return ( - {i18n.translate('xpack.apm.serviceOverview.toastText', { + {i18n.translate('xpack.apm.serviceInventory.toastText', { defaultMessage: "You're running Elastic Stack 7.0+ and we've detected incompatible data from a previous 6.x version. If you want to view this data in APM, you should migrate it. See more in ", })} @@ -74,7 +74,7 @@ export function ServiceOverview() { })} > {i18n.translate( - 'xpack.apm.serviceOverview.upgradeAssistantLink', + 'xpack.apm.serviceInventory.upgradeAssistantLinkText', { defaultMessage: 'the upgrade assistant', } @@ -86,6 +86,10 @@ export function ServiceOverview() { } }, [data.hasLegacyData, core.http.basePath, core.notifications.toasts]); + // The page is called "service inventory" to avoid confusion with the + // "service overview", but this is tracked in some dashboards because it's the + // initial landing page for APM, so it stays as "services_overview" (plural.) + // for backward compatibility. useTrackPageview({ app: 'apm', path: 'services_overview' }); useTrackPageview({ app: 'apm', path: 'services_overview', delay: 15000 }); diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/no_services_message.test.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/no_services_message.test.tsx new file mode 100644 index 0000000000000..0fc2a2b4cdcef --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/service_inventory/no_services_message.test.tsx @@ -0,0 +1,37 @@ +/* + * 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 { render } from '@testing-library/react'; +import React, { ReactNode } from 'react'; +import { MockApmPluginContextWrapper } from '../../../context/ApmPluginContext/MockApmPluginContext'; +import { FETCH_STATUS } from '../../../hooks/useFetcher'; +import { NoServicesMessage } from './no_services_message'; + +function Wrapper({ children }: { children?: ReactNode }) { + return {children}; +} + +describe('NoServicesMessage', () => { + Object.values(FETCH_STATUS).forEach((status) => { + [true, false].forEach((historicalDataFound) => { + describe(`when status is ${status}`, () => { + describe(`when historicalDataFound is ${historicalDataFound}`, () => { + it('renders', () => { + expect(() => + render( + , + { wrapper: Wrapper } + ) + ).not.toThrowError(); + }); + }); + }); + }); + }); +}); diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/NoServicesMessage.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/no_services_message.tsx similarity index 100% rename from x-pack/plugins/apm/public/components/app/ServiceOverview/NoServicesMessage.tsx rename to x-pack/plugins/apm/public/components/app/service_inventory/no_services_message.tsx diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/service_overview.test.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/service_inventory.test.tsx similarity index 79% rename from x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/service_overview.test.tsx rename to x-pack/plugins/apm/public/components/app/service_inventory/service_inventory.test.tsx index 06e9008d5aebe..d394c7db62554 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/service_overview.test.tsx +++ b/x-pack/plugins/apm/public/components/app/service_inventory/service_inventory.test.tsx @@ -7,22 +7,22 @@ import { render, waitFor } from '@testing-library/react'; import { CoreStart } from 'kibana/public'; import { merge } from 'lodash'; -import React, { FunctionComponent, ReactChild } from 'react'; +import React, { ReactNode } from 'react'; import { MemoryRouter } from 'react-router-dom'; import { createKibanaReactContext } from 'src/plugins/kibana_react/public'; -import { ServiceHealthStatus } from '../../../../../common/service_health_status'; -import { ServiceOverview } from '..'; -import { EuiThemeProvider } from '../../../../../../observability/public'; -import { ApmPluginContextValue } from '../../../../context/ApmPluginContext'; +import { ServiceHealthStatus } from '../../../../common/service_health_status'; +import { ServiceInventory } from '.'; +import { EuiThemeProvider } from '../../../../../observability/public'; +import { ApmPluginContextValue } from '../../../context/ApmPluginContext'; import { mockApmPluginContextValue, MockApmPluginContextWrapper, -} from '../../../../context/ApmPluginContext/MockApmPluginContext'; -import * as useAnomalyDetectionJobs from '../../../../hooks/useAnomalyDetectionJobs'; -import { FETCH_STATUS } from '../../../../hooks/useFetcher'; -import * as useLocalUIFilters from '../../../../hooks/useLocalUIFilters'; -import * as urlParamsHooks from '../../../../hooks/useUrlParams'; -import { SessionStorageMock } from '../../../../services/__test__/SessionStorageMock'; +} from '../../../context/ApmPluginContext/MockApmPluginContext'; +import * as useAnomalyDetectionJobs from '../../../hooks/useAnomalyDetectionJobs'; +import { FETCH_STATUS } from '../../../hooks/useFetcher'; +import * as useLocalUIFilters from '../../../hooks/useLocalUIFilters'; +import * as urlParamsHooks from '../../../hooks/useUrlParams'; +import { SessionStorageMock } from '../../../services/__test__/SessionStorageMock'; const KibanaReactContext = createKibanaReactContext({ usageCollection: { reportUiStats: () => {} }, @@ -31,7 +31,7 @@ const KibanaReactContext = createKibanaReactContext({ const addWarning = jest.fn(); const httpGet = jest.fn(); -function wrapper({ children }: { children: ReactChild }) { +function wrapper({ children }: { children?: ReactNode }) { const mockPluginContext = (merge({}, mockApmPluginContextValue, { core: { http: { @@ -58,13 +58,7 @@ function wrapper({ children }: { children: ReactChild }) { ); } -function renderServiceOverview() { - return render(, { wrapper } as { - wrapper: FunctionComponent<{}>; - }); -} - -describe('Service Overview -> View', () => { +describe('ServiceInventory', () => { beforeEach(() => { // @ts-expect-error global.sessionStorage = new SessionStorageMock(); @@ -129,13 +123,13 @@ describe('Service Overview -> View', () => { ], }); - const { container, findByText } = renderServiceOverview(); + const { container, findByText } = render(, { wrapper }); // wait for requests to be made await waitFor(() => expect(httpGet).toHaveBeenCalledTimes(1)); await findByText('My Python Service'); - expect(container.querySelectorAll('.euiTableRow')).toMatchSnapshot(); + expect(container.querySelectorAll('.euiTableRow')).toHaveLength(2); }); it('should render getting started message, when list is empty and no historical data is found', async () => { @@ -145,17 +139,17 @@ describe('Service Overview -> View', () => { items: [], }); - const { container, findByText } = renderServiceOverview(); + const { findByText } = render(, { wrapper }); // wait for requests to be made await waitFor(() => expect(httpGet).toHaveBeenCalledTimes(1)); // wait for elements to be rendered - await findByText( + const gettingStartedMessage = await findByText( "Looks like you don't have any APM services installed. Let's add some!" ); - expect(container.querySelectorAll('.euiTableRow')).toMatchSnapshot(); + expect(gettingStartedMessage).not.toBeEmpty(); }); it('should render empty message, when list is empty and historical data is found', async () => { @@ -165,13 +159,13 @@ describe('Service Overview -> View', () => { items: [], }); - const { container, findByText } = renderServiceOverview(); + const { findByText } = render(, { wrapper }); // wait for requests to be made await waitFor(() => expect(httpGet).toHaveBeenCalledTimes(1)); - await findByText('No services found'); + const noServicesText = await findByText('No services found'); - expect(container.querySelectorAll('.euiTableRow')).toMatchSnapshot(); + expect(noServicesText).not.toBeEmpty(); }); describe('when legacy data is found', () => { @@ -182,7 +176,7 @@ describe('Service Overview -> View', () => { items: [], }); - renderServiceOverview(); + render(, { wrapper }); // wait for requests to be made await waitFor(() => expect(httpGet).toHaveBeenCalledTimes(1)); @@ -203,7 +197,7 @@ describe('Service Overview -> View', () => { items: [], }); - renderServiceOverview(); + render(, { wrapper }); // wait for requests to be made await waitFor(() => expect(httpGet).toHaveBeenCalledTimes(1)); @@ -229,7 +223,7 @@ describe('Service Overview -> View', () => { ], }); - const { queryByText } = renderServiceOverview(); + const { queryByText } = render(, { wrapper }); // wait for requests to be made await waitFor(() => expect(httpGet).toHaveBeenCalledTimes(1)); @@ -256,7 +250,7 @@ describe('Service Overview -> View', () => { ], }); - const { queryAllByText } = renderServiceOverview(); + const { queryAllByText } = render(, { wrapper }); // wait for requests to be made await waitFor(() => expect(httpGet).toHaveBeenCalledTimes(1)); diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/service_inventory_link.tsx similarity index 90% rename from x-pack/plugins/apm/public/components/shared/Links/apm/ServiceOverviewLink.tsx rename to x-pack/plugins/apm/public/components/shared/Links/apm/service_inventory_link.tsx index 2081fc4767903..e3fa03a4d4f86 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceOverviewLink.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/service_inventory_link.tsx @@ -14,7 +14,7 @@ import { APMLink, APMLinkExtendProps } from './APMLink'; import { useUrlParams } from '../../../../hooks/useUrlParams'; import { pickKeys } from '../../../../../common/utils/pick_keys'; -function ServiceOverviewLink(props: APMLinkExtendProps) { +function ServiceInventoryLink(props: APMLinkExtendProps) { const { urlParams } = useUrlParams(); const persistedFilters = pickKeys(urlParams, 'host', 'agentName'); @@ -22,4 +22,4 @@ function ServiceOverviewLink(props: APMLinkExtendProps) { return ; } -export { ServiceOverviewLink }; +export { ServiceInventoryLink }; diff --git a/x-pack/plugins/apm/public/plugin.ts b/x-pack/plugins/apm/public/plugin.ts index 560a1a077931b..cc0151afba63c 100644 --- a/x-pack/plugins/apm/public/plugin.ts +++ b/x-pack/plugins/apm/public/plugin.ts @@ -81,14 +81,14 @@ export class ApmPlugin implements Plugin { if (plugins.observability) { const getApmDataHelper = async () => { const { - fetchOverviewPageData, + fetchObservabilityOverviewPageData, hasData, createCallApmApi, - } = await import('./services/rest/apm_overview_fetchers'); + } = await import('./services/rest/apm_observability_overview_fetchers'); // have to do this here as well in case app isn't mounted yet createCallApmApi(core.http); - return { fetchOverviewPageData, hasData }; + return { fetchObservabilityOverviewPageData, hasData }; }; plugins.observability.dashboard.register({ appName: 'apm', @@ -98,7 +98,7 @@ export class ApmPlugin implements Plugin { }, fetchData: async (params: FetchDataParams) => { const dataHelper = await getApmDataHelper(); - return await dataHelper.fetchOverviewPageData(params); + return await dataHelper.fetchObservabilityOverviewPageData(params); }, }); diff --git a/x-pack/plugins/apm/public/services/rest/apm_overview_fetchers.test.ts b/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.test.ts similarity index 89% rename from x-pack/plugins/apm/public/services/rest/apm_overview_fetchers.test.ts rename to x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.test.ts index 4e306c93805d0..22ec317fca64b 100644 --- a/x-pack/plugins/apm/public/services/rest/apm_overview_fetchers.test.ts +++ b/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.test.ts @@ -5,7 +5,10 @@ */ import moment from 'moment'; -import { fetchOverviewPageData, hasData } from './apm_overview_fetchers'; +import { + fetchObservabilityOverviewPageData, + hasData, +} from './apm_observability_overview_fetchers'; import * as createCallApmApi from './createCallApmApi'; describe('Observability dashboard data', () => { @@ -37,7 +40,7 @@ describe('Observability dashboard data', () => { }); }); - describe('fetchOverviewPageData', () => { + describe('fetchObservabilityOverviewPageData', () => { it('returns APM data with series and stats', async () => { callApmApiMock.mockImplementation(() => Promise.resolve({ @@ -49,7 +52,7 @@ describe('Observability dashboard data', () => { ], }) ); - const response = await fetchOverviewPageData(params); + const response = await fetchObservabilityOverviewPageData(params); expect(response).toEqual({ appLink: '/app/apm/services?rangeFrom=now-15m&rangeTo=now', stats: { @@ -80,7 +83,7 @@ describe('Observability dashboard data', () => { transactionCoordinates: [], }) ); - const response = await fetchOverviewPageData(params); + const response = await fetchObservabilityOverviewPageData(params); expect(response).toEqual({ appLink: '/app/apm/services?rangeFrom=now-15m&rangeTo=now', stats: { @@ -107,7 +110,7 @@ describe('Observability dashboard data', () => { transactionCoordinates: [{ x: 1 }, { x: 2 }, { x: 3 }], }) ); - const response = await fetchOverviewPageData(params); + const response = await fetchObservabilityOverviewPageData(params); expect(response).toEqual({ appLink: '/app/apm/services?rangeFrom=now-15m&rangeTo=now', stats: { diff --git a/x-pack/plugins/apm/public/services/rest/apm_overview_fetchers.ts b/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.ts similarity index 96% rename from x-pack/plugins/apm/public/services/rest/apm_overview_fetchers.ts rename to x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.ts index 422c7b882e5dc..bc1db4eed1d9e 100644 --- a/x-pack/plugins/apm/public/services/rest/apm_overview_fetchers.ts +++ b/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.ts @@ -13,7 +13,7 @@ import { callApmApi } from './createCallApmApi'; export { createCallApmApi } from './createCallApmApi'; -export const fetchOverviewPageData = async ({ +export const fetchObservabilityOverviewPageData = async ({ absoluteTime, relativeTime, bucketSize, diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index cd090b0c264ef..19e8e057db0ea 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -5105,10 +5105,10 @@ "xpack.apm.serviceOverview.mlNudgeMessage.content": "ML異常検知との統合により、サービスの正常性ステータスを確認できます", "xpack.apm.serviceOverview.mlNudgeMessage.dismissButton": "メッセージを消去", "xpack.apm.serviceOverview.mlNudgeMessage.learnMoreButton": "詳細", - "xpack.apm.serviceOverview.mlNudgeMessage.title": "異常検知を有効にしてサービスのヘルスを確認", - "xpack.apm.serviceOverview.toastText": "現在 Elastic Stack 7.0+ を実行中で、以前のバージョン 6.x からの互換性のないデータを検知しました。このデータを APM で表示するには、移行が必要です。詳細: ", - "xpack.apm.serviceOverview.toastTitle": "選択された時間範囲内にレガシーデータが検知されました。", - "xpack.apm.serviceOverview.upgradeAssistantLink": "アップグレードアシスタント", + "xpack.apm.serviceInventory.mlNudgeMessageTitle": "異常検知を有効にしてサービスのヘルスを確認", + "xpack.apm.serviceInventory.toastText": "現在 Elastic Stack 7.0+ を実行中で、以前のバージョン 6.x からの互換性のないデータを検知しました。このデータを APM で表示するには、移行が必要です。詳細: ", + "xpack.apm.serviceInventory.toastTitle": "選択された時間範囲内にレガシーデータが検知されました。", + "xpack.apm.serviceInventory.upgradeAssistantLinkText": "アップグレードアシスタント", "xpack.apm.servicesTable.7xOldDataMessage": "また、移行が必要な古いデータがある可能性もあります。", "xpack.apm.servicesTable.7xUpgradeServerMessage": "バージョン7.xより前からのアップグレードですか?また、\n APMサーバーインスタンスを7.0以降にアップグレードしていることも確認してください。", "xpack.apm.servicesTable.avgResponseTimeColumnLabel": "平均応答時間", @@ -5208,7 +5208,7 @@ "xpack.apm.settings.customizeUI.customLink.table.url": "URL", "xpack.apm.settings.indices": "インデックス", "xpack.apm.settings.pageTitle": "設定", - "xpack.apm.settings.returnToOverviewLinkLabel": "概要に戻る", + "xpack.apm.settings.returnLinkLabel": "概要に戻る", "xpack.apm.settingsLinkLabel": "設定", "xpack.apm.setupInstructionsButtonLabel": "セットアップの手順", "xpack.apm.stacktraceTab.causedByFramesToogleButtonLabel": "作成元", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 18403d85d5ff7..c448efdd9d7b5 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -5109,10 +5109,10 @@ "xpack.apm.serviceOverview.mlNudgeMessage.content": "我们集成了 ML 异常检测,让您可以查看服务的运行状况", "xpack.apm.serviceOverview.mlNudgeMessage.dismissButton": "关闭消息", "xpack.apm.serviceOverview.mlNudgeMessage.learnMoreButton": "了解详情", - "xpack.apm.serviceOverview.mlNudgeMessage.title": "启用异常检测可查看服务的运行状况", - "xpack.apm.serviceOverview.toastText": "您正在运行 Elastic Stack 7.0+,我们检测到来自以前 6.x 版本的不兼容数据。如果想在 APM 中查看,您应迁移这些数据。在以下位置查看更多: ", - "xpack.apm.serviceOverview.toastTitle": "在选定时间范围中检测到旧数据", - "xpack.apm.serviceOverview.upgradeAssistantLink": "升级助手", + "xpack.apm.serviceInventory.mlNudgeMessageTitle": "启用异常检测可查看服务的运行状况", + "xpack.apm.serviceInventory.toastText": "您正在运行 Elastic Stack 7.0+,我们检测到来自以前 6.x 版本的不兼容数据。如果想在 APM 中查看,您应迁移这些数据。在以下位置查看更多: ", + "xpack.apm.serviceInventory.toastTitle": "在选定时间范围中检测到旧数据", + "xpack.apm.serviceInventory.upgradeAssistantLinkText": "升级助手", "xpack.apm.servicesTable.7xOldDataMessage": "可能还有需要迁移的旧数据。", "xpack.apm.servicesTable.7xUpgradeServerMessage": "从 7.x 之前的版本升级?另外,确保您已将\n APM Server 实例升级到至少 7.0。", "xpack.apm.servicesTable.avgResponseTimeColumnLabel": "平均响应时间", @@ -5212,7 +5212,7 @@ "xpack.apm.settings.customizeUI.customLink.table.url": "URL", "xpack.apm.settings.indices": "索引", "xpack.apm.settings.pageTitle": "设置", - "xpack.apm.settings.returnToOverviewLinkLabel": "返回到概览", + "xpack.apm.settings.returnLinkLabel": "返回到概览", "xpack.apm.settingsLinkLabel": "璁剧疆", "xpack.apm.setupInstructionsButtonLabel": "设置说明", "xpack.apm.stacktraceTab.causedByFramesToogleButtonLabel": "原因", From fcb590e5bd8a77242c2f50447eeb018e35b9aacf Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Fri, 30 Oct 2020 13:26:50 -0500 Subject: [PATCH 80/80] Fix link to upgrade assistant (#82138) This broke when stack management changed their URLs. --- x-pack/plugins/apm/public/setHelpExtension.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/x-pack/plugins/apm/public/setHelpExtension.ts b/x-pack/plugins/apm/public/setHelpExtension.ts index b6e745dcf1655..f895fbc36ed03 100644 --- a/x-pack/plugins/apm/public/setHelpExtension.ts +++ b/x-pack/plugins/apm/public/setHelpExtension.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import url from 'url'; import { i18n } from '@kbn/i18n'; import { CoreStart } from 'kibana/public'; @@ -20,10 +19,7 @@ export function setHelpExtension({ chrome, http }: CoreStart) { }, { linkType: 'custom', - href: url.format({ - pathname: http.basePath.prepend('/app/kibana'), - hash: '/management/stack/upgrade_assistant', - }), + href: http.basePath.prepend('/app/management/stack/upgrade_assistant'), content: i18n.translate('xpack.apm.helpMenu.upgradeAssistantLink', { defaultMessage: 'Upgrade assistant', }),