diff --git a/.ci/pipeline-library/src/test/prChanges.groovy b/.ci/pipeline-library/src/test/prChanges.groovy
index f149340517ff0..0f354e7687246 100644
--- a/.ci/pipeline-library/src/test/prChanges.groovy
+++ b/.ci/pipeline-library/src/test/prChanges.groovy
@@ -97,4 +97,17 @@ class PrChangesTest extends KibanaBasePipelineTest {
assertFalse(prChanges.areChangesSkippable())
}
+
+ @Test
+ void 'areChangesSkippable() with plugin readme changes'() {
+ props([
+ githubPrs: [
+ getChanges: { [
+ [filename: 'src/plugins/foo/README.asciidoc'],
+ ] },
+ ],
+ ])
+
+ assertFalse(prChanges.areChangesSkippable())
+ }
}
diff --git a/src/plugins/visualize/public/application/components/experimental_vis_info.tsx b/src/plugins/visualize/public/application/components/experimental_vis_info.tsx
index 51abb3ca530a4..5f08bea60e538 100644
--- a/src/plugins/visualize/public/application/components/experimental_vis_info.tsx
+++ b/src/plugins/visualize/public/application/components/experimental_vis_info.tsx
@@ -26,12 +26,20 @@ export const InfoComponent = () => {
<>
{' '}
-
- GitHub
-
- {'.'}
+ defaultMessage="This visualization is experimental and is not subject to the support SLA of official GA features.
+ For feedback, please create an issue in {githubLink}."
+ values={{
+ githubLink: (
+
+ GitHub
+
+ ),
+ }}
+ />
>
);
diff --git a/vars/prChanges.groovy b/vars/prChanges.groovy
index adaacf952b5b6..a7fe46e7bf014 100644
--- a/vars/prChanges.groovy
+++ b/vars/prChanges.groovy
@@ -22,6 +22,8 @@ def getNotSkippablePaths() {
return [
// this file is auto-generated and changes to it need to be validated with CI
/^docs\/developer\/architecture\/code-exploration.asciidoc$/,
+ // don't skip CI on prs with changes to plugin readme files (?i) is for case-insensitive matching
+ /(?i)\/plugins\/[^\/]+\/readme\.(md|asciidoc)$/,
]
}
diff --git a/x-pack/plugins/alerts/server/alerts_client.ts b/x-pack/plugins/alerts/server/alerts_client.ts
index 256cae24e519f..dd66ccc7a0256 100644
--- a/x-pack/plugins/alerts/server/alerts_client.ts
+++ b/x-pack/plugins/alerts/server/alerts_client.ts
@@ -387,11 +387,18 @@ export class AlertsClient {
updateResult.scheduledTaskId &&
!isEqual(alertSavedObject.attributes.schedule, updateResult.schedule)
) {
- this.taskManager.runNow(updateResult.scheduledTaskId).catch((err: Error) => {
- this.logger.error(
- `Alert update failed to run its underlying task. TaskManager runNow failed with Error: ${err.message}`
- );
- });
+ this.taskManager
+ .runNow(updateResult.scheduledTaskId)
+ .then(() => {
+ this.logger.debug(
+ `Alert update has rescheduled the underlying task: ${updateResult.scheduledTaskId}`
+ );
+ })
+ .catch((err: Error) => {
+ this.logger.error(
+ `Alert update failed to run its underlying task. TaskManager runNow failed with Error: ${err.message}`
+ );
+ });
}
})(),
]);
diff --git a/x-pack/plugins/enterprise_search/common/constants.ts b/x-pack/plugins/enterprise_search/common/constants.ts
index fc9a47717871b..c5839df4c603b 100644
--- a/x-pack/plugins/enterprise_search/common/constants.ts
+++ b/x-pack/plugins/enterprise_search/common/constants.ts
@@ -4,6 +4,40 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { i18n } from '@kbn/i18n';
+
+export const ENTERPRISE_SEARCH_PLUGIN = {
+ ID: 'enterpriseSearch',
+ NAME: i18n.translate('xpack.enterpriseSearch.productName', {
+ defaultMessage: 'Enterprise Search',
+ }),
+ URL: '/app/enterprise_search',
+};
+
+export const APP_SEARCH_PLUGIN = {
+ ID: 'appSearch',
+ NAME: i18n.translate('xpack.enterpriseSearch.appSearch.productName', {
+ defaultMessage: 'App Search',
+ }),
+ DESCRIPTION: i18n.translate('xpack.enterpriseSearch.appSearch.productDescription', {
+ defaultMessage:
+ 'Leverage dashboards, analytics, and APIs for advanced application search made simple.',
+ }),
+ URL: '/app/enterprise_search/app_search',
+};
+
+export const WORKPLACE_SEARCH_PLUGIN = {
+ ID: 'workplaceSearch',
+ NAME: i18n.translate('xpack.enterpriseSearch.workplaceSearch.productName', {
+ defaultMessage: 'Workplace Search',
+ }),
+ DESCRIPTION: i18n.translate('xpack.enterpriseSearch.workplaceSearch.productDescription', {
+ defaultMessage:
+ 'Search all documents, files, and sources available across your virtual workplace.',
+ }),
+ URL: '/app/enterprise_search/workplace_search',
+};
+
export const JSON_HEADER = { 'Content-Type': 'application/json' }; // This needs specific casing or Chrome throws a 415 error
export const ENGINES_PAGE_SIZE = 10;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx
index df278bf938a69..f899423319afc 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx
@@ -9,6 +9,7 @@ import { EuiSpacer, EuiTitle, EuiText } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
+import { APP_SEARCH_PLUGIN } from '../../../../../common/constants';
import { SetupGuide as SetupGuideLayout } from '../../../shared/setup_guide';
import { SetAppSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs';
import { SendAppSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
@@ -16,14 +17,16 @@ import GettingStarted from '../../assets/getting_started.png';
export const SetupGuide: React.FC = () => (
-
+
(
breadcrumbs: TBreadcrumbs = []
) => [
- generateBreadcrumb({ text: 'Enterprise Search' }),
+ generateBreadcrumb({ text: ENTERPRISE_SEARCH_PLUGIN.NAME }),
...breadcrumbs.map(({ text, path }: IGenerateBreadcrumbProps) =>
generateBreadcrumb({ text, path, history })
),
];
export const appSearchBreadcrumbs = (history: History) => (breadcrumbs: TBreadcrumbs = []) =>
- enterpriseSearchBreadcrumbs(history)([{ text: 'App Search', path: '/' }, ...breadcrumbs]);
+ enterpriseSearchBreadcrumbs(history)([
+ { text: APP_SEARCH_PLUGIN.NAME, path: '/' },
+ ...breadcrumbs,
+ ]);
export const workplaceSearchBreadcrumbs = (history: History) => (breadcrumbs: TBreadcrumbs = []) =>
- enterpriseSearchBreadcrumbs(history)([{ text: 'Workplace Search', path: '/' }, ...breadcrumbs]);
+ enterpriseSearchBreadcrumbs(history)([
+ { text: WORKPLACE_SEARCH_PLUGIN.NAME, path: '/' },
+ ...breadcrumbs,
+ ]);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx
index 9fa508d599425..a1bc17e05dc05 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx
@@ -6,8 +6,8 @@
import React from 'react';
import { EuiPage, EuiPageBody, EuiPageContent } from '@elastic/eui';
-import { i18n } from '@kbn/i18n';
+import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants';
import { ErrorStatePrompt } from '../../../shared/error_state';
import { SetWorkplaceSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs';
import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
@@ -20,11 +20,7 @@ export const ErrorState: React.FC = () => {
-
+
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx
index 5b5d067d23eb8..e96d114c67c5d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx
@@ -9,8 +9,8 @@ import { EuiSpacer, EuiTitle, EuiText, EuiButton } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
+import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants';
import { SetupGuide as SetupGuideLayout } from '../../../shared/setup_guide';
-
import { SetWorkplaceSearchBreadcrumbs as SetBreadcrumbs } from '../../../shared/kibana_breadcrumbs';
import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
import GettingStarted from '../../assets/getting_started.png';
@@ -21,14 +21,16 @@ const GETTING_STARTED_LINK_URL =
export const SetupGuide: React.FC = () => {
return (
-
+
diff --git a/x-pack/plugins/enterprise_search/public/plugin.ts b/x-pack/plugins/enterprise_search/public/plugin.ts
index fc95828a3f4a4..66d2ae82fe3ce 100644
--- a/x-pack/plugins/enterprise_search/public/plugin.ts
+++ b/x-pack/plugins/enterprise_search/public/plugin.ts
@@ -20,6 +20,7 @@ import {
import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public';
import { LicensingPluginSetup } from '../../licensing/public';
+import { APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN } from '../common/constants';
import { getPublicUrl } from './applications/shared/enterprise_search_url';
import AppSearchLogo from './applications/app_search/assets/logo.svg';
import WorkplaceSearchLogo from './applications/workplace_search/assets/logo.svg';
@@ -44,9 +45,9 @@ export class EnterpriseSearchPlugin implements Plugin {
const config = { host: this.config.host };
core.application.register({
- id: 'appSearch',
- title: 'App Search',
- appRoute: '/app/enterprise_search/app_search',
+ id: APP_SEARCH_PLUGIN.ID,
+ title: APP_SEARCH_PLUGIN.NAME,
+ appRoute: APP_SEARCH_PLUGIN.URL,
category: DEFAULT_APP_CATEGORIES.enterpriseSearch,
mount: async (params: AppMountParameters) => {
const [coreStart] = await core.getStartServices();
@@ -61,9 +62,9 @@ export class EnterpriseSearchPlugin implements Plugin {
});
core.application.register({
- id: 'workplaceSearch',
- title: 'Workplace Search',
- appRoute: '/app/enterprise_search/workplace_search',
+ id: WORKPLACE_SEARCH_PLUGIN.ID,
+ title: WORKPLACE_SEARCH_PLUGIN.NAME,
+ appRoute: WORKPLACE_SEARCH_PLUGIN.URL,
category: DEFAULT_APP_CATEGORIES.enterpriseSearch,
mount: async (params: AppMountParameters) => {
const [coreStart] = await core.getStartServices();
@@ -76,23 +77,21 @@ export class EnterpriseSearchPlugin implements Plugin {
});
plugins.home.featureCatalogue.register({
- id: 'appSearch',
- title: 'App Search',
+ id: APP_SEARCH_PLUGIN.ID,
+ title: APP_SEARCH_PLUGIN.NAME,
icon: AppSearchLogo,
- description:
- 'Leverage dashboards, analytics, and APIs for advanced application search made simple.',
- path: '/app/enterprise_search/app_search',
+ description: APP_SEARCH_PLUGIN.DESCRIPTION,
+ path: APP_SEARCH_PLUGIN.URL,
category: FeatureCatalogueCategory.DATA,
showOnHomePage: true,
});
plugins.home.featureCatalogue.register({
- id: 'workplaceSearch',
- title: 'Workplace Search',
+ id: WORKPLACE_SEARCH_PLUGIN.ID,
+ title: WORKPLACE_SEARCH_PLUGIN.NAME,
icon: WorkplaceSearchLogo,
- description:
- 'Search all documents, files, and sources available across your virtual workplace.',
- path: '/app/enterprise_search/workplace_search',
+ description: WORKPLACE_SEARCH_PLUGIN.DESCRIPTION,
+ path: WORKPLACE_SEARCH_PLUGIN.URL,
category: FeatureCatalogueCategory.DATA,
showOnHomePage: true,
});
diff --git a/x-pack/plugins/enterprise_search/server/plugin.ts b/x-pack/plugins/enterprise_search/server/plugin.ts
index a7bd68f92f78b..6de6671337797 100644
--- a/x-pack/plugins/enterprise_search/server/plugin.ts
+++ b/x-pack/plugins/enterprise_search/server/plugin.ts
@@ -19,6 +19,11 @@ import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { SecurityPluginSetup } from '../../security/server';
import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server';
+import {
+ ENTERPRISE_SEARCH_PLUGIN,
+ APP_SEARCH_PLUGIN,
+ WORKPLACE_SEARCH_PLUGIN,
+} from '../common/constants';
import { ConfigType } from './';
import { checkAccess } from './lib/check_access';
import { registerPublicUrlRoute } from './routes/enterprise_search/public_url';
@@ -64,13 +69,13 @@ export class EnterpriseSearchPlugin implements Plugin {
* Register space/feature control
*/
features.registerFeature({
- id: 'enterpriseSearch',
- name: 'Enterprise Search',
+ id: ENTERPRISE_SEARCH_PLUGIN.ID,
+ name: ENTERPRISE_SEARCH_PLUGIN.NAME,
order: 0,
icon: 'logoEnterpriseSearch',
- navLinkId: 'appSearch', // TODO - remove this once functional tests no longer rely on navLinkId
- app: ['kibana', 'appSearch', 'workplaceSearch'], // TODO: 'enterpriseSearch'
- catalogue: ['appSearch', 'workplaceSearch'], // TODO: 'enterpriseSearch'
+ navLinkId: APP_SEARCH_PLUGIN.ID, // TODO - remove this once functional tests no longer rely on navLinkId
+ app: ['kibana', APP_SEARCH_PLUGIN.ID, WORKPLACE_SEARCH_PLUGIN.ID],
+ catalogue: [APP_SEARCH_PLUGIN.ID, WORKPLACE_SEARCH_PLUGIN.ID],
privileges: null,
});
diff --git a/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.test.ts b/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.test.ts
new file mode 100644
index 0000000000000..8be34b4498c3f
--- /dev/null
+++ b/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.test.ts
@@ -0,0 +1,70 @@
+/*
+ * 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 { omit } from 'lodash';
+import { mapToUrlState } from './with_metrics_explorer_options_url_state';
+
+describe('WithMetricsExplorerOptionsUrlState', () => {
+ describe('mapToUrlState', () => {
+ it('loads a valid URL state', () => {
+ expect(mapToUrlState(validState)).toEqual(validState);
+ });
+ it('discards invalid properties and loads valid properties into the URL', () => {
+ expect(mapToUrlState(invalidState)).toEqual(omit(invalidState, 'options'));
+ });
+ });
+});
+
+const validState = {
+ chartOptions: {
+ stack: false,
+ type: 'line',
+ yAxisMode: 'fromZero',
+ },
+ options: {
+ aggregation: 'avg',
+ filterQuery: '',
+ groupBy: ['host.hostname'],
+ metrics: [
+ {
+ aggregation: 'avg',
+ color: 'color0',
+ field: 'system.cpu.user.pct',
+ },
+ {
+ aggregation: 'avg',
+ color: 'color1',
+ field: 'system.load.1',
+ },
+ ],
+ source: 'url',
+ },
+ timerange: {
+ from: 'now-1h',
+ interval: '>=10s',
+ to: 'now',
+ },
+};
+
+const invalidState = {
+ chartOptions: {
+ stack: false,
+ type: 'line',
+ yAxisMode: 'fromZero',
+ },
+ options: {
+ aggregation: 'avg',
+ filterQuery: '',
+ groupBy: ['host.hostname'],
+ metrics: 'this is the wrong data type',
+ source: 'url',
+ },
+ timerange: {
+ from: 'now-1h',
+ interval: '>=10s',
+ to: 'now',
+ },
+};
diff --git a/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx b/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx
index 35fb66b2620d6..c263d0f68a45e 100644
--- a/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx
+++ b/x-pack/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx
@@ -5,19 +5,17 @@
*/
import { set } from '@elastic/safer-lodash-set';
-import { values } from 'lodash';
import React, { useContext, useMemo } from 'react';
-import * as t from 'io-ts';
import { ThrowReporter } from 'io-ts/lib/ThrowReporter';
-import { MetricsExplorerColor } from '../../../common/color_palette';
import { UrlStateContainer } from '../../utils/url_state';
import {
MetricsExplorerOptions,
MetricsExplorerOptionsContainer,
MetricsExplorerTimeOptions,
- MetricsExplorerYAxisMode,
- MetricsExplorerChartType,
MetricsExplorerChartOptions,
+ metricExplorerOptionsRT,
+ metricsExplorerChartOptionsRT,
+ metricsExplorerTimeOptionsRT,
} from '../../pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options';
interface MetricsExplorerUrlState {
@@ -74,36 +72,7 @@ export const WithMetricsExplorerOptionsUrlState = () => {
};
function isMetricExplorerOptions(subject: any): subject is MetricsExplorerOptions {
- const MetricRequired = t.type({
- aggregation: t.string,
- });
-
- const MetricOptional = t.partial({
- field: t.string,
- rate: t.boolean,
- color: t.keyof(
- Object.fromEntries(values(MetricsExplorerColor).map((c) => [c, null])) as Record
- ),
- label: t.string,
- });
-
- const Metric = t.intersection([MetricRequired, MetricOptional]);
-
- const OptionsRequired = t.type({
- aggregation: t.string,
- metrics: t.array(Metric),
- });
-
- const OptionsOptional = t.partial({
- limit: t.number,
- groupBy: t.string,
- filterQuery: t.string,
- source: t.string,
- });
-
- const Options = t.intersection([OptionsRequired, OptionsOptional]);
-
- const result = Options.decode(subject);
+ const result = metricExplorerOptionsRT.decode(subject);
try {
ThrowReporter.report(result);
@@ -114,22 +83,7 @@ function isMetricExplorerOptions(subject: any): subject is MetricsExplorerOption
}
function isMetricExplorerChartOptions(subject: any): subject is MetricsExplorerChartOptions {
- const ChartOptions = t.type({
- yAxisMode: t.keyof(
- Object.fromEntries(values(MetricsExplorerYAxisMode).map((v) => [v, null])) as Record<
- string,
- null
- >
- ),
- type: t.keyof(
- Object.fromEntries(values(MetricsExplorerChartType).map((v) => [v, null])) as Record<
- string,
- null
- >
- ),
- stack: t.boolean,
- });
- const result = ChartOptions.decode(subject);
+ const result = metricsExplorerChartOptionsRT.decode(subject);
try {
ThrowReporter.report(result);
@@ -140,12 +94,7 @@ function isMetricExplorerChartOptions(subject: any): subject is MetricsExplorerC
}
function isMetricExplorerTimeOption(subject: any): subject is MetricsExplorerTimeOptions {
- const TimeRange = t.type({
- from: t.string,
- to: t.string,
- interval: t.string,
- });
- const result = TimeRange.decode(subject);
+ const result = metricsExplorerTimeOptionsRT.decode(subject);
try {
ThrowReporter.report(result);
return true;
@@ -154,7 +103,7 @@ function isMetricExplorerTimeOption(subject: any): subject is MetricsExplorerTim
}
}
-const mapToUrlState = (value: any): MetricsExplorerUrlState | undefined => {
+export const mapToUrlState = (value: any): MetricsExplorerUrlState | undefined => {
const finalState = {};
if (value) {
if (value.options && isMetricExplorerOptions(value.options)) {
diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts
index fa103ce15e3e8..299231f1821f0 100644
--- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts
+++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options.ts
@@ -4,19 +4,29 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import * as t from 'io-ts';
+import { values } from 'lodash';
import createContainer from 'constate';
import { useState, useEffect, useMemo, Dispatch, SetStateAction } from 'react';
import { useAlertPrefillContext } from '../../../../alerting/use_alert_prefill';
import { MetricsExplorerColor } from '../../../../../common/color_palette';
-import {
- MetricsExplorerAggregation,
- MetricsExplorerMetric,
-} from '../../../../../common/http_api/metrics_explorer';
-
-export type MetricsExplorerOptionsMetric = MetricsExplorerMetric & {
- color?: MetricsExplorerColor;
- label?: string;
-};
+import { metricsExplorerMetricRT } from '../../../../../common/http_api/metrics_explorer';
+
+const metricsExplorerOptionsMetricRT = t.intersection([
+ metricsExplorerMetricRT,
+ t.partial({
+ rate: t.boolean,
+ color: t.keyof(
+ Object.fromEntries(values(MetricsExplorerColor).map((c) => [c, null])) as Record<
+ MetricsExplorerColor,
+ null
+ >
+ ),
+ label: t.string,
+ }),
+]);
+
+export type MetricsExplorerOptionsMetric = t.TypeOf;
export enum MetricsExplorerChartType {
line = 'line',
@@ -29,28 +39,50 @@ export enum MetricsExplorerYAxisMode {
auto = 'auto',
}
-export interface MetricsExplorerChartOptions {
- type: MetricsExplorerChartType;
- yAxisMode: MetricsExplorerYAxisMode;
- stack: boolean;
-}
-
-export interface MetricsExplorerOptions {
- metrics: MetricsExplorerOptionsMetric[];
- limit?: number;
- groupBy?: string | string[];
- filterQuery?: string;
- aggregation: MetricsExplorerAggregation;
- forceInterval?: boolean;
- dropLastBucket?: boolean;
- source?: string;
-}
-
-export interface MetricsExplorerTimeOptions {
- from: string;
- to: string;
- interval: string;
-}
+export const metricsExplorerChartOptionsRT = t.type({
+ yAxisMode: t.keyof(
+ Object.fromEntries(values(MetricsExplorerYAxisMode).map((v) => [v, null])) as Record<
+ MetricsExplorerYAxisMode,
+ null
+ >
+ ),
+ type: t.keyof(
+ Object.fromEntries(values(MetricsExplorerChartType).map((v) => [v, null])) as Record<
+ MetricsExplorerChartType,
+ null
+ >
+ ),
+ stack: t.boolean,
+});
+
+export type MetricsExplorerChartOptions = t.TypeOf;
+
+const metricExplorerOptionsRequiredRT = t.type({
+ aggregation: t.string,
+ metrics: t.array(metricsExplorerOptionsMetricRT),
+});
+
+const metricExplorerOptionsOptionalRT = t.partial({
+ limit: t.number,
+ groupBy: t.union([t.string, t.array(t.string)]),
+ filterQuery: t.string,
+ source: t.string,
+ forceInterval: t.boolean,
+ dropLastBucket: t.boolean,
+});
+export const metricExplorerOptionsRT = t.intersection([
+ metricExplorerOptionsRequiredRT,
+ metricExplorerOptionsOptionalRT,
+]);
+
+export type MetricsExplorerOptions = t.TypeOf;
+
+export const metricsExplorerTimeOptionsRT = t.type({
+ from: t.string,
+ to: t.string,
+ interval: t.string,
+});
+export type MetricsExplorerTimeOptions = t.TypeOf;
export const DEFAULT_TIMERANGE: MetricsExplorerTimeOptions = {
from: 'now-1h',
diff --git a/x-pack/plugins/ingest_manager/common/constants/agent_config.ts b/x-pack/plugins/ingest_manager/common/constants/agent_config.ts
index 30ca92f5f32f3..aa6399b73f14e 100644
--- a/x-pack/plugins/ingest_manager/common/constants/agent_config.ts
+++ b/x-pack/plugins/ingest_manager/common/constants/agent_config.ts
@@ -5,7 +5,7 @@
*/
import { AgentConfigStatus, DefaultPackages } from '../types';
-export const AGENT_CONFIG_SAVED_OBJECT_TYPE = 'ingest-agent-configs';
+export const AGENT_CONFIG_SAVED_OBJECT_TYPE = 'ingest-agent-policies';
export const DEFAULT_AGENT_CONFIG = {
name: 'Default config',
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx
index 8ea236b2dd6c3..9efc95b0a04cf 100644
--- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx
+++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx
@@ -36,8 +36,8 @@ export const ManualInstructions: React.FunctionComponent = ({
systemctl enable elastic-agent
systemctl start elastic-agent`;
- const windowsCommand = `.\elastic-agent enroll ${enrollArgs}
-./install-service-elastic-agent.ps1`;
+ const windowsCommand = `.\\elastic-agent enroll ${enrollArgs}
+.\\install-service-elastic-agent.ps1`;
return (
<>
diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx
index 7b5c714c236b3..90e24f6da5d0a 100644
--- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx
+++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx
@@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
import {
Direction,
- EuiButtonEmpty,
+ EuiButton,
EuiCallOut,
EuiEmptyPrompt,
EuiFlexGroup,
@@ -147,25 +147,29 @@ export const DataFrameAnalyticsList: FC = ({
return (
<>
{i18n.translate('xpack.ml.dataFrame.analyticsList.emptyPromptTitle', {
- defaultMessage: 'No data frame analytics jobs found',
+ defaultMessage: 'Create your first data frame analytics job',
})}
}
actions={
!isManagementTable
? [
- setIsSourceIndexModalVisible(true)}
isDisabled={disabled}
+ color="primary"
+ iconType="plusInCircle"
+ fill
data-test-subj="mlAnalyticsCreateFirstButton"
>
{i18n.translate('xpack.ml.dataFrame.analyticsList.emptyPromptButtonText', {
- defaultMessage: 'Create your first data frame analytics job',
+ defaultMessage: 'Create job',
})}
- ,
+ ,
]
: []
}
diff --git a/x-pack/plugins/task_manager/server/task_events.ts b/x-pack/plugins/task_manager/server/task_events.ts
index b17a3636c1730..e1dd85f868cdd 100644
--- a/x-pack/plugins/task_manager/server/task_events.ts
+++ b/x-pack/plugins/task_manager/server/task_events.ts
@@ -4,6 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { Option } from 'fp-ts/lib/Option';
+
import { ConcreteTaskInstance } from './task';
import { Result, Err } from './lib/result_type';
@@ -22,7 +24,7 @@ export interface TaskEvent {
}
export type TaskMarkRunning = TaskEvent;
export type TaskRun = TaskEvent;
-export type TaskClaim = TaskEvent;
+export type TaskClaim = TaskEvent>;
export type TaskRunRequest = TaskEvent;
export function asTaskMarkRunningEvent(
@@ -46,7 +48,7 @@ export function asTaskRunEvent(id: string, event: Result
+ event: Result>
): TaskClaim {
return {
id,
diff --git a/x-pack/plugins/task_manager/server/task_manager.test.ts b/x-pack/plugins/task_manager/server/task_manager.test.ts
index 80215ffa7abba..7035971ad6061 100644
--- a/x-pack/plugins/task_manager/server/task_manager.test.ts
+++ b/x-pack/plugins/task_manager/server/task_manager.test.ts
@@ -7,6 +7,7 @@
import _ from 'lodash';
import sinon from 'sinon';
import { Subject } from 'rxjs';
+import { none } from 'fp-ts/lib/Option';
import {
asTaskMarkRunningEvent,
@@ -297,7 +298,9 @@ describe('TaskManager', () => {
events$.next(asTaskMarkRunningEvent(id, asOk(task)));
events$.next(asTaskRunEvent(id, asErr(new Error('some thing gone wrong'))));
- return expect(result).rejects.toEqual(new Error('some thing gone wrong'));
+ return expect(result).rejects.toMatchInlineSnapshot(
+ `[Error: Failed to run task "01ddff11-e88a-4d13-bc4e-256164e755e2": Error: some thing gone wrong]`
+ );
});
test('rejects when the task mark as running fails', () => {
@@ -311,7 +314,9 @@ describe('TaskManager', () => {
events$.next(asTaskClaimEvent(id, asOk(task)));
events$.next(asTaskMarkRunningEvent(id, asErr(new Error('some thing gone wrong'))));
- return expect(result).rejects.toEqual(new Error('some thing gone wrong'));
+ return expect(result).rejects.toMatchInlineSnapshot(
+ `[Error: Failed to run task "01ddff11-e88a-4d13-bc4e-256164e755e2": Error: some thing gone wrong]`
+ );
});
test('when a task claim fails we ensure the task exists', async () => {
@@ -321,7 +326,7 @@ describe('TaskManager', () => {
const result = awaitTaskRunResult(id, events$, getLifecycle);
- events$.next(asTaskClaimEvent(id, asErr(new Error('failed to claim'))));
+ events$.next(asTaskClaimEvent(id, asErr(none)));
await expect(result).rejects.toEqual(
new Error(`Failed to run task "${id}" as it does not exist`)
@@ -337,7 +342,7 @@ describe('TaskManager', () => {
const result = awaitTaskRunResult(id, events$, getLifecycle);
- events$.next(asTaskClaimEvent(id, asErr(new Error('failed to claim'))));
+ events$.next(asTaskClaimEvent(id, asErr(none)));
await expect(result).rejects.toEqual(
new Error(`Failed to run task "${id}" as it is currently running`)
@@ -353,7 +358,7 @@ describe('TaskManager', () => {
const result = awaitTaskRunResult(id, events$, getLifecycle);
- events$.next(asTaskClaimEvent(id, asErr(new Error('failed to claim'))));
+ events$.next(asTaskClaimEvent(id, asErr(none)));
await expect(result).rejects.toEqual(
new Error(`Failed to run task "${id}" as it is currently running`)
@@ -386,9 +391,11 @@ describe('TaskManager', () => {
const result = awaitTaskRunResult(id, events$, getLifecycle);
- events$.next(asTaskClaimEvent(id, asErr(new Error('failed to claim'))));
+ events$.next(asTaskClaimEvent(id, asErr(none)));
- await expect(result).rejects.toEqual(new Error('failed to claim'));
+ await expect(result).rejects.toMatchInlineSnapshot(
+ `[Error: Failed to run task "01ddff11-e88a-4d13-bc4e-256164e755e2" for unknown reason (Current Task Lifecycle is "idle")]`
+ );
expect(getLifecycle).toHaveBeenCalledWith(id);
});
@@ -400,9 +407,11 @@ describe('TaskManager', () => {
const result = awaitTaskRunResult(id, events$, getLifecycle);
- events$.next(asTaskClaimEvent(id, asErr(new Error('failed to claim'))));
+ events$.next(asTaskClaimEvent(id, asErr(none)));
- await expect(result).rejects.toEqual(new Error('failed to claim'));
+ await expect(result).rejects.toMatchInlineSnapshot(
+ `[Error: Failed to run task "01ddff11-e88a-4d13-bc4e-256164e755e2" for unknown reason (Current Task Lifecycle is "failed")]`
+ );
expect(getLifecycle).toHaveBeenCalledWith(id);
});
@@ -424,7 +433,9 @@ describe('TaskManager', () => {
events$.next(asTaskRunEvent(id, asErr(new Error('some thing gone wrong'))));
- return expect(result).rejects.toEqual(new Error('some thing gone wrong'));
+ return expect(result).rejects.toMatchInlineSnapshot(
+ `[Error: Failed to run task "01ddff11-e88a-4d13-bc4e-256164e755e2": Error: some thing gone wrong]`
+ );
});
});
});
diff --git a/x-pack/plugins/task_manager/server/task_manager.ts b/x-pack/plugins/task_manager/server/task_manager.ts
index 35ca439bb9130..7165fd28678c1 100644
--- a/x-pack/plugins/task_manager/server/task_manager.ts
+++ b/x-pack/plugins/task_manager/server/task_manager.ts
@@ -9,13 +9,14 @@ import { filter } from 'rxjs/operators';
import { performance } from 'perf_hooks';
import { pipe } from 'fp-ts/lib/pipeable';
-import { Option, some, map as mapOptional } from 'fp-ts/lib/Option';
+import { Option, some, map as mapOptional, getOrElse } from 'fp-ts/lib/Option';
+
import {
SavedObjectsSerializer,
ILegacyScopedClusterClient,
ISavedObjectsRepository,
} from '../../../../src/core/server';
-import { Result, asErr, either, map, mapErr, promiseResult } from './lib/result_type';
+import { Result, asOk, asErr, either, map, mapErr, promiseResult } from './lib/result_type';
import { TaskManagerConfig } from './config';
import { Logger } from './types';
@@ -405,7 +406,9 @@ export async function claimAvailableTasks(
if (docs.length !== claimedTasks) {
logger.warn(
- `[Task Ownership error]: (${claimedTasks}) tasks were claimed by Kibana, but (${docs.length}) tasks were fetched`
+ `[Task Ownership error]: ${claimedTasks} tasks were claimed by Kibana, but ${
+ docs.length
+ } task(s) were fetched (${docs.map((doc) => doc.id).join(', ')})`
);
}
return docs;
@@ -437,48 +440,65 @@ export async function awaitTaskRunResult(
// listen for all events related to the current task
.pipe(filter(({ id }: TaskLifecycleEvent) => id === taskId))
.subscribe((taskEvent: TaskLifecycleEvent) => {
- either(
- taskEvent.event,
- (taskInstance: ConcreteTaskInstance) => {
- // resolve if the task has run sucessfully
- if (isTaskRunEvent(taskEvent)) {
- subscription.unsubscribe();
- resolve({ id: taskInstance.id });
- }
- },
- async (error: Error) => {
+ if (isTaskClaimEvent(taskEvent)) {
+ mapErr(async (error: Option) => {
// reject if any error event takes place for the requested task
subscription.unsubscribe();
- if (isTaskRunRequestEvent(taskEvent)) {
- return reject(
- new Error(
- `Failed to run task "${taskId}" as Task Manager is at capacity, please try again later`
- )
- );
- } else if (isTaskClaimEvent(taskEvent)) {
- reject(
- map(
- // if the error happened in the Claim phase - we try to provide better insight
- // into why we failed to claim by getting the task's current lifecycle status
- await promiseResult(getLifecycle(taskId)),
- (taskLifecycleStatus: TaskLifecycle) => {
- if (taskLifecycleStatus === TaskLifecycleResult.NotFound) {
- return new Error(`Failed to run task "${taskId}" as it does not exist`);
- } else if (
- taskLifecycleStatus === TaskStatus.Running ||
- taskLifecycleStatus === TaskStatus.Claiming
- ) {
- return new Error(`Failed to run task "${taskId}" as it is currently running`);
- }
- return error;
- },
- () => error
- )
- );
+ return reject(
+ map(
+ await pipe(
+ error,
+ mapOptional(async (taskReturnedBySweep) => asOk(taskReturnedBySweep.status)),
+ getOrElse(() =>
+ // if the error happened in the Claim phase - we try to provide better insight
+ // into why we failed to claim by getting the task's current lifecycle status
+ promiseResult(getLifecycle(taskId))
+ )
+ ),
+ (taskLifecycleStatus: TaskLifecycle) => {
+ if (taskLifecycleStatus === TaskLifecycleResult.NotFound) {
+ return new Error(`Failed to run task "${taskId}" as it does not exist`);
+ } else if (
+ taskLifecycleStatus === TaskStatus.Running ||
+ taskLifecycleStatus === TaskStatus.Claiming
+ ) {
+ return new Error(`Failed to run task "${taskId}" as it is currently running`);
+ }
+ return new Error(
+ `Failed to run task "${taskId}" for unknown reason (Current Task Lifecycle is "${taskLifecycleStatus}")`
+ );
+ },
+ (getLifecycleError: Error) =>
+ new Error(
+ `Failed to run task "${taskId}" and failed to get current Status:${getLifecycleError}`
+ )
+ )
+ );
+ }, taskEvent.event);
+ } else {
+ either>(
+ taskEvent.event,
+ (taskInstance: ConcreteTaskInstance) => {
+ // resolve if the task has run sucessfully
+ if (isTaskRunEvent(taskEvent)) {
+ subscription.unsubscribe();
+ resolve({ id: taskInstance.id });
+ }
+ },
+ async (error: Error | Option) => {
+ // reject if any error event takes place for the requested task
+ subscription.unsubscribe();
+ if (isTaskRunRequestEvent(taskEvent)) {
+ return reject(
+ new Error(
+ `Failed to run task "${taskId}" as Task Manager is at capacity, please try again later`
+ )
+ );
+ }
+ return reject(new Error(`Failed to run task "${taskId}": ${error}`));
}
- return reject(error);
- }
- );
+ );
+ }
});
});
}
diff --git a/x-pack/plugins/task_manager/server/task_store.test.ts b/x-pack/plugins/task_manager/server/task_store.test.ts
index 771b4e2d7d9cb..d65c39f4f454d 100644
--- a/x-pack/plugins/task_manager/server/task_store.test.ts
+++ b/x-pack/plugins/task_manager/server/task_store.test.ts
@@ -8,6 +8,7 @@ import _ from 'lodash';
import sinon from 'sinon';
import uuid from 'uuid';
import { filter } from 'rxjs/operators';
+import { Option, some, none } from 'fp-ts/lib/Option';
import {
TaskDictionary,
@@ -972,7 +973,7 @@ if (doc['task.runAt'].size()!=0) {
const runAt = new Date();
const tasks = [
{
- _id: 'aaa',
+ _id: 'claimed-by-id',
_source: {
type: 'task',
task: {
@@ -980,7 +981,7 @@ if (doc['task.runAt'].size()!=0) {
taskType: 'foo',
schedule: undefined,
attempts: 0,
- status: 'idle',
+ status: 'claiming',
params: '{ "hello": "world" }',
state: '{ "baby": "Henhen" }',
user: 'jimbo',
@@ -996,7 +997,31 @@ if (doc['task.runAt'].size()!=0) {
sort: ['a', 1],
},
{
- _id: 'bbb',
+ _id: 'claimed-by-schedule',
+ _source: {
+ type: 'task',
+ task: {
+ runAt,
+ taskType: 'bar',
+ schedule: { interval: '5m' },
+ attempts: 2,
+ status: 'claiming',
+ params: '{ "shazm": 1 }',
+ state: '{ "henry": "The 8th" }',
+ user: 'dabo',
+ scope: ['reporting', 'ceo'],
+ ownerId: taskManagerId,
+ startedAt: null,
+ retryAt: null,
+ scheduledAt: new Date(),
+ },
+ },
+ _seq_no: 3,
+ _primary_term: 4,
+ sort: ['b', 2],
+ },
+ {
+ _id: 'already-running',
_source: {
type: 'task',
task: {
@@ -1045,19 +1070,24 @@ if (doc['task.runAt'].size()!=0) {
});
const sub = store.events
- .pipe(filter((event: TaskEvent) => event.id === 'aaa'))
+ .pipe(
+ filter(
+ (event: TaskEvent>) =>
+ event.id === 'claimed-by-id'
+ )
+ )
.subscribe({
- next: (event: TaskEvent) => {
+ next: (event: TaskEvent>) => {
expect(event).toMatchObject(
asTaskClaimEvent(
- 'aaa',
+ 'claimed-by-id',
asOk({
- id: 'aaa',
+ id: 'claimed-by-id',
runAt,
taskType: 'foo',
schedule: undefined,
attempts: 0,
- status: 'idle' as TaskStatus,
+ status: 'claiming' as TaskStatus,
params: { hello: 'world' },
state: { baby: 'Henhen' },
user: 'jimbo',
@@ -1075,7 +1105,7 @@ if (doc['task.runAt'].size()!=0) {
});
await store.claimAvailableTasks({
- claimTasksById: ['aaa'],
+ claimTasksById: ['claimed-by-id'],
claimOwnershipUntil: new Date(),
size: 10,
});
@@ -1102,19 +1132,24 @@ if (doc['task.runAt'].size()!=0) {
});
const sub = store.events
- .pipe(filter((event: TaskEvent) => event.id === 'bbb'))
+ .pipe(
+ filter(
+ (event: TaskEvent>) =>
+ event.id === 'claimed-by-schedule'
+ )
+ )
.subscribe({
- next: (event: TaskEvent) => {
+ next: (event: TaskEvent>) => {
expect(event).toMatchObject(
asTaskClaimEvent(
- 'bbb',
+ 'claimed-by-schedule',
asOk({
- id: 'bbb',
+ id: 'claimed-by-schedule',
runAt,
taskType: 'bar',
schedule: { interval: '5m' },
attempts: 2,
- status: 'running' as TaskStatus,
+ status: 'claiming' as TaskStatus,
params: { shazm: 1 },
state: { henry: 'The 8th' },
user: 'dabo',
@@ -1132,14 +1167,14 @@ if (doc['task.runAt'].size()!=0) {
});
await store.claimAvailableTasks({
- claimTasksById: ['aaa'],
+ claimTasksById: ['claimed-by-id'],
claimOwnershipUntil: new Date(),
size: 10,
});
});
test('emits an event when the store fails to claim a required task by id', async (done) => {
- const { taskManagerId, tasks } = generateTasks();
+ const { taskManagerId, runAt, tasks } = generateTasks();
const callCluster = sinon.spy(async (name: string, params?: unknown) =>
name === 'updateByQuery'
? {
@@ -1159,11 +1194,36 @@ if (doc['task.runAt'].size()!=0) {
});
const sub = store.events
- .pipe(filter((event: TaskEvent) => event.id === 'ccc'))
+ .pipe(
+ filter(
+ (event: TaskEvent>) =>
+ event.id === 'already-running'
+ )
+ )
.subscribe({
- next: (event: TaskEvent) => {
+ next: (event: TaskEvent>) => {
expect(event).toMatchObject(
- asTaskClaimEvent('ccc', asErr(new Error(`failed to claim task 'ccc'`)))
+ asTaskClaimEvent(
+ 'already-running',
+ asErr(
+ some({
+ id: 'already-running',
+ runAt,
+ taskType: 'bar',
+ schedule: { interval: '5m' },
+ attempts: 2,
+ status: 'running' as TaskStatus,
+ params: { shazm: 1 },
+ state: { henry: 'The 8th' },
+ user: 'dabo',
+ scope: ['reporting', 'ceo'],
+ ownerId: taskManagerId,
+ startedAt: null,
+ retryAt: null,
+ scheduledAt: new Date(),
+ })
+ )
+ )
);
sub.unsubscribe();
done();
@@ -1171,7 +1231,49 @@ if (doc['task.runAt'].size()!=0) {
});
await store.claimAvailableTasks({
- claimTasksById: ['ccc'],
+ claimTasksById: ['already-running'],
+ claimOwnershipUntil: new Date(),
+ size: 10,
+ });
+ });
+
+ test('emits an event when the store fails to find a task which was required by id', async (done) => {
+ const { taskManagerId, tasks } = generateTasks();
+ const callCluster = sinon.spy(async (name: string, params?: unknown) =>
+ name === 'updateByQuery'
+ ? {
+ total: tasks.length,
+ updated: tasks.length,
+ }
+ : { hits: { hits: tasks } }
+ );
+ const store = new TaskStore({
+ callCluster,
+ maxAttempts: 2,
+ definitions: taskDefinitions,
+ serializer,
+ savedObjectsRepository: savedObjectsClient,
+ taskManagerId,
+ index: '',
+ });
+
+ const sub = store.events
+ .pipe(
+ filter(
+ (event: TaskEvent>) =>
+ event.id === 'unknown-task'
+ )
+ )
+ .subscribe({
+ next: (event: TaskEvent>) => {
+ expect(event).toMatchObject(asTaskClaimEvent('unknown-task', asErr(none)));
+ sub.unsubscribe();
+ done();
+ },
+ });
+
+ await store.claimAvailableTasks({
+ claimTasksById: ['unknown-task'],
claimOwnershipUntil: new Date(),
size: 10,
});
diff --git a/x-pack/plugins/task_manager/server/task_store.ts b/x-pack/plugins/task_manager/server/task_store.ts
index cac37db72202d..a18fb57b35b3d 100644
--- a/x-pack/plugins/task_manager/server/task_store.ts
+++ b/x-pack/plugins/task_manager/server/task_store.ts
@@ -9,7 +9,9 @@
*/
import apm from 'elastic-apm-node';
import { Subject, Observable } from 'rxjs';
-import { omit, difference, defaults } from 'lodash';
+import { omit, difference, partition, map, defaults } from 'lodash';
+
+import { some, none } from 'fp-ts/lib/Option';
import { SearchResponse, UpdateDocumentByQueryResponse } from 'elasticsearch';
import {
@@ -31,6 +33,7 @@ import {
TaskLifecycle,
TaskLifecycleResult,
SerializedConcreteTaskInstance,
+ TaskStatus,
} from './task';
import { TaskClaim, asTaskClaimEvent } from './task_events';
@@ -221,13 +224,35 @@ export class TaskStore {
// emit success/fail events for claimed tasks by id
if (claimTasksById && claimTasksById.length) {
- this.emitEvents(docs.map((doc) => asTaskClaimEvent(doc.id, asOk(doc))));
+ const [documentsReturnedById, documentsClaimedBySchedule] = partition(docs, (doc) =>
+ claimTasksById.includes(doc.id)
+ );
+
+ const [documentsClaimedById, documentsRequestedButNotClaimed] = partition(
+ documentsReturnedById,
+ // we filter the schduled tasks down by status is 'claiming' in the esearch,
+ // but we do not apply this limitation on tasks claimed by ID so that we can
+ // provide more detailed error messages when we fail to claim them
+ (doc) => doc.status === TaskStatus.Claiming
+ );
+
+ const documentsRequestedButNotReturned = difference(
+ claimTasksById,
+ map(documentsReturnedById, 'id')
+ );
+
+ this.emitEvents(
+ [...documentsClaimedById, ...documentsClaimedBySchedule].map((doc) =>
+ asTaskClaimEvent(doc.id, asOk(doc))
+ )
+ );
+
+ this.emitEvents(
+ documentsRequestedButNotClaimed.map((doc) => asTaskClaimEvent(doc.id, asErr(some(doc))))
+ );
this.emitEvents(
- difference(
- claimTasksById,
- docs.map((doc) => doc.id)
- ).map((id) => asTaskClaimEvent(id, asErr(new Error(`failed to claim task '${id}'`))))
+ documentsRequestedButNotReturned.map((id) => asTaskClaimEvent(id, asErr(none)))
);
}
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 998d5f488629b..028d647cefd58 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -4529,7 +4529,6 @@
"visualize.createVisualization.noVisTypeErrorMessage": "有効なビジュアライゼーションタイプを指定してください",
"visualize.editor.createBreadcrumb": "作成",
"visualize.error.title": "ビジュアライゼーションエラー",
- "visualize.experimentalVisInfoText": "このビジュアライゼーションは実験的なものです。フィードバックがありますか?で問題を報告してください。",
"visualize.helpMenu.appName": "可視化",
"visualize.linkedToSearch.unlinkSuccessNotificationText": "保存された検索「{searchTitle}」からリンクが解除されました",
"visualize.listing.betaTitle": "ベータ",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 814bdf8b3d45c..c826953f5418b 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -4530,7 +4530,6 @@
"visualize.createVisualization.noVisTypeErrorMessage": "必须提供有效的可视化类型",
"visualize.editor.createBreadcrumb": "创建",
"visualize.error.title": "可视化错误",
- "visualize.experimentalVisInfoText": "此可视化标记为“实验性”。想反馈?请在以下位置创建问题:",
"visualize.helpMenu.appName": "Visualize",
"visualize.linkedToSearch.unlinkSuccessNotificationText": "已取消与已保存搜索“{searchTitle}”的链接",
"visualize.listing.betaTitle": "公测版",
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
index 2b2897a2181b1..3d55c51e45281 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
@@ -152,6 +152,10 @@ export const AlertsList: React.FunctionComponent = () => {
data: alertsResponse.data,
totalItemCount: alertsResponse.total,
});
+
+ if (!alertsResponse.data?.length && page.index > 0) {
+ setPage({ ...page, index: 0 });
+ }
} catch (e) {
toastNotifications.addDanger({
title: i18n.translate(
@@ -399,18 +403,9 @@ export const AlertsList: React.FunctionComponent = () => {
return (
{
- if (selectedIds.length === 0 || selectedIds.length === deleted.length) {
- const updatedAlerts = alertsState.data.filter(
- (alert) => alert.id && !alertsToDelete.includes(alert.id)
- );
- setAlertsState({
- isLoading: false,
- data: updatedAlerts,
- totalItemCount: alertsState.totalItemCount - deleted.length,
- });
- setSelectedIds([]);
- }
+ onDeleted={async (deleted: string[]) => {
+ loadAlertsData();
+ setSelectedIds([]);
setAlertsToDelete([]);
}}
onErrors={async () => {
diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts
index 18fdd5f9c3ac3..0833dd0425894 100644
--- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts
+++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts
@@ -51,7 +51,8 @@ export class SampleTaskManagerFixturePlugin
.toPromise();
public setup(core: CoreSetup) {
- core.http.createRouter().get(
+ const router = core.http.createRouter();
+ router.get(
{
path: '/api/alerting_tasks/{taskId}',
validate: {
@@ -77,6 +78,23 @@ export class SampleTaskManagerFixturePlugin
}
}
);
+
+ router.get(
+ {
+ path: `/api/ensure_tasks_index_refreshed`,
+ validate: {},
+ },
+ async function (
+ context: RequestHandlerContext,
+ req: KibanaRequest,
+ res: KibanaResponseFactory
+ ): Promise> {
+ await core.elasticsearch.legacy.client.callAsInternalUser('indices.refresh', {
+ index: '.kibana_task_manager',
+ });
+ return res.ok({ body: {} });
+ }
+ );
}
public start(core: CoreStart, { taskManager }: SampleTaskManagerFixtureStartDeps) {
diff --git a/x-pack/test/functional/es_archives/fleet/agents/data.json b/x-pack/test/functional/es_archives/fleet/agents/data.json
index b3d49199b0d9e..c94b87f6ad1ec 100644
--- a/x-pack/test/functional/es_archives/fleet/agents/data.json
+++ b/x-pack/test/functional/es_archives/fleet/agents/data.json
@@ -203,11 +203,11 @@
{
"type": "doc",
"value": {
- "id": "ingest-agent-configs:config1",
+ "id": "ingest-agent-policies:config1",
"index": ".kibana",
"source": {
- "type": "ingest-agent-configs",
- "ingest-agent-configs": {
+ "type": "ingest-agent-policies",
+ "ingest-agent-policies": {
"name": "Test config",
"namespace": "default",
"description": "Config 1",
diff --git a/x-pack/test/functional/es_archives/fleet/agents/mappings.json b/x-pack/test/functional/es_archives/fleet/agents/mappings.json
index 1f0aa2f24d6df..acc32c3e2cbb5 100644
--- a/x-pack/test/functional/es_archives/fleet/agents/mappings.json
+++ b/x-pack/test/functional/es_archives/fleet/agents/mappings.json
@@ -58,7 +58,7 @@
"siem-ui-timeline": "f2d929253ecd06ffbac78b4047f45a86",
"kql-telemetry": "d12a98a6f19a2d273696597547e064ee",
"ui-metric": "0d409297dc5ebe1e3a1da691c6ee32e3",
- "ingest-agent-configs": "f4bdc17427437537ca1754d5d5057ad5",
+ "ingest-agent-policies": "f4bdc17427437537ca1754d5d5057ad5",
"url": "b675c3be8d76ecf029294d51dc7ec65d",
"migrationVersion": "4a1746014a75ade3a714e1db5763276f",
"index-pattern": "66eccb05066c5a89924f48a9e9736499",
@@ -1797,7 +1797,7 @@
}
}
},
- "ingest-agent-configs": {
+ "ingest-agent-policies": {
"properties": {
"package_configs": {
"type": "keyword"
diff --git a/x-pack/test/functional/es_archives/lists/mappings.json b/x-pack/test/functional/es_archives/lists/mappings.json
index c1b277b8183a3..2fc1f1a3111a7 100644
--- a/x-pack/test/functional/es_archives/lists/mappings.json
+++ b/x-pack/test/functional/es_archives/lists/mappings.json
@@ -61,7 +61,7 @@
"siem-ui-timeline": "94bc38c7a421d15fbfe8ea565370a421",
"kql-telemetry": "d12a98a6f19a2d273696597547e064ee",
"ui-metric": "0d409297dc5ebe1e3a1da691c6ee32e3",
- "ingest-agent-configs": "9326f99c977fd2ef5ab24b6336a0675c",
+ "ingest-agent-policies": "9326f99c977fd2ef5ab24b6336a0675c",
"url": "c7f66a0df8b1b52f17c28c4adb111105",
"endpoint:user-artifact-manifest": "67c28185da541c1404e7852d30498cd6",
"migrationVersion": "4a1746014a75ade3a714e1db5763276f",
@@ -1210,7 +1210,7 @@
}
}
},
- "ingest-agent-configs": {
+ "ingest-agent-policies": {
"properties": {
"description": {
"type": "text"
@@ -2488,4 +2488,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json b/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json
index 1432a53b45461..1fd338fbb0ffb 100644
--- a/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json
+++ b/x-pack/test/functional/es_archives/reporting/canvas_disallowed_url/mappings.json
@@ -2,8 +2,7 @@
"type": "index",
"value": {
"aliases": {
- ".kibana": {
- }
+ ".kibana": {}
},
"index": ".kibana_1",
"mappings": {
@@ -38,7 +37,7 @@
"fleet-enrollment-api-keys": "28b91e20b105b6f928e2012600085d8f",
"graph-workspace": "cd7ba1330e6682e9cc00b78850874be1",
"index-pattern": "66eccb05066c5a89924f48a9e9736499",
- "ingest-agent-configs": "9326f99c977fd2ef5ab24b6336a0675c",
+ "ingest-agent-policies": "9326f99c977fd2ef5ab24b6336a0675c",
"ingest-outputs": "8aa988c376e65443fefc26f1075e93a3",
"ingest-package-configs": "48e8bd97e488008e21c0b5a2367b83ad",
"ingest_manager_settings": "012cf278ec84579495110bb827d1ed09",
@@ -1149,7 +1148,7 @@
}
}
},
- "ingest-agent-configs": {
+ "ingest-agent-policies": {
"properties": {
"description": {
"type": "text"
@@ -2213,4 +2212,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts.ts
index fa714e8374ec7..56952919e416a 100644
--- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts.ts
@@ -5,6 +5,7 @@
*/
import uuid from 'uuid';
+import { times } from 'lodash';
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
@@ -361,11 +362,22 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
});
it('should delete all selection', async () => {
- const createdAlert = await createAlert();
+ const namePrefix = generateUniqueKey();
+ let count = 0;
+ const createdAlertsFirstPage = await Promise.all(
+ times(10, () => createAlert({ name: `${namePrefix}-0${count++}` }))
+ );
+
+ const createdAlertsSecondPage = await Promise.all(
+ times(2, () => createAlert({ name: `${namePrefix}-1${count++}` }))
+ );
+
await pageObjects.common.navigateToApp('triggersActions');
- await pageObjects.triggersActionsUI.searchAlerts(createdAlert.name);
+ await pageObjects.triggersActionsUI.searchAlerts(namePrefix);
- await testSubjects.click(`checkboxSelectRow-${createdAlert.id}`);
+ for (const createdAlert of createdAlertsFirstPage) {
+ await testSubjects.click(`checkboxSelectRow-${createdAlert.id}`);
+ }
await testSubjects.click('bulkAction');
@@ -377,9 +389,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await pageObjects.common.closeToast();
await pageObjects.common.navigateToApp('triggersActions');
- await pageObjects.triggersActionsUI.searchAlerts(createdAlert.name);
+ await pageObjects.triggersActionsUI.searchAlerts(namePrefix);
const searchResultsAfterDelete = await pageObjects.triggersActionsUI.getAlertsList();
- expect(searchResultsAfterDelete.length).to.eql(0);
+ expect(searchResultsAfterDelete).to.have.length(2);
+ expect(searchResultsAfterDelete[0].name).to.eql(createdAlertsSecondPage[0].name);
+ expect(searchResultsAfterDelete[1].name).to.eql(createdAlertsSecondPage[1].name);
});
});
};
diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/list.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/list.ts
index 20414fcb90521..0b6a37d77387e 100644
--- a/x-pack/test/ingest_manager_api_integration/apis/epm/list.ts
+++ b/x-pack/test/ingest_manager_api_integration/apis/epm/list.ts
@@ -29,7 +29,7 @@ export default function ({ getService }: FtrProviderContext) {
return response.body;
};
const listResponse = await fetchPackageList();
- expect(listResponse.response.length).to.be(14);
+ expect(listResponse.response.length).to.be(8);
} else {
warnAndSkipTest(this, log);
}
diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/fields/fields.yml
index 12a9a03c1337b..6e003ed0ad147 100644
--- a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/fields/fields.yml
+++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/fields/fields.yml
@@ -1,15 +1,15 @@
-- name: dataset.type
+- name: data_stream.type
type: constant_keyword
description: >
- Dataset type.
-- name: dataset.name
+ Data stream type.
+- name: data_stream.dataset
type: constant_keyword
description: >
- Dataset name.
-- name: dataset.namespace
+ Data stream dataset.
+- name: data_stream.namespace
type: constant_keyword
description: >
- Dataset namespace.
+ Data stream namespace.
- name: '@timestamp'
type: date
description: >
diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_metrics/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_metrics/fields/fields.yml
index 12a9a03c1337b..6e003ed0ad147 100644
--- a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_metrics/fields/fields.yml
+++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_metrics/fields/fields.yml
@@ -1,15 +1,15 @@
-- name: dataset.type
+- name: data_stream.type
type: constant_keyword
description: >
- Dataset type.
-- name: dataset.name
+ Data stream type.
+- name: data_stream.dataset
type: constant_keyword
description: >
- Dataset name.
-- name: dataset.namespace
+ Data stream dataset.
+- name: data_stream.namespace
type: constant_keyword
description: >
- Dataset namespace.
+ Data stream namespace.
- name: '@timestamp'
type: date
description: >
diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.1.0/dataset/test/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.1.0/dataset/test/fields/fields.yml
index 12a9a03c1337b..6e003ed0ad147 100644
--- a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.1.0/dataset/test/fields/fields.yml
+++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.1.0/dataset/test/fields/fields.yml
@@ -1,15 +1,15 @@
-- name: dataset.type
+- name: data_stream.type
type: constant_keyword
description: >
- Dataset type.
-- name: dataset.name
+ Data stream type.
+- name: data_stream.dataset
type: constant_keyword
description: >
- Dataset name.
-- name: dataset.namespace
+ Data stream dataset.
+- name: data_stream.namespace
type: constant_keyword
description: >
- Dataset namespace.
+ Data stream namespace.
- name: '@timestamp'
type: date
description: >
diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.2.0/dataset/test/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.2.0/dataset/test/fields/fields.yml
index 12a9a03c1337b..6e003ed0ad147 100644
--- a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.2.0/dataset/test/fields/fields.yml
+++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.2.0/dataset/test/fields/fields.yml
@@ -1,15 +1,15 @@
-- name: dataset.type
+- name: data_stream.type
type: constant_keyword
description: >
- Dataset type.
-- name: dataset.name
+ Data stream type.
+- name: data_stream.dataset
type: constant_keyword
description: >
- Dataset name.
-- name: dataset.namespace
+ Data stream dataset.
+- name: data_stream.namespace
type: constant_keyword
description: >
- Dataset namespace.
+ Data stream namespace.
- name: '@timestamp'
type: date
description: >
diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.3.0/dataset/test/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.3.0/dataset/test/fields/fields.yml
index 12a9a03c1337b..6e003ed0ad147 100644
--- a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.3.0/dataset/test/fields/fields.yml
+++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/multiple_versions/0.3.0/dataset/test/fields/fields.yml
@@ -1,15 +1,15 @@
-- name: dataset.type
+- name: data_stream.type
type: constant_keyword
description: >
- Dataset type.
-- name: dataset.name
+ Data stream type.
+- name: data_stream.dataset
type: constant_keyword
description: >
- Dataset name.
-- name: dataset.namespace
+ Data stream dataset.
+- name: data_stream.namespace
type: constant_keyword
description: >
- Dataset namespace.
+ Data stream namespace.
- name: '@timestamp'
type: date
description: >
diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/overrides/0.1.0/dataset/test/fields/fields.yml b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/overrides/0.1.0/dataset/test/fields/fields.yml
index 12a9a03c1337b..6e003ed0ad147 100644
--- a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/overrides/0.1.0/dataset/test/fields/fields.yml
+++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/overrides/0.1.0/dataset/test/fields/fields.yml
@@ -1,15 +1,15 @@
-- name: dataset.type
+- name: data_stream.type
type: constant_keyword
description: >
- Dataset type.
-- name: dataset.name
+ Data stream type.
+- name: data_stream.dataset
type: constant_keyword
description: >
- Dataset name.
-- name: dataset.namespace
+ Data stream dataset.
+- name: data_stream.namespace
type: constant_keyword
description: >
- Dataset namespace.
+ Data stream namespace.
- name: '@timestamp'
type: date
description: >
diff --git a/x-pack/test/ingest_manager_api_integration/apis/package_config/create.ts b/x-pack/test/ingest_manager_api_integration/apis/package_config/create.ts
index cae4ff79bdef6..a2c2b99364d50 100644
--- a/x-pack/test/ingest_manager_api_integration/apis/package_config/create.ts
+++ b/x-pack/test/ingest_manager_api_integration/apis/package_config/create.ts
@@ -100,7 +100,7 @@ export default function ({ getService }: FtrProviderContext) {
package: {
name: 'endpoint',
title: 'Endpoint',
- version: '0.8.0',
+ version: '0.13.0',
},
})
.expect(200);
@@ -118,7 +118,7 @@ export default function ({ getService }: FtrProviderContext) {
package: {
name: 'endpoint',
title: 'Endpoint',
- version: '0.8.0',
+ version: '0.13.0',
},
})
.expect(500);
diff --git a/x-pack/test/ingest_manager_api_integration/config.ts b/x-pack/test/ingest_manager_api_integration/config.ts
index 85d1c20c7f155..08d5da148b51e 100644
--- a/x-pack/test/ingest_manager_api_integration/config.ts
+++ b/x-pack/test/ingest_manager_api_integration/config.ts
@@ -12,7 +12,7 @@ import { defineDockerServersConfig } from '@kbn/test';
// Docker image to use for Ingest Manager API integration tests.
// This hash comes from the commit hash here: https://github.com/elastic/package-storage/commit
export const dockerImage =
- 'docker.elastic.co/package-registry/distribution:80e93ade87f65e18d487b1c407406825915daba8';
+ 'docker.elastic.co/package-registry/distribution:f6b01daec8cfe355101e366de9941d35a4c3763e';
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const xPackAPITestsConfig = await readConfigFile(require.resolve('../api_integration/config.ts'));
diff --git a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts
index f35d6baac8f5a..266e66b5a1a45 100644
--- a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts
+++ b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts
@@ -223,6 +223,21 @@ export function initRoutes(
}
);
+ router.get(
+ {
+ path: `/api/ensure_tasks_index_refreshed`,
+ validate: {},
+ },
+ async function (
+ context: RequestHandlerContext,
+ req: KibanaRequest,
+ res: KibanaResponseFactory
+ ): Promise> {
+ await ensureIndexIsRefreshed();
+ return res.ok({ body: {} });
+ }
+ );
+
router.delete(
{
path: `/api/sample_tasks`,
diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js
index 165e79fb311ea..c87a5039360b8 100644
--- a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js
+++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js
@@ -28,8 +28,7 @@ export default function ({ getService }) {
const testHistoryIndex = '.kibana_task_manager_test_result';
const supertest = supertestAsPromised(url.format(config.get('servers.kibana')));
- // FLAKY: https://github.com/elastic/kibana/issues/71390
- 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)
);
@@ -69,6 +68,14 @@ export default function ({ getService }) {
.then((response) => response.body);
}
+ function ensureTasksIndexRefreshed() {
+ return supertest
+ .get(`/api/ensure_tasks_index_refreshed`)
+ .send({})
+ .expect(200)
+ .then((response) => response.body);
+ }
+
function historyDocs(taskId) {
return es
.search({
@@ -404,7 +411,7 @@ export default function ({ getService }) {
const originalTask = await scheduleTask({
taskType: 'sampleTask',
schedule: { interval: `30m` },
- params: { failWith: 'error on run now', failOn: 3 },
+ params: { failWith: 'this task was meant to fail!', failOn: 3 },
});
await retry.try(async () => {
@@ -415,11 +422,14 @@ export default function ({ getService }) {
const task = await currentTask(originalTask.id);
expect(task.state.count).to.eql(1);
+ expect(task.status).to.eql('idle');
// ensure this task shouldnt run for another half hour
expectReschedule(Date.parse(originalTask.runAt), task, 30 * 60000);
});
+ await ensureTasksIndexRefreshed();
+
// second run should still be successful
const successfulRunNowResult = await runTaskNow({
id: originalTask.id,
@@ -429,14 +439,20 @@ export default function ({ getService }) {
await retry.try(async () => {
const task = await currentTask(originalTask.id);
expect(task.state.count).to.eql(2);
+ expect(task.status).to.eql('idle');
});
+ await ensureTasksIndexRefreshed();
+
// third run should fail
const failedRunNowResult = await runTaskNow({
id: originalTask.id,
});
- expect(failedRunNowResult).to.eql({ id: originalTask.id, error: `Error: error on run now` });
+ expect(failedRunNowResult).to.eql({
+ id: originalTask.id,
+ error: `Error: Failed to run task \"${originalTask.id}\": Error: this task was meant to fail!`,
+ });
await retry.try(async () => {
expect(
@@ -479,8 +495,13 @@ export default function ({ getService }) {
expect(
docs.filter((taskDoc) => taskDoc._source.taskId === longRunningTask.id).length
).to.eql(1);
+
+ const task = await currentTask(longRunningTask.id);
+ expect(task.status).to.eql('running');
});
+ await ensureTasksIndexRefreshed();
+
// first runNow should fail
const failedRunNowResult = await runTaskNow({
id: longRunningTask.id,
@@ -496,8 +517,13 @@ export default function ({ getService }) {
await retry.try(async () => {
const tasks = (await currentTasks()).docs;
expect(getTaskById(tasks, longRunningTask.id).state.count).to.eql(1);
+
+ const task = await currentTask(longRunningTask.id);
+ expect(task.status).to.eql('idle');
});
+ await ensureTasksIndexRefreshed();
+
// second runNow should be successful
const successfulRunNowResult = runTaskNow({
id: longRunningTask.id,
diff --git a/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json b/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json
index 2cfa0bde4e977..dc92d23a618d3 100644
--- a/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json
+++ b/x-pack/test/security_solution_cypress/es_archives/export_rule/mappings.json
@@ -39,7 +39,7 @@
"graph-workspace": "cd7ba1330e6682e9cc00b78850874be1",
"index-pattern": "66eccb05066c5a89924f48a9e9736499",
"infrastructure-ui-source": "2b2809653635caf490c93f090502d04c",
- "ingest-agent-configs": "9326f99c977fd2ef5ab24b6336a0675c",
+ "ingest-agent-policies": "9326f99c977fd2ef5ab24b6336a0675c",
"ingest-outputs": "8aa988c376e65443fefc26f1075e93a3",
"ingest-package-configs": "48e8bd97e488008e21c0b5a2367b83ad",
"ingest_manager_settings": "012cf278ec84579495110bb827d1ed09",
@@ -1222,7 +1222,7 @@
}
}
},
- "ingest-agent-configs": {
+ "ingest-agent-policies": {
"properties": {
"description": {
"type": "text"