From b34b9f12c38b99eb1f23675e22fd9f5bd4ab7156 Mon Sep 17 00:00:00 2001 From: achyutjhunjhunwala Date: Fri, 21 Jun 2024 13:27:53 +0200 Subject: [PATCH 01/12] Fix refresh table breaking for summary --- x-pack/test/functional/page_objects/dataset_quality.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x-pack/test/functional/page_objects/dataset_quality.ts b/x-pack/test/functional/page_objects/dataset_quality.ts index d9b274e158536..57d4e43d2d58b 100644 --- a/x-pack/test/functional/page_objects/dataset_quality.ts +++ b/x-pack/test/functional/page_objects/dataset_quality.ts @@ -219,6 +219,10 @@ export function DatasetQualityPageObject({ getPageObjects, getService }: FtrProv }, async refreshTable() { + await testSubjects.waitForEnabled( + testSubjectSelectors.datasetQualityFiltersContainer, + 10 * 1000 + ); const filtersContainer = await testSubjects.find( testSubjectSelectors.datasetQualityFiltersContainer ); From d1fdaebaa8fb5b6dbfaccef41b51f4364daf4444 Mon Sep 17 00:00:00 2001 From: achyutjhunjhunwala Date: Fri, 21 Jun 2024 13:30:45 +0200 Subject: [PATCH 02/12] Add timeout to find --- x-pack/test/functional/page_objects/dataset_quality.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/x-pack/test/functional/page_objects/dataset_quality.ts b/x-pack/test/functional/page_objects/dataset_quality.ts index 57d4e43d2d58b..490118ee7ebec 100644 --- a/x-pack/test/functional/page_objects/dataset_quality.ts +++ b/x-pack/test/functional/page_objects/dataset_quality.ts @@ -219,13 +219,10 @@ export function DatasetQualityPageObject({ getPageObjects, getService }: FtrProv }, async refreshTable() { - await testSubjects.waitForEnabled( + const filtersContainer = await testSubjects.find( testSubjectSelectors.datasetQualityFiltersContainer, 10 * 1000 ); - const filtersContainer = await testSubjects.find( - testSubjectSelectors.datasetQualityFiltersContainer - ); const refreshButton = await filtersContainer.findByTestSubject( testSubjectSelectors.superDatePickerApplyTimeButton ); From db7d63b8387626d559bd14aebd9d000112946c67 Mon Sep 17 00:00:00 2001 From: achyutjhunjhunwala Date: Fri, 21 Jun 2024 13:37:32 +0200 Subject: [PATCH 03/12] Revert "Add timeout to find" This reverts commit d1fdaebaa8fb5b6dbfaccef41b51f4364daf4444. --- x-pack/test/functional/page_objects/dataset_quality.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/page_objects/dataset_quality.ts b/x-pack/test/functional/page_objects/dataset_quality.ts index 490118ee7ebec..57d4e43d2d58b 100644 --- a/x-pack/test/functional/page_objects/dataset_quality.ts +++ b/x-pack/test/functional/page_objects/dataset_quality.ts @@ -219,10 +219,13 @@ export function DatasetQualityPageObject({ getPageObjects, getService }: FtrProv }, async refreshTable() { - const filtersContainer = await testSubjects.find( + await testSubjects.waitForEnabled( testSubjectSelectors.datasetQualityFiltersContainer, 10 * 1000 ); + const filtersContainer = await testSubjects.find( + testSubjectSelectors.datasetQualityFiltersContainer + ); const refreshButton = await filtersContainer.findByTestSubject( testSubjectSelectors.superDatePickerApplyTimeButton ); From c3a2774031af9678857111aa1180476c22862e8c Mon Sep 17 00:00:00 2001 From: achyutjhunjhunwala Date: Fri, 21 Jun 2024 13:37:32 +0200 Subject: [PATCH 04/12] Revert "Fix refresh table breaking for summary" This reverts commit b34b9f12c38b99eb1f23675e22fd9f5bd4ab7156. --- x-pack/test/functional/page_objects/dataset_quality.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/x-pack/test/functional/page_objects/dataset_quality.ts b/x-pack/test/functional/page_objects/dataset_quality.ts index 57d4e43d2d58b..d9b274e158536 100644 --- a/x-pack/test/functional/page_objects/dataset_quality.ts +++ b/x-pack/test/functional/page_objects/dataset_quality.ts @@ -219,10 +219,6 @@ export function DatasetQualityPageObject({ getPageObjects, getService }: FtrProv }, async refreshTable() { - await testSubjects.waitForEnabled( - testSubjectSelectors.datasetQualityFiltersContainer, - 10 * 1000 - ); const filtersContainer = await testSubjects.find( testSubjectSelectors.datasetQualityFiltersContainer ); From 11e57080c3d1e538f1eeef495335528a75c955ca Mon Sep 17 00:00:00 2001 From: achyutjhunjhunwala Date: Wed, 3 Jul 2024 11:03:22 +0200 Subject: [PATCH 05/12] Add logic to refactor integration into not depending on main page --- .../dataset_quality/common/api_types.ts | 15 +- .../common/data_stream_details/types.ts | 13 ++ .../common/data_streams_stats/integration.ts | 5 +- .../common/data_streams_stats/types.ts | 6 - .../dataset_quality/common/types/common.ts | 11 ++ .../public/components/flyout/flyout.tsx | 17 +- .../public/components/flyout/header.tsx | 10 +- .../flyout/integration_actions_menu.tsx | 7 +- .../components/flyout/integration_summary.tsx | 11 +- .../hooks/use_dataset_quality_flyout.tsx | 11 +- .../hooks/use_flyout_integration_actions.tsx | 4 +- .../public/hooks/use_redirect_link.ts | 16 +- .../data_stream_details_client.ts | 38 ++++- .../services/data_stream_details/types.ts | 11 +- .../data_streams_stats_client.ts | 6 +- .../services/data_streams_stats/types.ts | 4 +- .../src/notifications.ts | 9 ++ .../src/state_machine.ts | 146 ++++++++++++------ .../dataset_quality_controller/src/types.ts | 22 ++- .../get_data_stream_details/index.ts | 5 + .../get_data_streams_stats/index.ts | 2 +- .../routes/integrations/get_integrations.ts | 4 +- .../server/routes/integrations/routes.ts | 6 +- 23 files changed, 263 insertions(+), 116 deletions(-) create mode 100644 x-pack/plugins/observability_solution/dataset_quality/common/data_stream_details/types.ts diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts b/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts index ce84985a39405..87cd9624e6f35 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts @@ -11,8 +11,6 @@ const userPrivilegesRt = rt.type({ canMonitor: rt.boolean, }); -export type DataStreamUserPrivileges = rt.TypeOf; - const datasetUserPrivilegesRt = rt.intersection([ userPrivilegesRt, rt.type({ @@ -44,14 +42,13 @@ export const dashboardRT = rt.type({ title: rt.string, }); +export type Dashboard = rt.TypeOf; + export const integrationDashboardsRT = rt.type({ dashboards: rt.array(dashboardRT), }); -export type IntegrationDashboards = rt.TypeOf; -export type Dashboard = rt.TypeOf; - -export const getIntegrationDashboardsResponseRt = rt.exact(integrationDashboardsRT); +export type IntegrationDashboardsResponse = rt.TypeOf; export const integrationIconRt = rt.intersection([ rt.type({ @@ -74,11 +71,10 @@ export const integrationRt = rt.intersection([ version: rt.string, icons: rt.array(integrationIconRt), datasets: rt.record(rt.string, rt.string), - dashboards: rt.array(dashboardRT), }), ]); -export type Integration = rt.TypeOf; +export type IntegrationType = rt.TypeOf; export const getIntegrationsResponseRt = rt.exact( rt.type({ @@ -86,6 +82,8 @@ export const getIntegrationsResponseRt = rt.exact( }) ); +export type IntegrationResponse = rt.TypeOf; + export const degradedDocsRt = rt.type({ dataset: rt.string, count: rt.number, @@ -117,6 +115,7 @@ export type DegradedFieldResponse = rt.TypeOf; diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/data_stream_details/types.ts b/x-pack/plugins/observability_solution/dataset_quality/common/data_stream_details/types.ts new file mode 100644 index 0000000000000..74f0653396447 --- /dev/null +++ b/x-pack/plugins/observability_solution/dataset_quality/common/data_stream_details/types.ts @@ -0,0 +1,13 @@ +/* + * 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 { DataStreamType } from '../types'; + +export interface GetDataStreamIntegrationParams { + type: DataStreamType; + integrationName: string; +} diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/integration.ts b/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/integration.ts index ad8fecd91c7e0..8a3a9d4b5e8b0 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/integration.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/integration.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { DashboardType, IntegrationType } from './types'; +import { IntegrationType } from '../api_types'; export class Integration { name: IntegrationType['name']; @@ -13,14 +13,12 @@ export class Integration { version: string; datasets: Record; icons?: IntegrationType['icons']; - dashboards?: DashboardType[]; private constructor(integration: Integration) { this.name = integration.name; this.title = integration.title || integration.name; this.version = integration.version || '1.0.0'; this.icons = integration.icons; - this.dashboards = integration.dashboards || []; this.datasets = integration.datasets || {}; } @@ -29,7 +27,6 @@ export class Integration { ...integration, title: integration.title || integration.name, version: integration.version || '1.0.0', - dashboards: integration.dashboards || [], datasets: integration.datasets || {}, }; diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/types.ts b/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/types.ts index 42fbeeb2cff52..9fe23f6ceef6f 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/types.ts @@ -17,9 +17,6 @@ export type DataStreamStatServiceResponse = GetDataStreamsStatsResponse; export type GetIntegrationsParams = APIClientRequestParamsOf<`GET /internal/dataset_quality/integrations`>['params']; -export type GetIntegrationsResponse = APIReturnType<`GET /internal/dataset_quality/integrations`>; -export type IntegrationType = GetIntegrationsResponse['integrations'][0]; -export type IntegrationsResponse = IntegrationType[]; export type GetDataStreamsDegradedDocsStatsParams = APIClientRequestParamsOf<`GET /internal/dataset_quality/data_streams/degraded_docs`>['params']; @@ -69,9 +66,6 @@ export type GetNonAggregatableDataStreamsResponse = export type GetIntegrationDashboardsParams = APIClientRequestParamsOf<`GET /internal/dataset_quality/integrations/{integration}/dashboards`>['params']['path']; -export type GetIntegrationDashboardsResponse = - APIReturnType<`GET /internal/dataset_quality/integrations/{integration}/dashboards`>; -export type DashboardType = GetIntegrationDashboardsResponse['dashboards'][0]; export type { DataStreamStat } from './data_stream_stat'; export type { diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/types/common.ts b/x-pack/plugins/observability_solution/dataset_quality/common/types/common.ts index d7e5c4d78bbef..fd83bbf24e956 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/types/common.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/types/common.ts @@ -5,6 +5,9 @@ * 2.0. */ +import { DataStreamStatType } from '../data_streams_stats'; +import { Integration } from '../data_streams_stats/integration'; + export type SortDirection = 'asc' | 'desc'; export type Maybe = T | null | undefined; @@ -13,3 +16,11 @@ export interface Coordinate { x: number; y: Maybe; } + +export interface BasicDataStreamStats { + type: string; + name: DataStreamStatType['name']; + namespace: string; + title: string; + integration?: Integration; +} diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/flyout.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/flyout.tsx index 7543322a5dafc..e6ce36b268afe 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/flyout.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/flyout.tsx @@ -26,6 +26,7 @@ import { Header } from './header'; import { IntegrationSummary } from './integration_summary'; import { FlyoutProps } from './types'; import { FlyoutSummary } from './flyout_summary/flyout_summary'; +import { BasicDataStreamStats } from '../../../common/types'; // Allow for lazy loading // eslint-disable-next-line import/no-default-export @@ -39,8 +40,17 @@ export default function Flyout({ dataset, closeFlyout }: FlyoutProps) { timeRange, loadingState, flyoutLoading, + integration, } = useDatasetQualityFlyout(); + const titleAndLinkDetails: BasicDataStreamStats = { + name: dataset.name, + integration: integration?.integrationDetails, + type: dataset.type, + namespace: dataset.namespace, + title: integration?.integrationDetails?.datasets?.[dataset.name] ?? dataset.name, + }; + return ( ) : ( <> -
+
- {dataStreamStat.integration && ( + {integration?.integrationDetails && ( <> diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx index 63fb761ce87f5..f130f785e8f7d 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx @@ -21,14 +21,16 @@ import { flyoutOpenInLogsExplorerText, } from '../../../common/translations'; import { useRedirectLink } from '../../hooks'; -import { FlyoutDataset } from '../../state_machines/dataset_quality_controller'; import { IntegrationIcon } from '../common'; +import { BasicDataStreamStats } from '../../../common/types'; -export function Header({ dataStreamStat }: { dataStreamStat: FlyoutDataset }) { - const { integration, title } = dataStreamStat; +export function Header({ titleAndLinkDetails }: { titleAndLinkDetails: BasicDataStreamStats }) { + const { integration, title } = titleAndLinkDetails; const euiShadow = useEuiShadow('s'); const { euiTheme } = useEuiTheme(); - const redirectLinkProps = useRedirectLink({ dataStreamStat }); + const redirectLinkProps = useRedirectLink({ + dataStreamStat: titleAndLinkDetails, + }); return ( diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/integration_actions_menu.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/integration_actions_menu.tsx index 9b0e45ce27e90..99afb7f269df5 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/integration_actions_menu.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/integration_actions_menu.tsx @@ -18,9 +18,10 @@ import { } from '@elastic/eui'; import { css } from '@emotion/react'; import { RouterLinkProps } from '@kbn/router-utils/src/get_router_link_props'; -import { Integration } from '../../../common/data_streams_stats/integration'; import { useDatasetQualityFlyout } from '../../hooks'; import { useFlyoutIntegrationActions } from '../../hooks/use_flyout_integration_actions'; +import { Integration } from '../../../common/data_streams_stats/integration'; +import { Dashboard } from '../../../common/api_types'; const integrationActionsText = i18n.translate('xpack.datasetQuality.flyoutIntegrationActionsText', { defaultMessage: 'Integration actions', @@ -40,15 +41,17 @@ const viewDashboardsText = i18n.translate('xpack.datasetQuality.flyoutViewDashbo export function IntegrationActionsMenu({ integration, + dashboards, dashboardsLoading, }: { integration: Integration; + dashboards: Dashboard[]; dashboardsLoading: boolean; }) { const { dataStreamStat, canUserAccessDashboards, canUserViewIntegrations } = useDatasetQualityFlyout(); + const { version, name: integrationName } = integration; const { type, name } = dataStreamStat!; - const { dashboards = [], version, name: integrationName } = integration; const { isOpen, handleCloseMenu, diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/integration_summary.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/integration_summary.tsx index 1450e830eac1e..6ac94411098a6 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/integration_summary.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/integration_summary.tsx @@ -13,22 +13,29 @@ import { flyoutIntegrationNameText, flyoutIntegrationVersionText, } from '../../../common/translations'; -import { Integration } from '../../../common/data_streams_stats/integration'; import { IntegrationIcon } from '../common'; import { FieldsList } from './fields_list'; import { IntegrationActionsMenu } from './integration_actions_menu'; +import { Integration } from '../../../common/data_streams_stats/integration'; +import { Dashboard } from '../../../common/api_types'; export function IntegrationSummary({ integration, + dashboards, dashboardsLoading, }: { integration: Integration; + dashboards: Dashboard[]; dashboardsLoading: boolean; }) { const { name, version } = integration; const integrationActionsMenu = ( - + ); return ( { insightsTimeRange, breakdownField, isNonAggregatable, + integration, } = useSelector(service, (state) => state.context.flyout) ?? {}; const { timeRange } = useSelector(service, (state) => state.context.filters); @@ -30,12 +31,17 @@ export const useDatasetQualityFlyout = () => { const loadingState = useSelector(service, (state) => ({ dataStreamDetailsLoading: state.matches('flyout.initializing.dataStreamDetails.fetching'), dataStreamSettingsLoading: state.matches('flyout.initializing.dataStreamSettings.fetching'), - datasetIntegrationsLoading: state.matches('flyout.initializing.integrationDashboards.fetching'), + datasetIntegrationsLoading: state.matches( + 'flyout.initializing.dataStreamSettings.initializeIntegrations.integrationDashboards.fetching' + ), })); const canUserAccessDashboards = useSelector( service, - (state) => !state.matches('flyout.initializing.integrationDashboards.unauthorized') + (state) => + !state.matches( + 'flyout.initializing.dataStreamSettings.initializeIntegrations.integrationDashboards.unauthorized' + ) ); const canUserViewIntegrations = useSelector( @@ -48,6 +54,7 @@ export const useDatasetQualityFlyout = () => { dataStreamSettings, dataStreamDetails, isNonAggregatable, + integration, fieldFormats, timeRange: insightsTimeRange ?? timeRange, breakdownField, diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_flyout_integration_actions.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_flyout_integration_actions.tsx index 29faaec2788ea..cd899041ae283 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_flyout_integration_actions.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_flyout_integration_actions.tsx @@ -10,8 +10,8 @@ import { useMemo, useCallback } from 'react'; import useToggle from 'react-use/lib/useToggle'; import { MANAGEMENT_APP_LOCATOR } from '@kbn/deeplinks-management/constants'; import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics'; -import { DashboardType } from '../../common/data_streams_stats'; import { useKibanaContextForPlugin } from '../utils'; +import { Dashboard } from '../../common/api_types'; export const useFlyoutIntegrationActions = () => { const { @@ -59,7 +59,7 @@ export const useFlyoutIntegrationActions = () => { [indexManagementLocator] ); const getDashboardLinkProps = useCallback( - (dashboard: DashboardType) => + (dashboard: Dashboard) => getRouterLinkProps({ href: dashboardLocator?.getRedirectUrl({ dashboardId: dashboard?.id } || ''), onClick: () => dashboardLocator?.navigate({ dashboardId: dashboard?.id } || ''), diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_redirect_link.ts b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_redirect_link.ts index 751b7e14ebb79..09c074a2a11bc 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_redirect_link.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_redirect_link.ts @@ -16,18 +16,18 @@ import { RouterLinkProps } from '@kbn/router-utils/src/get_router_link_props'; import { LocatorPublic } from '@kbn/share-plugin/common'; import { LocatorClient } from '@kbn/shared-ux-prompt-no-data-views-types'; import { useSelector } from '@xstate/react'; -import { DataStreamStat } from '../../common/data_streams_stats/data_stream_stat'; import { useDatasetQualityContext } from '../components/dataset_quality/context'; -import { FlyoutDataset, TimeRangeConfig } from '../state_machines/dataset_quality_controller'; +import { TimeRangeConfig } from '../state_machines/dataset_quality_controller'; import { useKibanaContextForPlugin } from '../utils'; +import { BasicDataStreamStats } from '../../common/types'; -export const useRedirectLink = ({ +export const useRedirectLink = ({ dataStreamStat, query, timeRangeConfig, breakdownField, }: { - dataStreamStat: DataStreamStat | FlyoutDataset; + dataStreamStat: T; query?: Query | AggregateQuery; timeRangeConfig?: TimeRangeConfig; breakdownField?: string; @@ -68,7 +68,7 @@ export const useRedirectLink = ({ }; }; -const buildLogsExplorerConfig = ({ +const buildLogsExplorerConfig = ({ locator, dataStreamStat, query, @@ -77,7 +77,7 @@ const buildLogsExplorerConfig = ({ breakdownField, }: { locator: LocatorPublic; - dataStreamStat: DataStreamStat | FlyoutDataset; + dataStreamStat: T; query?: Query | AggregateQuery; from: string; to: string; @@ -117,7 +117,7 @@ const buildLogsExplorerConfig = ({ return { routerLinkProps: logsExplorerLinkProps, navigate: navigateToLogsExplorer }; }; -const buildDiscoverConfig = ({ +const buildDiscoverConfig = ({ locatorClient, dataStreamStat, query, @@ -126,7 +126,7 @@ const buildDiscoverConfig = ({ breakdownField, }: { locatorClient: LocatorClient; - dataStreamStat: DataStreamStat | FlyoutDataset; + dataStreamStat: T; query?: Query | AggregateQuery; from: string; to: string; diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/data_stream_details_client.ts b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/data_stream_details_client.ts index 52bdf3c53ea51..a5813b3190351 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/data_stream_details_client.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/data_stream_details_client.ts @@ -11,7 +11,10 @@ import { getDataStreamDegradedFieldsResponseRt, getDataStreamsDetailsResponseRt, getDataStreamsSettingsResponseRt, + getIntegrationsResponseRt, + IntegrationDashboardsResponse, integrationDashboardsRT, + IntegrationResponse, } from '../../../common/api_types'; import { DataStreamDetails, @@ -24,10 +27,11 @@ import { GetDataStreamSettingsResponse, GetDataStreamsStatsError, GetIntegrationDashboardsParams, - GetIntegrationDashboardsResponse, } from '../../../common/data_streams_stats'; import { IDataStreamDetailsClient } from './types'; import { GetDataStreamsDetailsError } from '../../../common/data_stream_details'; +import { Integration } from '../../../common/data_streams_stats/integration'; +import { GetDataStreamIntegrationParams } from '../../../common/data_stream_details/types'; export class DataStreamDetailsClient implements IDataStreamDetailsClient { constructor(private readonly http: HttpStart) {} @@ -107,7 +111,7 @@ export class DataStreamDetailsClient implements IDataStreamDetailsClient { public async getIntegrationDashboards({ integration }: GetIntegrationDashboardsParams) { const response = await this.http - .get( + .get( `/internal/dataset_quality/integrations/${integration}/dashboards` ) .catch((error) => { @@ -117,7 +121,7 @@ export class DataStreamDetailsClient implements IDataStreamDetailsClient { ); }); - const integrationDashboards = decodeOrThrow( + const { dashboards } = decodeOrThrow( integrationDashboardsRT, (message: string) => new GetDataStreamsStatsError( @@ -125,6 +129,32 @@ export class DataStreamDetailsClient implements IDataStreamDetailsClient { ) )(response); - return integrationDashboards; + return dashboards; + } + + public async getDataStreamIntegration( + params: GetDataStreamIntegrationParams + ): Promise { + const { type, integrationName } = params; + const response = await this.http + .get('/internal/dataset_quality/integrations', { + query: { type }, + }) + .catch((error) => { + throw new GetDataStreamsStatsError( + `Failed to fetch integrations: ${error}`, + error.body.statusCode + ); + }); + + const { integrations } = decodeOrThrow( + getIntegrationsResponseRt, + (message: string) => + new GetDataStreamsStatsError(`Failed to decode integrations response: ${message}`) + )(response); + + const integration = integrations.find((i) => i.name === integrationName); + + if (integration) return Integration.create(integration); } } diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/types.ts b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/types.ts index 708c1ba8a6c4c..40eaf499a3032 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_stream_details/types.ts @@ -6,16 +6,18 @@ */ import { HttpStart } from '@kbn/core/public'; +import { Integration } from '../../../common/data_streams_stats/integration'; import { GetDataStreamSettingsParams, DataStreamSettings, GetDataStreamDetailsParams, DataStreamDetails, GetIntegrationDashboardsParams, - GetIntegrationDashboardsResponse, GetDataStreamDegradedFieldsParams, DegradedFieldResponse, } from '../../../common/data_streams_stats'; +import { GetDataStreamIntegrationParams } from '../../../common/data_stream_details/types'; +import { Dashboard } from '../../../common/api_types'; export type DataStreamDetailsServiceSetup = void; @@ -33,7 +35,8 @@ export interface IDataStreamDetailsClient { getDataStreamDegradedFields( params: GetDataStreamDegradedFieldsParams ): Promise; - getIntegrationDashboards( - params: GetIntegrationDashboardsParams - ): Promise; + getIntegrationDashboards(params: GetIntegrationDashboardsParams): Promise; + getDataStreamIntegration( + params: GetDataStreamIntegrationParams + ): Promise; } diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts index 6ffa91e7151da..bbce86404e1dd 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts @@ -12,6 +12,7 @@ import { getDataStreamsStatsResponseRt, getIntegrationsResponseRt, getNonAggregatableDatasetsRt, + IntegrationResponse, } from '../../../common/api_types'; import { DEFAULT_DATASET_TYPE } from '../../../common/constants'; import { @@ -24,7 +25,6 @@ import { GetIntegrationsParams, GetNonAggregatableDataStreamsParams, GetNonAggregatableDataStreamsResponse, - IntegrationsResponse, } from '../../../common/data_streams_stats'; import { Integration } from '../../../common/data_streams_stats/integration'; import { IDataStreamsStatsClient } from './types'; @@ -113,9 +113,9 @@ export class DataStreamsStatsClient implements IDataStreamsStatsClient { public async getIntegrations( params: GetIntegrationsParams['query'] = { type: DEFAULT_DATASET_TYPE } - ): Promise { + ): Promise { const response = await this.http - .get('/internal/dataset_quality/integrations', { + .get('/internal/dataset_quality/integrations', { query: params, }) .catch((error) => { diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/types.ts b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/types.ts index 7e3ee958b4074..ba1f9077f45b0 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/services/data_streams_stats/types.ts @@ -14,8 +14,8 @@ import { GetIntegrationsParams, GetNonAggregatableDataStreamsParams, GetNonAggregatableDataStreamsResponse, - IntegrationsResponse, } from '../../../common/data_streams_stats'; +import { Integration } from '../../../common/data_streams_stats/integration'; export type DataStreamsStatsServiceSetup = void; @@ -32,7 +32,7 @@ export interface IDataStreamsStatsClient { getDataStreamsDegradedStats( params?: GetDataStreamsDegradedDocsStatsQuery ): Promise; - getIntegrations(params: GetIntegrationsParams['query']): Promise; + getIntegrations(params: GetIntegrationsParams['query']): Promise; getNonAggregatableDatasets( params: GetNonAggregatableDataStreamsParams ): Promise; diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/notifications.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/notifications.ts index d2077f20ad9d2..c5bf91412656d 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/notifications.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/notifications.ts @@ -71,6 +71,15 @@ export const fetchIntegrationsFailedNotifier = (toasts: IToasts, error: Error) = }); }; +export const fetchDataStreamIntegrationFailedNotifier = (toasts: IToasts, error: Error) => { + toasts.addDanger({ + title: i18n.translate('xpack.datasetQuality.flyout.fetchIntegrationsFailed', { + defaultMessage: "We couldn't get your integrations.", + }), + text: error.message, + }); +}; + export const noDatasetSelected = i18n.translate( 'xpack.datasetQuality.fetchDatasetDetailsFailed.noDatasetSelected', { diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts index 4c2b516fc4662..97bad90df012c 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts @@ -8,11 +8,10 @@ import { IToasts } from '@kbn/core/public'; import { getDateISORange } from '@kbn/timerange'; import { assign, createMachine, DoneInvokeEvent, InterpreterFrom } from 'xstate'; -import { DataStreamStat, DegradedFieldResponse } from '../../../../common/api_types'; +import { Dashboard, DataStreamStat, DegradedFieldResponse } from '../../../../common/api_types'; import { Integration } from '../../../../common/data_streams_stats/integration'; import { IDataStreamDetailsClient } from '../../../services/data_stream_details'; import { - DashboardType, DataStreamSettings, DataStreamDetails, GetDataStreamsStatsQuery, @@ -35,6 +34,7 @@ import { fetchIntegrationsFailedNotifier, noDatasetSelected, fetchNonAggregatableDatasetsFailedNotifier, + fetchDataStreamIntegrationFailedNotifier, } from './notifications'; import { DatasetQualityControllerContext, @@ -261,7 +261,7 @@ export const createPureDatasetQualityControllerStateMachine = ( invoke: { src: 'loadDataStreamSettings', onDone: { - target: 'done', + target: 'initializeIntegrations', actions: ['storeDataStreamSettings'], }, onError: { @@ -270,6 +270,62 @@ export const createPureDatasetQualityControllerStateMachine = ( }, }, }, + initializeIntegrations: { + type: 'parallel', + states: { + integrationDetails: { + initial: 'fetching', + states: { + fetching: { + invoke: { + src: 'loadDataStreamIntegrations', + onDone: { + target: 'done', + actions: ['storeDataStreamIntegrations'], + }, + onError: { + target: 'done', + actions: ['notifyFetchDatasetIntegrationsFailed'], + }, + }, + }, + done: { + type: 'final', + }, + }, + }, + integrationDashboards: { + initial: 'fetching', + states: { + fetching: { + invoke: { + src: 'loadIntegrationDashboards', + onDone: { + target: 'done', + actions: ['storeIntegrationDashboards'], + }, + onError: [ + { + target: 'unauthorized', + cond: 'checkIfActionForbidden', + }, + { + target: 'done', + actions: ['notifyFetchIntegrationDashboardsFailed'], + }, + ], + }, + }, + done: { + type: 'final', + }, + unauthorized: { + type: 'final', + }, + }, + }, + }, + }, done: { type: 'final', }, @@ -304,36 +360,6 @@ export const createPureDatasetQualityControllerStateMachine = ( }, }, }, - integrationDashboards: { - initial: 'fetching', - states: { - fetching: { - invoke: { - src: 'loadIntegrationDashboards', - onDone: { - target: 'done', - actions: ['storeIntegrationDashboards'], - }, - onError: [ - { - target: 'unauthorized', - cond: 'checkIfActionForbidden', - }, - { - target: 'done', - actions: ['notifyFetchIntegrationDashboardsFailed'], - }, - ], - }, - }, - done: { - type: 'final', - }, - unauthorized: { - type: 'final', - }, - }, - }, dataStreamDegradedFields: { initial: 'fetching', states: { @@ -623,18 +649,28 @@ export const createPureDatasetQualityControllerStateMachine = ( integrations: [], }; }), - storeIntegrationDashboards: assign((context, event) => { - return 'data' in event && 'dashboards' in event.data + storeDataStreamIntegrations: assign((context, event: DoneInvokeEvent) => { + return 'data' in event ? { flyout: { ...context.flyout, - dataset: { - ...context.flyout.dataset, - integration: { - ...context.flyout.dataset?.integration, - dashboards: event.data.dashboards as DashboardType[], - }, - } as FlyoutDataset, + integration: { + ...context.flyout.integration, + integrationDetails: event.data, + }, + }, + } + : {}; + }), + storeIntegrationDashboards: assign((context, event: DoneInvokeEvent) => { + return 'data' in event + ? { + flyout: { + ...context.flyout, + integration: { + ...context.flyout.integration, + dashboards: event.data, + }, }, } : {}; @@ -688,6 +724,8 @@ export const createDatasetQualityControllerStateMachine = ({ fetchIntegrationDashboardsFailedNotifier(toasts, event.data), notifyFetchIntegrationsFailed: (_context, event: DoneInvokeEvent) => fetchIntegrationsFailedNotifier(toasts, event.data), + notifyFetchDatasetIntegrationsFailed: (_context, event: DoneInvokeEvent) => + fetchDataStreamIntegrationFailedNotifier(toasts, event.data), }, services: { loadDataStreamStats: (context) => @@ -757,6 +795,16 @@ export const createDatasetQualityControllerStateMachine = ({ }), }); }, + loadDataStreamIntegrations: (context) => { + if (context.flyout.datasetSettings?.integration && context.flyout.dataset) { + const { type } = context.flyout.dataset; + return dataStreamDetailsClient.getDataStreamIntegration({ + type: type as DataStreamType, + integrationName: context.flyout.datasetSettings.integration, + }); + } + return Promise.resolve(); + }, loadDataStreamDetails: (context) => { if (!context.flyout.dataset || !context.flyout.insightsTimeRange) { fetchDatasetDetailsFailedNotifier(toasts, new Error(noDatasetSelected)); @@ -780,17 +828,13 @@ export const createDatasetQualityControllerStateMachine = ({ }); }, loadIntegrationDashboards: (context) => { - if (!context.flyout.dataset) { - fetchDatasetDetailsFailedNotifier(toasts, new Error(noDatasetSelected)); - - return Promise.resolve({}); + if (context.flyout.datasetSettings?.integration) { + return dataStreamDetailsClient.getIntegrationDashboards({ + integration: context.flyout.datasetSettings.integration, + }); } - const { integration } = context.flyout.dataset; - - return integration - ? dataStreamDetailsClient.getIntegrationDashboards({ integration: integration.name }) - : Promise.resolve({}); + return Promise.resolve(); }, loadDatasetIsNonAggregatable: async (context) => { if (!context.flyout.dataset || !context.flyout.insightsTimeRange) { diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts index c75c648020d61..6f6fc1fab5285 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts @@ -8,17 +8,15 @@ import { DoneInvokeEvent } from 'xstate'; import { RefreshInterval, TimeRange } from '@kbn/data-plugin/common'; import { QualityIndicators, SortDirection } from '../../../../common/types'; -import { DatasetUserPrivileges } from '../../../../common/api_types'; +import { Dashboard, DatasetUserPrivileges } from '../../../../common/api_types'; import { Integration } from '../../../../common/data_streams_stats/integration'; import { DatasetTableSortField, DegradedFieldSortField } from '../../../hooks'; import { DegradedDocsStat } from '../../../../common/data_streams_stats/malformed_docs_stat'; import { - DashboardType, DataStreamDegradedDocsStatServiceResponse, DataStreamSettings, DataStreamDetails, DataStreamStatServiceResponse, - IntegrationsResponse, DataStreamStat, DataStreamStatType, GetNonAggregatableDataStreamsResponse, @@ -59,6 +57,11 @@ interface FiltersCriteria { query?: string; } +export interface DataStreamIntegrations { + integrationDetails?: Integration; + dashboards?: Dashboard[]; +} + export interface WithTableOptions { table: TableCriteria; } @@ -72,6 +75,7 @@ export interface WithFlyoutOptions { breakdownField?: string; degradedFields: DegradedFields; isNonAggregatable?: boolean; + integration?: DataStreamIntegrations; }; } @@ -146,6 +150,14 @@ export type DatasetQualityControllerTypeState = value: 'flyout.initializing.dataStreamSettings.fetching'; context: DefaultDatasetQualityStateContext; } + | { + value: 'flyout.initializing.dataStreamSettings.initializeIntegrations.integrationDashboards.fetching'; + context: DefaultDatasetQualityStateContext; + } + | { + value: 'flyout.initializing.dataStreamSettings.initializeIntegrations.integrationDashboards.unauthorized'; + context: DefaultDatasetQualityStateContext; + } | { value: 'flyout.initializing.dataStreamDetails.fetching'; context: DefaultDatasetQualityStateContext; @@ -222,10 +234,10 @@ export type DatasetQualityControllerEvent = } | DoneInvokeEvent | DoneInvokeEvent - | DoneInvokeEvent + | DoneInvokeEvent | DoneInvokeEvent | DoneInvokeEvent | DoneInvokeEvent | DoneInvokeEvent - | DoneInvokeEvent + | DoneInvokeEvent | DoneInvokeEvent; diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts index 52804c5d9369c..a14cd98730ccd 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts @@ -32,8 +32,13 @@ export async function getDataStreamSettings({ const createdOn = await getDataStreamCreatedOn(esClient, dataStream); + // Getting the 1st item from the data streams endpoint as we will be passing the exact DS name + const [dataStreamInfo] = await dataStreamService.getMatchingDataStreams(esClient, dataStream); + const integration = dataStreamInfo._meta?.package?.name ?? null; + return { createdOn, + integration, }; } diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_streams_stats/index.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_streams_stats/index.ts index 41f89fa7ac156..8c7878f244862 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_streams_stats/index.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_streams_stats/index.ts @@ -24,7 +24,7 @@ export async function getDataStreamsStats({ }; } - const matchingDataStreamsStats = await dataStreamService.getStreamsStats(esClient, dataStreams); + const matchingDataStreamsStats = dataStreamService.getStreamsStats(esClient, dataStreams); const indicesDocsCount = sizeStatsAvailable ? indexStatsService.getIndicesDocCounts(esClient, dataStreams) diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/integrations/get_integrations.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/integrations/get_integrations.ts index 70aa86f08efc3..208ed7e70ab32 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/integrations/get_integrations.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/integrations/get_integrations.ts @@ -11,13 +11,13 @@ import { PackageNotFoundError } from '@kbn/fleet-plugin/server/errors'; import { PackageListItem, RegistryDataStream } from '@kbn/fleet-plugin/common'; import { DEFAULT_DATASET_TYPE } from '../../../common/constants'; import { DataStreamType } from '../../../common/types'; -import { Integration } from '../../../common/api_types'; +import { IntegrationType } from '../../../common/api_types'; export async function getIntegrations(options: { packageClient: PackageClient; logger: Logger; type?: DataStreamType; -}): Promise { +}): Promise { const { packageClient, logger, type = DEFAULT_DATASET_TYPE } = options; const packages = await packageClient.getPackages(); diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/integrations/routes.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/integrations/routes.ts index dfc0b8a2824e3..1a21d7e1a14c4 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/integrations/routes.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/integrations/routes.ts @@ -6,7 +6,7 @@ */ import * as t from 'io-ts'; -import { Integration, IntegrationDashboards } from '../../../common/api_types'; +import { IntegrationType, IntegrationDashboardsResponse } from '../../../common/api_types'; import { typeRt } from '../../types/default_api_types'; import { createDatasetQualityServerRoute } from '../create_datasets_quality_server_route'; import { getIntegrations } from './get_integrations'; @@ -21,7 +21,7 @@ const integrationsRoute = createDatasetQualityServerRoute({ tags: [], }, async handler(resources): Promise<{ - integrations: Integration[]; + integrations: IntegrationType[]; }> { const { params, plugins, logger } = resources; @@ -44,7 +44,7 @@ const integrationDashboardsRoute = createDatasetQualityServerRoute({ options: { tags: [], }, - async handler(resources): Promise { + async handler(resources): Promise { const { context, params, plugins } = resources; const { integration } = params.path; const { savedObjects } = await context.core; From f9dd8ee9e5e92d4bfea2fb944ea02dfa65151c7c Mon Sep 17 00:00:00 2001 From: achyutjhunjhunwala Date: Wed, 3 Jul 2024 14:23:57 +0200 Subject: [PATCH 06/12] Fix code review comments --- .../dataset_quality/common/api_types.ts | 2 +- .../dataset_quality/common/types/common.ts | 3 +- .../public/components/flyout/flyout.tsx | 12 ++- .../public/components/flyout/header.tsx | 91 +++++++++++-------- .../hooks/use_dataset_quality_flyout.tsx | 5 +- .../public/hooks/use_redirect_link.ts | 8 +- .../src/notifications.ts | 12 ++- .../src/state_machine.ts | 14 +-- .../get_data_stream_details/index.ts | 2 +- 9 files changed, 89 insertions(+), 60 deletions(-) diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts b/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts index 87cd9624e6f35..a88b2d531b9bc 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/api_types.ts @@ -115,7 +115,7 @@ export type DegradedFieldResponse = rt.TypeOf; diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/types/common.ts b/x-pack/plugins/observability_solution/dataset_quality/common/types/common.ts index fd83bbf24e956..ca5c4632ec0d3 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/types/common.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/types/common.ts @@ -17,9 +17,10 @@ export interface Coordinate { y: Maybe; } -export interface BasicDataStreamStats { +export interface BasicDataStream { type: string; name: DataStreamStatType['name']; + rawName: string; namespace: string; title: string; integration?: Integration; diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/flyout.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/flyout.tsx index 28c0e8f321a36..7411067a7317f 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/flyout.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/flyout.tsx @@ -26,7 +26,7 @@ import { Header } from './header'; import { IntegrationSummary } from './integration_summary'; import { FlyoutProps } from './types'; import { FlyoutSummary } from './flyout_summary/flyout_summary'; -import { BasicDataStreamStats } from '../../../common/types'; +import { BasicDataStream } from '../../../common/types'; // Allow for lazy loading // eslint-disable-next-line import/no-default-export @@ -43,8 +43,9 @@ export default function Flyout({ dataset, closeFlyout }: FlyoutProps) { integration, } = useDatasetQualityFlyout(); - const titleAndLinkDetails: BasicDataStreamStats = { + const titleAndLinkDetails: BasicDataStream = { name: dataset.name, + rawName: dataset.rawName, integration: integration?.integrationDetails, type: dataset.type, namespace: dataset.namespace, @@ -68,7 +69,10 @@ export default function Flyout({ dataset, closeFlyout }: FlyoutProps) { ) : ( <> -
+
)} diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx index 274b987c5c762..300d4c6660557 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx @@ -10,6 +10,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiFlyoutHeader, + EuiSkeletonTitle, EuiTitle, useEuiShadow, useEuiTheme, @@ -23,9 +24,15 @@ import { import { NavigationSource } from '../../services/telemetry'; import { useRedirectLink } from '../../hooks'; import { IntegrationIcon } from '../common'; -import { BasicDataStreamStats } from '../../../common/types'; +import { BasicDataStream } from '../../../common/types'; -export function Header({ titleAndLinkDetails }: { titleAndLinkDetails: BasicDataStreamStats }) { +export function Header({ + titleAndLinkDetails, + loading, +}: { + titleAndLinkDetails: BasicDataStream; + loading: boolean; +}) { const { integration, title } = titleAndLinkDetails; const euiShadow = useEuiShadow('s'); const { euiTheme } = useEuiTheme(); @@ -39,47 +46,51 @@ export function Header({ titleAndLinkDetails }: { titleAndLinkDetails: BasicData return ( - - - - -

{title}

-
-
+ ) : ( + + + + +

{title}

+
+
+ +
+
+
+ + - -
-
-
- - - - {redirectLinkProps.isLogsExplorerAvailable - ? flyoutOpenInLogsExplorerText - : flyoutOpenInDiscoverText} - - - -
+ + {redirectLinkProps.isLogsExplorerAvailable + ? flyoutOpenInLogsExplorerText + : flyoutOpenInDiscoverText} + + + + + )}
); } diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_quality_flyout.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_quality_flyout.tsx index 358bd19497ade..88bf869a5a2a9 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_quality_flyout.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_dataset_quality_flyout.tsx @@ -31,9 +31,12 @@ export const useDatasetQualityFlyout = () => { const loadingState = useSelector(service, (state) => ({ dataStreamDetailsLoading: state.matches('flyout.initializing.dataStreamDetails.fetching'), dataStreamSettingsLoading: state.matches('flyout.initializing.dataStreamSettings.fetching'), - datasetIntegrationsLoading: state.matches( + datasetIntegrationDashboardLoading: state.matches( 'flyout.initializing.dataStreamSettings.initializeIntegrations.integrationDashboards.fetching' ), + datasetIntegrationDone: state.matches( + 'flyout.initializing.dataStreamSettings.initializeIntegrations.integrationDetails.done' + ), })); const canUserAccessDashboards = useSelector( diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_redirect_link.ts b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_redirect_link.ts index a33ba418c2c22..4a4c6772c412c 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_redirect_link.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_redirect_link.ts @@ -20,10 +20,10 @@ import { useSelector } from '@xstate/react'; import { useDatasetQualityContext } from '../components/dataset_quality/context'; import { TimeRangeConfig } from '../state_machines/dataset_quality_controller'; import { useKibanaContextForPlugin } from '../utils'; -import { BasicDataStreamStats } from '../../common/types'; +import { BasicDataStream } from '../../common/types'; import { useRedirectLinkTelemetry } from './use_telemetry'; -export const useRedirectLink = ({ +export const useRedirectLink = ({ dataStreamStat, query, timeRangeConfig, @@ -109,7 +109,7 @@ export const useRedirectLink = ({ ]); }; -const buildLogsExplorerConfig = ({ +const buildLogsExplorerConfig = ({ locator, dataStreamStat, query, @@ -158,7 +158,7 @@ const buildLogsExplorerConfig = ({ return { routerLinkProps: logsExplorerLinkProps, navigate: navigateToLogsExplorer }; }; -const buildDiscoverConfig = ({ +const buildDiscoverConfig = ({ locatorClient, dataStreamStat, query, diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/notifications.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/notifications.ts index c5bf91412656d..cd733d9a55f2f 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/notifications.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/notifications.ts @@ -71,10 +71,18 @@ export const fetchIntegrationsFailedNotifier = (toasts: IToasts, error: Error) = }); }; -export const fetchDataStreamIntegrationFailedNotifier = (toasts: IToasts, error: Error) => { +export const fetchDataStreamIntegrationFailedNotifier = ( + toasts: IToasts, + error: Error, + integrationName?: string +) => { toasts.addDanger({ title: i18n.translate('xpack.datasetQuality.flyout.fetchIntegrationsFailed', { - defaultMessage: "We couldn't get your integrations.", + defaultMessage: `${ + integrationName + ? `We couldn't get ${integrationName} integration info.` + : `We couldn't get your integration` + }`, }), text: error.message, }); diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts index 97bad90df012c..6cad5ae252c0f 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/state_machine.ts @@ -278,10 +278,10 @@ export const createPureDatasetQualityControllerStateMachine = ( states: { fetching: { invoke: { - src: 'loadDataStreamIntegrations', + src: 'loadDataStreamIntegration', onDone: { target: 'done', - actions: ['storeDataStreamIntegrations'], + actions: ['storeDataStreamIntegration'], }, onError: { target: 'done', @@ -649,7 +649,7 @@ export const createPureDatasetQualityControllerStateMachine = ( integrations: [], }; }), - storeDataStreamIntegrations: assign((context, event: DoneInvokeEvent) => { + storeDataStreamIntegration: assign((context, event: DoneInvokeEvent) => { return 'data' in event ? { flyout: { @@ -724,8 +724,10 @@ export const createDatasetQualityControllerStateMachine = ({ fetchIntegrationDashboardsFailedNotifier(toasts, event.data), notifyFetchIntegrationsFailed: (_context, event: DoneInvokeEvent) => fetchIntegrationsFailedNotifier(toasts, event.data), - notifyFetchDatasetIntegrationsFailed: (_context, event: DoneInvokeEvent) => - fetchDataStreamIntegrationFailedNotifier(toasts, event.data), + notifyFetchDatasetIntegrationsFailed: (context, event: DoneInvokeEvent) => { + const integrationName = context.flyout.datasetSettings?.integration; + return fetchDataStreamIntegrationFailedNotifier(toasts, event.data, integrationName); + }, }, services: { loadDataStreamStats: (context) => @@ -795,7 +797,7 @@ export const createDatasetQualityControllerStateMachine = ({ }), }); }, - loadDataStreamIntegrations: (context) => { + loadDataStreamIntegration: (context) => { if (context.flyout.datasetSettings?.integration && context.flyout.dataset) { const { type } = context.flyout.dataset; return dataStreamDetailsClient.getDataStreamIntegration({ diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts index a14cd98730ccd..7bdf1aace34cb 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts @@ -34,7 +34,7 @@ export async function getDataStreamSettings({ // Getting the 1st item from the data streams endpoint as we will be passing the exact DS name const [dataStreamInfo] = await dataStreamService.getMatchingDataStreams(esClient, dataStream); - const integration = dataStreamInfo._meta?.package?.name ?? null; + const integration = dataStreamInfo._meta?.package?.name; return { createdOn, From 62cbefbc60c0732c48aa27b5f1637a7ba290df7d Mon Sep 17 00:00:00 2001 From: achyutjhunjhunwala Date: Wed, 3 Jul 2024 14:56:22 +0200 Subject: [PATCH 07/12] Fix unwanted Server side Unit tests --- .../src/notifications.ts | 9 ++-- .../get_data_stream_settings.test.ts | 44 ++++++++++++++++++- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/notifications.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/notifications.ts index cd733d9a55f2f..f92db44eb516c 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/notifications.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/notifications.ts @@ -78,11 +78,10 @@ export const fetchDataStreamIntegrationFailedNotifier = ( ) => { toasts.addDanger({ title: i18n.translate('xpack.datasetQuality.flyout.fetchIntegrationsFailed', { - defaultMessage: `${ - integrationName - ? `We couldn't get ${integrationName} integration info.` - : `We couldn't get your integration` - }`, + defaultMessage: "We couldn't get {integrationName} integration info.", + values: { + integrationName, + }, }), text: error.message, }); diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/get_data_stream_settings.test.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/get_data_stream_settings.test.ts index dd2548d033c71..1a4ce17fbce3b 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/get_data_stream_settings.test.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/get_data_stream_settings.test.ts @@ -8,6 +8,7 @@ import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; import { getDataStreamSettings } from '.'; +import { IndicesGetDataStreamResponse } from '@elastic/elasticsearch/lib/api/types'; const accessLogsDataStream = 'logs-nginx.access-default'; const errorLogsDataStream = 'logs-nginx.error-default'; const dateStr1 = '1702998651925'; // .ds-logs-nginx.access-default-2023.12.19-000001 @@ -38,12 +39,13 @@ describe('getDataStreamSettings', () => { esClientMock.indices.getSettings.mockReturnValue( Promise.resolve(MOCK_NGINX_ERROR_INDEX_SETTINGS) ); + esClientMock.indices.getDataStream.mockReturnValue(Promise.resolve(MOCK_NGINX_DATA_STREAM)); const dataStreamSettings = await getDataStreamSettings({ esClient: esClientMock, dataStream: errorLogsDataStream, }); - expect(dataStreamSettings).toEqual({ createdOn: Number(dateStr3) }); + expect(dataStreamSettings).toEqual({ createdOn: Number(dateStr3), integration: 'apache' }); }); it('returns the earliest creation date of a data stream with multiple backing indices', async () => { @@ -51,12 +53,13 @@ describe('getDataStreamSettings', () => { esClientMock.indices.getSettings.mockReturnValue( Promise.resolve(MOCK_NGINX_ACCESS_INDEX_SETTINGS) ); + esClientMock.indices.getDataStream.mockReturnValue(Promise.resolve(MOCK_NGINX_DATA_STREAM)); const dataStreamSettings = await getDataStreamSettings({ esClient: esClientMock, dataStream: accessLogsDataStream, }); - expect(dataStreamSettings).toEqual({ createdOn: Number(dateStr1) }); + expect(dataStreamSettings).toEqual({ createdOn: Number(dateStr1), integration: 'apache' }); }); }); @@ -225,3 +228,40 @@ const MOCK_INDEX_ERROR = { }, status: 404, }; + +const MOCK_NGINX_DATA_STREAM: IndicesGetDataStreamResponse = { + data_streams: [ + { + name: 'logs-apache.access-production', + timestamp_field: { + name: '@timestamp', + }, + indices: [ + { + index_name: '.ds-logs-apache.access-production-2024.07.03-000001', + index_uuid: 'xrGjQ-GFSeqAlUbyS0Fx-A', + prefer_ilm: true, + ilm_policy: 'logs', + managed_by: 'Index Lifecycle Management', + }, + ], + generation: 1, + _meta: { + package: { + name: 'apache', + }, + managed: true, + managed_by: 'fleet', + }, + status: 'YELLOW', + template: 'logs-apache.access', + ilm_policy: 'logs', + next_generation_managed_by: 'Index Lifecycle Management', + prefer_ilm: true, + hidden: false, + system: false, + allow_custom_routing: false, + replicated: false, + }, + ], +}; From 121d4e4e88062e265eafd351682379f96a561cd1 Mon Sep 17 00:00:00 2001 From: achyutjhunjhunwala Date: Wed, 3 Jul 2024 14:57:42 +0200 Subject: [PATCH 08/12] Fixed missing type change --- .../state_machines/dataset_quality_controller/src/types.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts index 6f6fc1fab5285..1454c098f9783 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/types.ts @@ -158,6 +158,10 @@ export type DatasetQualityControllerTypeState = value: 'flyout.initializing.dataStreamSettings.initializeIntegrations.integrationDashboards.unauthorized'; context: DefaultDatasetQualityStateContext; } + | { + value: 'flyout.initializing.dataStreamSettings.initializeIntegrations.integrationDetails.done'; + context: DefaultDatasetQualityStateContext; + } | { value: 'flyout.initializing.dataStreamDetails.fetching'; context: DefaultDatasetQualityStateContext; From f91a8d5310b1ab66394008e9b9c1d977e86054e4 Mon Sep 17 00:00:00 2001 From: achyutjhunjhunwala Date: Wed, 3 Jul 2024 15:40:05 +0200 Subject: [PATCH 09/12] Fix API integration tests --- x-pack/plugins/observability_solution/dataset_quality/README.md | 2 +- .../server/routes/data_streams/get_data_stream_details/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/observability_solution/dataset_quality/README.md b/x-pack/plugins/observability_solution/dataset_quality/README.md index d000c5697b1d3..25f01ceb6fa60 100755 --- a/x-pack/plugins/observability_solution/dataset_quality/README.md +++ b/x-pack/plugins/observability_solution/dataset_quality/README.md @@ -47,7 +47,7 @@ Once the tests finish, the instances will be terminated. node x-pack/plugins/observability_solution/dataset_quality/scripts/api --server # run tests -node x-pack/plugins/observability_solution/dataset_quality/scripts/api --runner --grep-files=error_group_list +node x-pack/plugins/observability_solution/dataset_quality/scripts/api --runner --grep-files=data_stream_settings.spec.ts ``` diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts index 7bdf1aace34cb..d89bb83867d10 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_data_stream_details/index.ts @@ -34,7 +34,7 @@ export async function getDataStreamSettings({ // Getting the 1st item from the data streams endpoint as we will be passing the exact DS name const [dataStreamInfo] = await dataStreamService.getMatchingDataStreams(esClient, dataStream); - const integration = dataStreamInfo._meta?.package?.name; + const integration = dataStreamInfo?._meta?.package?.name; return { createdOn, From 4171d8e5794da57696b6f5eaf069e92237fcb609 Mon Sep 17 00:00:00 2001 From: achyutjhunjhunwala Date: Wed, 3 Jul 2024 16:22:14 +0200 Subject: [PATCH 10/12] Add logic for E2E tests, where the Flyout is marked ready once the integrations have loaded --- .../public/components/flyout/header.tsx | 6 +++++- x-pack/test/functional/page_objects/dataset_quality.ts | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx index 300d4c6660557..5fc66f79b79ba 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx @@ -47,7 +47,11 @@ export function Header({ return ( {loading ? ( - + ) : ( diff --git a/x-pack/test/functional/page_objects/dataset_quality.ts b/x-pack/test/functional/page_objects/dataset_quality.ts index dc580d2951c6a..7cb633a8113b6 100644 --- a/x-pack/test/functional/page_objects/dataset_quality.ts +++ b/x-pack/test/functional/page_objects/dataset_quality.ts @@ -96,6 +96,7 @@ export function DatasetQualityPageObject({ getPageObjects, getService }: FtrProv datasetQualityFlyoutFieldValue: 'datasetQualityFlyoutFieldValue', datasetQualityFlyoutFieldsListIntegrationDetails: 'datasetQualityFlyoutFieldsList-integration_details', + datasetQualityFlyoutIntegrationLoading: 'datasetQualityFlyoutIntegrationLoading', datasetQualityFlyoutIntegrationActionsButton: 'datasetQualityFlyoutIntegrationActionsButton', datasetQualityFlyoutIntegrationAction: (action: string) => `datasetQualityFlyoutIntegrationAction${action}`, @@ -163,6 +164,13 @@ export function DatasetQualityPageObject({ getPageObjects, getService }: FtrProv await find.waitForDeletedByCssSelector('.euiFlyoutBody .euiBasicTable-loading', 20 * 1000); }, + async waitUntilIntegrationsInFlyoutLoaded() { + await find.waitForDeletedByCssSelector( + '.euiSkeletonTitle .datasetQualityFlyoutIntegrationLoading', + 10 * 1000 + ); + }, + async waitUntilSummaryPanelLoaded(isStateful: boolean = true) { await testSubjects.missingOrFail(`datasetQuality-${texts.activeDatasets}-loading`); if (isStateful) { @@ -321,6 +329,8 @@ export function DatasetQualityPageObject({ getPageObjects, getService }: FtrProv if (isCollapsed) { await datasetExpandButton.click(); } + + await this.waitUntilIntegrationsInFlyoutLoaded(); }, async closeFlyout() { From 6e6717d6d1ba6f85d8c199ed1603b09db4787423 Mon Sep 17 00:00:00 2001 From: achyutjhunjhunwala Date: Wed, 3 Jul 2024 17:21:31 +0200 Subject: [PATCH 11/12] Add Integration tests --- .../common/config.ts | 3 ++ .../common/ftr_provider_context.ts | 3 +- .../common/integration_service.ts | 29 +++++++++++++ .../data_streams/data_stream_settings.spec.ts | 43 ++++++++++++++++++- 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 x-pack/test/dataset_quality_api_integration/common/integration_service.ts diff --git a/x-pack/test/dataset_quality_api_integration/common/config.ts b/x-pack/test/dataset_quality_api_integration/common/config.ts index e5a45b72d7f06..4f76c5d2b2047 100644 --- a/x-pack/test/dataset_quality_api_integration/common/config.ts +++ b/x-pack/test/dataset_quality_api_integration/common/config.ts @@ -22,6 +22,7 @@ import { import { createDatasetQualityApiClient } from './dataset_quality_api_supertest'; import { RegistryProvider } from './registry'; import { DatasetQualityFtrConfigName } from '../configs'; +import { PackageService } from './integration_service'; export interface DatasetQualityFtrConfig { name: DatasetQualityFtrConfigName; @@ -70,6 +71,7 @@ export interface CreateTest { context: InheritedFtrProviderContext ) => Promise; datasetQualityApiClient: (context: InheritedFtrProviderContext) => DatasetQualityApiClient; + packageService: PackageService; }; junit: { reportName: string }; esTestCluster: any; @@ -98,6 +100,7 @@ export function createTestConfig( servicesRequiredForTestAnalysis: ['datasetQualityFtrConfig', 'registry'], services: { ...services, + packageService: PackageService, datasetQualityFtrConfig: () => config, registry: RegistryProvider, logSynthtraceEsClient: (context: InheritedFtrProviderContext) => diff --git a/x-pack/test/dataset_quality_api_integration/common/ftr_provider_context.ts b/x-pack/test/dataset_quality_api_integration/common/ftr_provider_context.ts index 69de63c48402c..f48da8f57c18f 100644 --- a/x-pack/test/dataset_quality_api_integration/common/ftr_provider_context.ts +++ b/x-pack/test/dataset_quality_api_integration/common/ftr_provider_context.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { GenericFtrProviderContext } from '@kbn/test'; +import { GenericFtrProviderContext, GenericFtrService } from '@kbn/test'; import { FtrProviderContext as InheritedFtrProviderContext } from '../../api_integration/ftr_provider_context'; import { DatasetQualityServices } from './config'; @@ -18,3 +18,4 @@ export type InheritedServices = InheritedFtrProviderContext extends GenericFtrPr export type { InheritedFtrProviderContext }; export type FtrProviderContext = GenericFtrProviderContext; +export class FtrService extends GenericFtrService {} diff --git a/x-pack/test/dataset_quality_api_integration/common/integration_service.ts b/x-pack/test/dataset_quality_api_integration/common/integration_service.ts new file mode 100644 index 0000000000000..a3c5916c43ff0 --- /dev/null +++ b/x-pack/test/dataset_quality_api_integration/common/integration_service.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. + */ +import { FtrService } from './ftr_provider_context'; + +export interface IntegrationPackage { + name: string; + version: string; +} + +export class PackageService extends FtrService { + private readonly supertest = this.ctx.getService('supertest'); + + async uninstallPackage({ name, version }: IntegrationPackage) { + return this.supertest + .delete(`/api/fleet/epm/packages/${name}/${version}`) + .set('kbn-xsrf', 'xxxx'); + } + + async installPackage({ name, version }: IntegrationPackage) { + return this.supertest + .post(`/api/fleet/epm/packages/${name}/${version}`) + .set('kbn-xsrf', 'xxxx') + .send({ force: true }); + } +} diff --git a/x-pack/test/dataset_quality_api_integration/tests/data_streams/data_stream_settings.spec.ts b/x-pack/test/dataset_quality_api_integration/tests/data_streams/data_stream_settings.spec.ts index e6f75d53b6c77..e5b38d2463cb0 100644 --- a/x-pack/test/dataset_quality_api_integration/tests/data_streams/data_stream_settings.spec.ts +++ b/x-pack/test/dataset_quality_api_integration/tests/data_streams/data_stream_settings.spec.ts @@ -21,13 +21,19 @@ export default function ApiTest({ getService }: FtrProviderContext) { const synthtrace = getService('logSynthtraceEsClient'); const esClient = getService('es'); const datasetQualityApiClient = getService('datasetQualityApiClient'); + const pkgService = getService('packageService'); const start = '2023-12-11T18:00:00.000Z'; const end = '2023-12-11T18:01:00.000Z'; const type = 'logs'; - const dataset = 'nginx.access'; + const dataset = 'synth.1'; + const integrationDataset = 'apache.access'; const namespace = 'default'; const serviceName = 'my-service'; const hostName = 'synth-host'; + const pkg = { + name: 'apache', + version: '1.14.0', + }; async function callApiAs(user: DatasetQualityApiClientKey, dataStream: string) { return await datasetQualityApiClient[user]({ @@ -43,6 +49,27 @@ export default function ApiTest({ getService }: FtrProviderContext) { registry.when('DataStream Settings', { config: 'basic' }, () => { describe('gets the data stream settings', () => { before(async () => { + // Install Integration and ingest logs for it + await pkgService.installPackage(pkg); + await synthtrace.index([ + timerange(start, end) + .interval('1m') + .rate(1) + .generator((timestamp) => + log + .create() + .message('This is a log message') + .timestamp(timestamp) + .dataset(integrationDataset) + .namespace(namespace) + .defaults({ + 'log.file.path': '/my-service.log', + 'service.name': serviceName, + 'host.name': hostName, + }) + ), + ]); + // Ingest basic logs await synthtrace.index([ timerange(start, end) .interval('1m') @@ -98,8 +125,22 @@ export default function ApiTest({ getService }: FtrProviderContext) { expect(resp.body.createdOn).to.be(Number(dataStreamSettings?.index?.creation_date)); }); + it('returns "createdOn" and "integration" correctly when available', async () => { + const dataStreamSettings = await getDataStreamSettingsOfEarliestIndex( + esClient, + `${type}-${integrationDataset}-${namespace}` + ); + const resp = await callApiAs( + 'datasetQualityLogsUser', + `${type}-${integrationDataset}-${namespace}` + ); + expect(resp.body.createdOn).to.be(Number(dataStreamSettings?.index?.creation_date)); + expect(resp.body.integration).to.be('apache'); + }); + after(async () => { await synthtrace.clean(); + await pkgService.uninstallPackage(pkg); }); }); }); From b15f8225783e4dc2d24449e770eae5c29ae26fcf Mon Sep 17 00:00:00 2001 From: achyutjhunjhunwala Date: Thu, 4 Jul 2024 11:02:13 +0200 Subject: [PATCH 12/12] Fixing a checktype issue --- .../common/config.ts | 4 +-- .../common/integration_service.ts | 29 ------------------ .../common/package_service.ts | 30 +++++++++++++++++++ 3 files changed, 32 insertions(+), 31 deletions(-) delete mode 100644 x-pack/test/dataset_quality_api_integration/common/integration_service.ts create mode 100644 x-pack/test/dataset_quality_api_integration/common/package_service.ts diff --git a/x-pack/test/dataset_quality_api_integration/common/config.ts b/x-pack/test/dataset_quality_api_integration/common/config.ts index 4f76c5d2b2047..e297d8eaf0354 100644 --- a/x-pack/test/dataset_quality_api_integration/common/config.ts +++ b/x-pack/test/dataset_quality_api_integration/common/config.ts @@ -22,7 +22,7 @@ import { import { createDatasetQualityApiClient } from './dataset_quality_api_supertest'; import { RegistryProvider } from './registry'; import { DatasetQualityFtrConfigName } from '../configs'; -import { PackageService } from './integration_service'; +import { PackageService } from './package_service'; export interface DatasetQualityFtrConfig { name: DatasetQualityFtrConfigName; @@ -71,7 +71,7 @@ export interface CreateTest { context: InheritedFtrProviderContext ) => Promise; datasetQualityApiClient: (context: InheritedFtrProviderContext) => DatasetQualityApiClient; - packageService: PackageService; + packageService: ({ getService }: FtrProviderContext) => ReturnType; }; junit: { reportName: string }; esTestCluster: any; diff --git a/x-pack/test/dataset_quality_api_integration/common/integration_service.ts b/x-pack/test/dataset_quality_api_integration/common/integration_service.ts deleted file mode 100644 index a3c5916c43ff0..0000000000000 --- a/x-pack/test/dataset_quality_api_integration/common/integration_service.ts +++ /dev/null @@ -1,29 +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 { FtrService } from './ftr_provider_context'; - -export interface IntegrationPackage { - name: string; - version: string; -} - -export class PackageService extends FtrService { - private readonly supertest = this.ctx.getService('supertest'); - - async uninstallPackage({ name, version }: IntegrationPackage) { - return this.supertest - .delete(`/api/fleet/epm/packages/${name}/${version}`) - .set('kbn-xsrf', 'xxxx'); - } - - async installPackage({ name, version }: IntegrationPackage) { - return this.supertest - .post(`/api/fleet/epm/packages/${name}/${version}`) - .set('kbn-xsrf', 'xxxx') - .send({ force: true }); - } -} diff --git a/x-pack/test/dataset_quality_api_integration/common/package_service.ts b/x-pack/test/dataset_quality_api_integration/common/package_service.ts new file mode 100644 index 0000000000000..0449fd9f921dd --- /dev/null +++ b/x-pack/test/dataset_quality_api_integration/common/package_service.ts @@ -0,0 +1,30 @@ +/* + * 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 { FtrProviderContext } from './ftr_provider_context'; + +interface IntegrationPackage { + name: string; + version: string; +} + +export function PackageService({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + + function uninstallPackage({ name, version }: IntegrationPackage) { + return supertest.delete(`/api/fleet/epm/packages/${name}/${version}`).set('kbn-xsrf', 'xxxx'); + } + + function installPackage({ name, version }: IntegrationPackage) { + return supertest + .post(`/api/fleet/epm/packages/${name}/${version}`) + .set('kbn-xsrf', 'xxxx') + .send({ force: true }); + } + + return { uninstallPackage, installPackage }; +}