diff --git a/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts b/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts index c684c050036124f..6d4d107adb796d3 100644 --- a/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts @@ -6,12 +6,12 @@ */ import { keyBy, keys, merge } from 'lodash'; -import type { RequestHandler, SavedObjectsClientContract } from 'src/core/server'; +import type { RequestHandler, SavedObjectsBulkGetObject } from 'src/core/server'; import type { DataStream } from '../../types'; -import { KibanaAssetType, KibanaSavedObjectType } from '../../../common'; +import { KibanaSavedObjectType } from '../../../common'; import type { GetDataStreamsResponse } from '../../../common'; -import { getPackageSavedObjects, getKibanaSavedObject } from '../../services/epm/packages/get'; +import { getPackageSavedObjects } from '../../services/epm/packages/get'; import { defaultIngestErrorHandler } from '../../errors'; const DATA_STREAM_INDEX_PATTERN = 'logs-*-*,metrics-*-*,traces-*-*'; @@ -78,6 +78,40 @@ export const getListHandler: RequestHandler = async (context, request, response) const packageSavedObjectsByName = keyBy(packageSavedObjects.saved_objects, 'id'); const packageMetadata: any = {}; + // Get dashboard information for all packages + const dashboardIdsByPackageName = packageSavedObjects.saved_objects.reduce< + Record + >((allDashboards, pkgSavedObject) => { + const dashboards: string[] = []; + (pkgSavedObject.attributes?.installed_kibana || []).forEach((o) => { + if (o.type === KibanaSavedObjectType.dashboard) { + dashboards.push(o.id); + } + }); + allDashboards[pkgSavedObject.id] = dashboards; + return allDashboards; + }, {}); + const allDashboardSavedObjects = await context.core.savedObjects.client.bulkGet<{ + title?: string; + }>( + Object.values(dashboardIdsByPackageName).reduce( + (allDashboards, dashboardIds) => { + return allDashboards.concat( + dashboardIds.map((id) => ({ + id, + type: KibanaSavedObjectType.dashboard, + fields: ['title'], + })) + ); + }, + [] + ) + ); + const allDashboardSavedObjectsById = keyBy( + allDashboardSavedObjects.saved_objects, + (dashboardSavedObject) => dashboardSavedObject.id + ); + // Query additional information for each data stream const dataStreamPromises = dataStreamNames.map(async (dataStreamName) => { const dataStream = dataStreams[dataStreamName]; @@ -158,19 +192,23 @@ export const getListHandler: RequestHandler = async (context, request, response) // - and we didn't pick the metadata in an earlier iteration of this map() if (!packageMetadata[pkgName]) { // then pick the dashboards from the package saved object - const dashboards = - pkgSavedObject.attributes?.installed_kibana?.filter( - (o) => o.type === KibanaSavedObjectType.dashboard - ) || []; - // and then pick the human-readable titles from the dashboard saved objects - const enhancedDashboards = await getEnhancedDashboards( - context.core.savedObjects.client, - dashboards - ); + const packageDashboardIds = dashboardIdsByPackageName[pkgName] || []; + const packageDashboards = packageDashboardIds.reduce< + Array<{ id: string; title: string }> + >((dashboards, dashboardId) => { + const dashboard = allDashboardSavedObjectsById[dashboardId]; + if (dashboard) { + dashboards.push({ + id: dashboard.id, + title: dashboard.attributes.title || dashboard.id, + }); + } + return dashboards; + }, []); packageMetadata[pkgName] = { version: pkgSavedObject.attributes?.version || '', - dashboards: enhancedDashboards, + dashboards: packageDashboards, }; } @@ -195,21 +233,3 @@ export const getListHandler: RequestHandler = async (context, request, response) return defaultIngestErrorHandler({ error, response }); } }; - -const getEnhancedDashboards = async ( - savedObjectsClient: SavedObjectsClientContract, - dashboards: any[] -) => { - const dashboardsPromises = dashboards.map(async (db) => { - const dbSavedObject: any = await getKibanaSavedObject( - savedObjectsClient, - KibanaAssetType.dashboard, - db.id - ); - return { - id: db.id, - title: dbSavedObject.attributes?.title || db.id, - }; - }); - return await Promise.all(dashboardsPromises); -}; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.ts index 98dbd3bd5716217..706b2679ed2eb9c 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.ts @@ -19,7 +19,6 @@ import type { RegistryPackage, EpmPackageAdditions, } from '../../../../common/types'; -import type { KibanaAssetType } from '../../../types'; import type { Installation, PackageInfo } from '../../../types'; import { IngestManagerError } from '../../../errors'; import { appContextService } from '../../'; @@ -260,11 +259,3 @@ function sortByName(a: { name: string }, b: { name: string }) { return 0; } } - -export async function getKibanaSavedObject( - savedObjectsClient: SavedObjectsClientContract, - type: KibanaAssetType, - id: string -) { - return savedObjectsClient.get(type, id); -}