diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality/filters/filters.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality/filters/filters.tsx index 5e2c4d0b57516..4c63b8480d3b7 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality/filters/filters.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/dataset_quality/filters/filters.tsx @@ -34,6 +34,10 @@ const typesNoneMatching = i18n.translate('xpack.datasetQuality.selector.types.no defaultMessage: 'No types found', }); +const typesNoneAvailable = i18n.translate('xpack.datasetQuality.selector.types.noneAvailable', { + defaultMessage: 'No types available', +}); + // Allow for lazy loading // eslint-disable-next-line import/no-default-export export default function Filters() { @@ -88,6 +92,7 @@ export default function Filters() { label={typesLabel} searchPlaceholder={typesSearchPlaceholder} noneMatchingMessage={typesNoneMatching} + noneAvailableMessage={typesNoneAvailable} options={types} onOptionsChange={onTypesChange} /> diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_telemetry.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_telemetry.tsx index 1b3629825fc76..c473495c0a661 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_telemetry.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_telemetry.tsx @@ -25,7 +25,6 @@ import { import { FlyoutDataset } from '../state_machines/dataset_quality_controller'; import { useDatasetQualityContext } from '../components/dataset_quality/context'; import { useDatasetQualityFilters } from './use_dataset_quality_filters'; -import { flattenStats } from '../utils/flatten_stats'; import { TimeRangeConfig } from '../../common/types'; export const useRedirectLinkTelemetry = ({ @@ -113,7 +112,7 @@ export const useDatasetTelemetry = () => { foundDataset, sort, appliedFilters, - flattenStats(nonAggregatableDatasets).flat(), + nonAggregatableDatasets, isIgnoredFilter, canUserViewIntegrations ); 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 fc347c64a7bde..1e75088853d33 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 @@ -39,7 +39,7 @@ export class DataStreamsStatsClient implements IDataStreamsStatsClient { const response = await this.http .get('/internal/dataset_quality/data_streams/stats', { query: { - datasetQuery: params.datasetQuery, + ...params, types: rison.encodeArray(types), }, }) @@ -89,6 +89,7 @@ export class DataStreamsStatsClient implements IDataStreamsStatsClient { .get('/internal/dataset_quality/data_streams/non_aggregatable', { query: { ...params, + types: rison.encodeArray(params.types), }, }) .catch((error) => { diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/defaults.ts b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/defaults.ts index 4c9d96d0f0033..821bb7cc85972 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/defaults.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/state_machines/dataset_quality_controller/src/defaults.ts @@ -38,7 +38,7 @@ export const DEFAULT_CONTEXT: DefaultDatasetQualityControllerState = { canMonitor: true, canViewIntegrations: true, }, - dataStreamStats: DEFAULT_DICTIONARY_TYPE, + dataStreamStats: [], degradedDocStats: DEFAULT_DICTIONARY_TYPE, filters: { inactive: true, @@ -71,5 +71,5 @@ export const DEFAULT_CONTEXT: DefaultDatasetQualityControllerState = { }, datasets: [], isSizeStatsAvailable: true, - nonAggregatableDatasets: DEFAULT_DICTIONARY_TYPE, + nonAggregatableDatasets: [], }; 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 3f3ab8959a3cb..e70c950580f06 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 @@ -23,7 +23,6 @@ import { DataStreamDetails, DataStreamStatServiceResponse, DataStreamDegradedDocsStatServiceResponse, - GetDataStreamsStatsQuery, } from '../../../../common/data_streams_stats'; import { DataStreamType } from '../../../../common/types'; import { dataStreamPartsToIndexName } from '../../../../common/utils'; @@ -100,14 +99,6 @@ export const createPureDatasetQualityControllerStateMachine = ( loaded: {}, }, on: { - SAVE_DATASTREAM_STATS: { - target: 'datasets.loaded', - actions: ['storeDataStreamStats', 'storeDatasets'], - }, - NOTIFY_DATASTREAM_STATS_FAILED: { - target: 'datasets.loaded', - actions: ['notifyFetchDatasetStatsFailed'], - }, UPDATE_TIME_RANGE: { target: 'datasets.fetching', actions: ['storeTimeRange'], @@ -156,28 +147,28 @@ export const createPureDatasetQualityControllerStateMachine = ( initial: 'fetching', states: { fetching: { - ...generateInvokePerType({ + invoke: { src: 'loadNonAggregatableDatasets', - }), + onDone: { + target: 'loaded', + actions: ['storeNonAggregatableDatasets'], + }, + onError: [ + { + target: 'unauthorized', + cond: 'checkIfActionForbidden', + }, + { + target: 'loaded', + actions: ['notifyFetchNonAggregatableDatasetsFailed'], + }, + ], + }, }, loaded: {}, unauthorized: { type: 'final' }, }, on: { - SAVE_NON_AGGREGATABLE_DATASETS: { - target: 'nonAggregatableDatasets.loaded', - actions: ['storeNonAggregatableDatasets'], - }, - NOTIFY_NON_AGGREGATABLE_DATASETS_FAILED: [ - { - target: 'nonAggregatableDatasets.unauthorized', - cond: 'checkIfActionForbidden', - }, - { - target: 'nonAggregatableDatasets.loaded', - actions: ['notifyFetchNonAggregatableDatasetsFailed'], - }, - ], UPDATE_TIME_RANGE: { target: 'nonAggregatableDatasets.fetching', }, @@ -630,31 +621,18 @@ export const createPureDatasetQualityControllerStateMachine = ( }), resetFlyoutOptions: assign(() => ({ flyout: DEFAULT_CONTEXT.flyout })), storeDataStreamStats: assign( - (context, event: DoneInvokeEvent, meta) => { - const type = meta._event.origin as DataStreamType; - + (_context, event: DoneInvokeEvent) => { const dataStreamStats = event.data.dataStreamsStats as DataStreamStat[]; + const datasetUserPrivileges = event.data.datasetUserPrivileges; // Check if any DataStreamStat has null; to check for serverless const isSizeStatsAvailable = !dataStreamStats.length || dataStreamStats.some((stat) => stat.totalDocs !== null); return { - dataStreamStats: { - ...context.dataStreamStats, - [type]: dataStreamStats, - }, + dataStreamStats, isSizeStatsAvailable, - datasetUserPrivileges: { - canMonitor: - context.datasetUserPrivileges.canMonitor && - event.data.datasetUserPrivileges.canMonitor, - canRead: - context.datasetUserPrivileges.canRead && event.data.datasetUserPrivileges.canRead, - canViewIntegrations: - context.datasetUserPrivileges.canViewIntegrations && - event.data.datasetUserPrivileges.canViewIntegrations, - }, + datasetUserPrivileges, }; } ), @@ -682,16 +660,9 @@ export const createPureDatasetQualityControllerStateMachine = ( }; }), storeNonAggregatableDatasets: assign( - (context, event: DoneInvokeEvent, meta) => { - const type = meta._event.origin as DataStreamType; - - return { - nonAggregatableDatasets: { - ...context.nonAggregatableDatasets, - [type]: event.data.datasets, - }, - }; - } + (_context, event: DoneInvokeEvent) => ({ + nonAggregatableDatasets: event.data.datasets, + }) ), storeDataStreamSettings: assign((context, event) => { return 'data' in event @@ -832,7 +803,7 @@ export const createDatasetQualityControllerStateMachine = ({ services: { loadDataStreamStats: (context, _event) => dataStreamStatsClient.getDataStreamsStats({ - types: context.filters.types as GetDataStreamsStatsQuery['types'], + types: context.filters.types as DataStreamType[], datasetQuery: context.filters.query, }), loadDegradedDocs: @@ -861,34 +832,15 @@ export const createDatasetQualityControllerStateMachine = ({ }); } }, - loadNonAggregatableDatasets: - (context, _event, { data: { type } }) => - async (send) => { - try { - const { startDate: start, endDate: end } = getDateISORange(context.filters.timeRange); + loadNonAggregatableDatasets: (context) => { + const { startDate: start, endDate: end } = getDateISORange(context.filters.timeRange); - const nonAggregatableDatasets = await (isTypeSelected(type, context) - ? dataStreamStatsClient.getNonAggregatableDatasets({ - type, - start, - end, - }) - : Promise.resolve({ - aggregatable: true, - datasets: [], - })); - - send({ - type: 'SAVE_NON_AGGREGATABLE_DATASETS', - data: nonAggregatableDatasets, - }); - } catch (e) { - send({ - type: 'NOTIFY_NON_AGGREGATABLE_DATASETS_FAILED', - data: e, - }); - } - }, + return dataStreamStatsClient.getNonAggregatableDatasets({ + types: context.filters.types as DataStreamType[], + start, + end, + }); + }, loadDegradedFieldsPerDataStream: (context) => { if (!context.flyout.dataset || !context.flyout.insightsTimeRange) { return Promise.resolve({}); @@ -981,7 +933,7 @@ export const createDatasetQualityControllerStateMachine = ({ ); return dataStreamStatsClient.getNonAggregatableDatasets({ - type: type as DataStreamType, + types: [type as DataStreamType], start, end, dataStream: dataStreamPartsToIndexName({ 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 88b744d7be0a1..d3506494b33f8 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 @@ -83,7 +83,7 @@ export type DictionaryType = Record; export interface WithDataStreamStats { datasetUserPrivileges: DatasetUserPrivileges; - dataStreamStats: DictionaryType; + dataStreamStats: DataStreamStatType[]; } export interface WithDegradedDocs { @@ -91,7 +91,7 @@ export interface WithDegradedDocs { } export interface WithNonAggregatableDatasets { - nonAggregatableDatasets: DictionaryType; + nonAggregatableDatasets: string[]; } export interface WithDatasets { diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.test.ts b/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.test.ts index 5c44342229d9f..6f2e46baacf8c 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.test.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.test.ts @@ -8,6 +8,7 @@ import { indexNameToDataStreamParts } from '../../common/utils'; import { Integration } from '../../common/data_streams_stats/integration'; import { generateDatasets } from './generate_datasets'; +import { DataStreamStatType } from '../../common/data_streams_stats'; import { DEFAULT_DICTIONARY_TYPE } from '../state_machines/dataset_quality_controller'; describe('generateDatasets', () => { @@ -34,30 +35,27 @@ describe('generateDatasets', () => { }, ]; - const dataStreamStats = { - ...DEFAULT_DICTIONARY_TYPE, - logs: [ - { - name: 'logs-system.application-default', - lastActivity: 1712911241117, - size: '82.1kb', - sizeBytes: 84160, - integration: 'system', - userPrivileges: { - canMonitor: true, - }, + const dataStreamStats: DataStreamStatType[] = [ + { + name: 'logs-system.application-default', + lastActivity: 1712911241117, + size: '82.1kb', + sizeBytes: 84160, + integration: 'system', + userPrivileges: { + canMonitor: true, }, - { - name: 'logs-synth-default', - lastActivity: 1712911241117, - size: '62.5kb', - sizeBytes: 64066, - userPrivileges: { - canMonitor: true, - }, + }, + { + name: 'logs-synth-default', + lastActivity: 1712911241117, + size: '62.5kb', + sizeBytes: 64066, + userPrivileges: { + canMonitor: true, }, - ], - }; + }, + ]; const degradedDocs = { ...DEFAULT_DICTIONARY_TYPE, @@ -84,15 +82,13 @@ describe('generateDatasets', () => { expect(datasets).toEqual([ { - ...dataStreamStats.logs[0], - name: indexNameToDataStreamParts(dataStreamStats.logs[0].name).dataset, - namespace: indexNameToDataStreamParts(dataStreamStats.logs[0].name).namespace, + ...dataStreamStats[0], + name: indexNameToDataStreamParts(dataStreamStats[0].name).dataset, + namespace: indexNameToDataStreamParts(dataStreamStats[0].name).namespace, title: - integrations[0].datasets[ - indexNameToDataStreamParts(dataStreamStats.logs[0].name).dataset - ], - type: indexNameToDataStreamParts(dataStreamStats.logs[0].name).type, - rawName: dataStreamStats.logs[0].name, + integrations[0].datasets[indexNameToDataStreamParts(dataStreamStats[0].name).dataset], + type: indexNameToDataStreamParts(dataStreamStats[0].name).type, + rawName: dataStreamStats[0].name, integration: integrations[0], degradedDocs: { percentage: degradedDocs.logs[0].percentage, @@ -102,12 +98,12 @@ describe('generateDatasets', () => { }, }, { - ...dataStreamStats.logs[1], - name: indexNameToDataStreamParts(dataStreamStats.logs[1].name).dataset, - namespace: indexNameToDataStreamParts(dataStreamStats.logs[1].name).namespace, - title: indexNameToDataStreamParts(dataStreamStats.logs[1].name).dataset, - type: indexNameToDataStreamParts(dataStreamStats.logs[1].name).type, - rawName: dataStreamStats.logs[1].name, + ...dataStreamStats[1], + name: indexNameToDataStreamParts(dataStreamStats[1].name).dataset, + namespace: indexNameToDataStreamParts(dataStreamStats[1].name).namespace, + title: indexNameToDataStreamParts(dataStreamStats[1].name).dataset, + type: indexNameToDataStreamParts(dataStreamStats[1].name).type, + rawName: dataStreamStats[1].name, degradedDocs: { count: 0, percentage: 0, @@ -119,7 +115,7 @@ describe('generateDatasets', () => { }); it('merges integrations information with degradedDocs', () => { - const datasets = generateDatasets(DEFAULT_DICTIONARY_TYPE, degradedDocs, integrations); + const datasets = generateDatasets(undefined, degradedDocs, integrations); expect(datasets).toEqual([ { @@ -169,15 +165,13 @@ describe('generateDatasets', () => { expect(datasets).toEqual([ { - ...dataStreamStats.logs[0], - name: indexNameToDataStreamParts(dataStreamStats.logs[0].name).dataset, - namespace: indexNameToDataStreamParts(dataStreamStats.logs[0].name).namespace, + ...dataStreamStats[0], + name: indexNameToDataStreamParts(dataStreamStats[0].name).dataset, + namespace: indexNameToDataStreamParts(dataStreamStats[0].name).namespace, title: - integrations[0].datasets[ - indexNameToDataStreamParts(dataStreamStats.logs[0].name).dataset - ], - type: indexNameToDataStreamParts(dataStreamStats.logs[0].name).type, - rawName: dataStreamStats.logs[0].name, + integrations[0].datasets[indexNameToDataStreamParts(dataStreamStats[0].name).dataset], + type: indexNameToDataStreamParts(dataStreamStats[0].name).type, + rawName: dataStreamStats[0].name, integration: integrations[0], degradedDocs: { percentage: degradedDocs.logs[0].percentage, @@ -187,12 +181,12 @@ describe('generateDatasets', () => { }, }, { - ...dataStreamStats.logs[1], - name: indexNameToDataStreamParts(dataStreamStats.logs[1].name).dataset, - namespace: indexNameToDataStreamParts(dataStreamStats.logs[1].name).namespace, - title: indexNameToDataStreamParts(dataStreamStats.logs[1].name).dataset, - type: indexNameToDataStreamParts(dataStreamStats.logs[1].name).type, - rawName: dataStreamStats.logs[1].name, + ...dataStreamStats[1], + name: indexNameToDataStreamParts(dataStreamStats[1].name).dataset, + namespace: indexNameToDataStreamParts(dataStreamStats[1].name).namespace, + title: indexNameToDataStreamParts(dataStreamStats[1].name).dataset, + type: indexNameToDataStreamParts(dataStreamStats[1].name).type, + rawName: dataStreamStats[1].name, degradedDocs: { percentage: degradedDocs.logs[1].percentage, count: degradedDocs.logs[1].count, @@ -206,32 +200,27 @@ describe('generateDatasets', () => { it('merges integration information with dataStreamStats when dataset is not an integration default one', () => { const dataset = 'logs-system.custom-default'; - const nonDefaultDatasets = { - ...DEFAULT_DICTIONARY_TYPE, - logs: [ - { - name: dataset, - lastActivity: 1712911241117, - size: '82.1kb', - sizeBytes: 84160, - integration: 'system', - userPrivileges: { - canMonitor: true, - }, - }, - ], + const nonDefaultDataset = { + name: dataset, + lastActivity: 1712911241117, + size: '82.1kb', + sizeBytes: 84160, + integration: 'system', + userPrivileges: { + canMonitor: true, + }, }; - const datasets = generateDatasets(nonDefaultDatasets, DEFAULT_DICTIONARY_TYPE, integrations); + const datasets = generateDatasets([nonDefaultDataset], DEFAULT_DICTIONARY_TYPE, integrations); expect(datasets).toEqual([ { - ...nonDefaultDatasets.logs[0], + ...nonDefaultDataset, title: indexNameToDataStreamParts(dataset).dataset, name: indexNameToDataStreamParts(dataset).dataset, namespace: indexNameToDataStreamParts(dataset).namespace, type: indexNameToDataStreamParts(dataset).type, - rawName: nonDefaultDatasets.logs[0].name, + rawName: nonDefaultDataset.name, integration: integrations[0], degradedDocs: { count: 0, diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.ts b/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.ts index 6364cdb21951a..fb479198bbac3 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/utils/generate_datasets.ts @@ -14,13 +14,11 @@ import { DictionaryType } from '../state_machines/dataset_quality_controller/src import { flattenStats } from './flatten_stats'; export function generateDatasets( - dataStreamStats: DictionaryType, + dataStreamStats: DataStreamStatType[] = [], degradedDocStats: DictionaryType, integrations: Integration[] ): DataStreamStat[] { - const dataStreams = flattenStats(dataStreamStats); - - if (!dataStreams.length && !integrations.length) { + if (!dataStreamStats.length && !integrations.length) { return []; } @@ -54,7 +52,7 @@ export function generateDatasets( const degradedDocs = flattenStats(degradedDocStats); - if (!dataStreams.length) { + if (!dataStreamStats.length) { return degradedDocs.map((degradedDocStat) => DataStreamStat.fromDegradedDocStat({ degradedDocStat, datasetIntegrationMap }) ); @@ -81,7 +79,7 @@ export function generateDatasets( {} ); - return dataStreams.map((dataStream) => { + return dataStreamStats?.map((dataStream) => { const dataset = DataStreamStat.create(dataStream); return { diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_non_aggregatable_data_streams.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_non_aggregatable_data_streams.ts index b59999d0c3c2e..6137bc5426f86 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_non_aggregatable_data_streams.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/get_non_aggregatable_data_streams.ts @@ -8,28 +8,29 @@ import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import { rangeQuery } from '@kbn/observability-plugin/server/utils/queries'; import { extractIndexNameFromBackingIndex } from '../../../common/utils'; -import { DEFAULT_DATASET_TYPE } from '../../../common/constants'; import { _IGNORED } from '../../../common/es_fields'; import { DataStreamType } from '../../../common/types'; import { createDatasetQualityESClient } from '../../utils'; export async function getNonAggregatableDataStreams({ esClient, - type = DEFAULT_DATASET_TYPE, + types, start, end, dataStream, }: { esClient: ElasticsearchClient; - type?: DataStreamType; + types: DataStreamType[]; start: number; end: number; dataStream?: string; }) { const datasetQualityESClient = createDatasetQualityESClient(esClient); + const dataStreamTypes = types.map((type) => `${type}-*-*`).join(','); + const response = await datasetQualityESClient.fieldCaps({ - index: dataStream ?? `${type}-*-*`, + index: dataStream ?? dataStreamTypes, fields: [_IGNORED], index_filter: { ...rangeQuery(start, end)[0], diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/routes.ts b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/routes.ts index 8895719325142..54a229cb790e7 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/routes.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/routes/data_streams/routes.ts @@ -52,8 +52,7 @@ const statsRoute = createDatasetQualityServerRoute({ const { items, datasetUserPrivileges } = await getDataStreams({ esClient, - types: typesRt.encode(params.query.types), - datasetQuery: params.query.datasetQuery, + ...params.query, uncategorisedOnly: false, }); @@ -118,7 +117,7 @@ const nonAggregatableDatasetsRoute = createDatasetQualityServerRoute({ params: t.type({ query: t.intersection([ rangeRt, - typeRt, + t.type({ types: typesRt }), t.partial({ dataStream: t.string, }), @@ -133,11 +132,36 @@ const nonAggregatableDatasetsRoute = createDatasetQualityServerRoute({ const esClient = coreContext.elasticsearch.client.asCurrentUser; + return await getNonAggregatableDataStreams({ + esClient, + ...params.query, + }); + }, +}); + +const nonAggregatableDatasetRoute = createDatasetQualityServerRoute({ + endpoint: 'GET /internal/dataset_quality/data_streams/{dataStream}/non_aggregatable', + params: t.type({ + path: t.type({ + dataStream: t.string, + }), + query: t.intersection([rangeRt, typeRt]), + }), + options: { + tags: [], + }, + async handler(resources): Promise { + const { context, params } = resources; + const coreContext = await context.core; + + const esClient = coreContext.elasticsearch.client.asCurrentUser; + await datasetQualityPrivileges.throwIfCannotReadDataset(esClient, params.query.type); return await getNonAggregatableDataStreams({ esClient, ...params.query, + types: [params.query.type], }); }, }); @@ -232,6 +256,7 @@ export const dataStreamsRouteRepository = { ...statsRoute, ...degradedDocsRoute, ...nonAggregatableDatasetsRoute, + ...nonAggregatableDatasetRoute, ...degradedFieldsRoute, ...dataStreamDetailsRoute, ...dataStreamSettingsRoute, diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/types/default_api_types.ts b/x-pack/plugins/observability_solution/dataset_quality/server/types/default_api_types.ts index 02f570da70e11..c2b746e655280 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/types/default_api_types.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/types/default_api_types.ts @@ -7,22 +7,22 @@ import { isoToEpochRt } from '@kbn/io-ts-utils'; import * as t from 'io-ts'; -import rison from '@kbn/rison'; import { DataStreamType, dataStreamTypesRt } from '../../common/types'; -export const typeRt = t.partial({ +export const typeRt = t.type({ type: dataStreamTypesRt, }); -export const typesRt = new t.Type( +export const typesRt = new t.Type( 'typesRt', - (input: unknown): input is string => - typeof input === 'string' && input.split(',').every((value) => dataStreamTypesRt.is(value)), + (input: unknown): input is DataStreamType[] => + (typeof input === 'string' && input.split(',').every((value) => dataStreamTypesRt.is(value))) || + (Array.isArray(input) && input.every((value) => dataStreamTypesRt.is(value))), (input, context) => typeof input === 'string' && input.split(',').every((value) => dataStreamTypesRt.is(value)) - ? t.success(input) + ? t.success(input.split(',') as DataStreamType[]) : t.failure(input, context), - (input) => rison.decodeArray(input) as DataStreamType[] + t.identity ); export const rangeRt = t.type({ diff --git a/x-pack/test/dataset_quality_api_integration/tests/data_streams/stats.spec.ts b/x-pack/test/dataset_quality_api_integration/tests/data_streams/stats.spec.ts index b01dc1f2375aa..5d38693d8db32 100644 --- a/x-pack/test/dataset_quality_api_integration/tests/data_streams/stats.spec.ts +++ b/x-pack/test/dataset_quality_api_integration/tests/data_streams/stats.spec.ts @@ -22,7 +22,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { endpoint: 'GET /internal/dataset_quality/data_streams/stats', params: { query: { - type: 'logs', + types: ['logs'], datasetQuery: '-', }, },