diff --git a/x-pack/legacy/plugins/apm/index.ts b/x-pack/legacy/plugins/apm/index.ts index c52e6742ddae5..712584ced3110 100644 --- a/x-pack/legacy/plugins/apm/index.ts +++ b/x-pack/legacy/plugins/apm/index.ts @@ -11,7 +11,6 @@ import { APMPluginContract } from '../../../plugins/apm/server'; import { LegacyPluginInitializer } from '../../../../src/legacy/types'; import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/utils'; import mappings from './mappings.json'; -import { makeApmUsageCollector } from './server/lib/apm_telemetry'; export const apm: LegacyPluginInitializer = kibana => { return new kibana.Plugin({ @@ -109,11 +108,9 @@ export const apm: LegacyPluginInitializer = kibana => { } } }); - const { usageCollection } = server.newPlatform.setup.plugins; - makeApmUsageCollector(usageCollection, server); + const apmPlugin = server.newPlatform.setup.plugins .apm as APMPluginContract; - apmPlugin.registerLegacyAPI({ server }); } }); diff --git a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/index.test.ts b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/index.test.ts index 26cae303542a4..ab4148340c5d4 100644 --- a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/index.test.ts +++ b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/index.test.ts @@ -45,25 +45,10 @@ describe('apm_telemetry', () => { }); describe('storeApmServicesTelemetry', () => { - let server: any; let apmTelemetry: SavedObjectAttributes; - let savedObjectsClientInstance: any; + let savedObjectsClient: any; beforeEach(() => { - savedObjectsClientInstance = { create: jest.fn() }; - const callWithInternalUser = jest.fn(); - const internalRepository = jest.fn(); - server = { - savedObjects: { - SavedObjectsClient: jest.fn(() => savedObjectsClientInstance), - getSavedObjectsRepository: jest.fn(() => internalRepository) - }, - plugins: { - elasticsearch: { - getCluster: jest.fn(() => ({ callWithInternalUser })) - } - } - }; apmTelemetry = { has_any_services: true, services_per_agent: { @@ -72,30 +57,27 @@ describe('apm_telemetry', () => { 'js-base': 1 } }; + savedObjectsClient = { create: jest.fn() }; }); it('should call savedObjectsClient create with the given ApmTelemetry object', () => { - storeApmServicesTelemetry(server, apmTelemetry); - expect(savedObjectsClientInstance.create.mock.calls[0][1]).toBe( - apmTelemetry - ); + storeApmServicesTelemetry(savedObjectsClient, apmTelemetry); + expect(savedObjectsClient.create.mock.calls[0][1]).toBe(apmTelemetry); }); it('should call savedObjectsClient create with the apm-telemetry document type and ID', () => { - storeApmServicesTelemetry(server, apmTelemetry); - expect(savedObjectsClientInstance.create.mock.calls[0][0]).toBe( + storeApmServicesTelemetry(savedObjectsClient, apmTelemetry); + expect(savedObjectsClient.create.mock.calls[0][0]).toBe( APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE ); - expect(savedObjectsClientInstance.create.mock.calls[0][2].id).toBe( + expect(savedObjectsClient.create.mock.calls[0][2].id).toBe( APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID ); }); it('should call savedObjectsClient create with overwrite: true', () => { - storeApmServicesTelemetry(server, apmTelemetry); - expect(savedObjectsClientInstance.create.mock.calls[0][2].overwrite).toBe( - true - ); + storeApmServicesTelemetry(savedObjectsClient, apmTelemetry); + expect(savedObjectsClient.create.mock.calls[0][2].overwrite).toBe(true); }); }); }); diff --git a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/index.ts b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/index.ts index ddfb4144d9636..6a92cbdcdad76 100644 --- a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/index.ts +++ b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/index.ts @@ -5,14 +5,12 @@ */ import { countBy } from 'lodash'; -import { SavedObjectAttributes } from 'src/core/server'; +import { SavedObjectAttributes, SavedObjectsClient } from 'src/core/server'; import { isAgentName } from '../../../common/agent_name'; -import { getInternalSavedObjectsClient } from '../helpers/saved_objects_client'; import { APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE, APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID } from '../../../common/apm_saved_object_constants'; -import { APMLegacyServer } from '../../routes/typings'; import { UsageCollectionSetup } from '../../../../../../../src/plugins/usage_collection/server'; export function createApmTelementry( @@ -25,35 +23,31 @@ export function createApmTelementry( }; } +type ISavedObjectsClient = Pick; + export async function storeApmServicesTelemetry( - server: APMLegacyServer, + savedObjectsClient: ISavedObjectsClient, apmTelemetry: SavedObjectAttributes ) { - try { - const savedObjectsClient = getInternalSavedObjectsClient(server); - await savedObjectsClient.create( - APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE, - apmTelemetry, - { - id: APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID, - overwrite: true - } - ); - } catch (e) { - server.log(['error'], `Unable to save APM telemetry data: ${e.message}`); - } + return savedObjectsClient.create( + APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE, + apmTelemetry, + { + id: APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID, + overwrite: true + } + ); } export function makeApmUsageCollector( usageCollector: UsageCollectionSetup, - server: APMLegacyServer + savedObjectsRepository: ISavedObjectsClient ) { const apmUsageCollector = usageCollector.makeUsageCollector({ type: 'apm', fetch: async () => { - const internalSavedObjectsClient = getInternalSavedObjectsClient(server); try { - const apmTelemetrySavedObject = await internalSavedObjectsClient.get( + const apmTelemetrySavedObject = await savedObjectsRepository.get( APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE, APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID ); diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.test.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.test.ts deleted file mode 100644 index c685ffdd801dc..0000000000000 --- a/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.test.ts +++ /dev/null @@ -1,58 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getInternalSavedObjectsClient } from './saved_objects_client'; - -describe('saved_objects/client', () => { - describe('getSavedObjectsClient', () => { - let server: any; - let savedObjectsClientInstance: any; - let callWithInternalUser: any; - let internalRepository: any; - - beforeEach(() => { - savedObjectsClientInstance = { create: jest.fn() }; - callWithInternalUser = jest.fn(); - internalRepository = jest.fn(); - server = { - savedObjects: { - SavedObjectsClient: jest.fn(() => savedObjectsClientInstance), - getSavedObjectsRepository: jest.fn(() => internalRepository) - }, - plugins: { - elasticsearch: { - getCluster: jest.fn(() => ({ callWithInternalUser })) - } - } - }; - }); - - it('should use internal user "admin"', () => { - getInternalSavedObjectsClient(server); - - expect(server.plugins.elasticsearch.getCluster).toHaveBeenCalledWith( - 'admin' - ); - }); - - it('should call getSavedObjectsRepository with a cluster using the internal user context', () => { - getInternalSavedObjectsClient(server); - - expect( - server.savedObjects.getSavedObjectsRepository - ).toHaveBeenCalledWith(callWithInternalUser); - }); - - it('should return a SavedObjectsClient initialized with the saved objects internal repository', () => { - const internalSavedObjectsClient = getInternalSavedObjectsClient(server); - - expect(internalSavedObjectsClient).toBe(savedObjectsClientInstance); - expect(server.savedObjects.SavedObjectsClient).toHaveBeenCalledWith( - internalRepository - ); - }); - }); -}); diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.ts deleted file mode 100644 index ced6f77944b6c..0000000000000 --- a/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.ts +++ /dev/null @@ -1,16 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { APMLegacyServer } from '../../routes/typings'; - -export function getInternalSavedObjectsClient(server: APMLegacyServer) { - const { SavedObjectsClient, getSavedObjectsRepository } = server.savedObjects; - const { callWithInternalUser } = server.plugins.elasticsearch.getCluster( - 'admin' - ); - const internalRepository = getSavedObjectsRepository(callWithInternalUser); - return new SavedObjectsClient(internalRepository); -} diff --git a/x-pack/legacy/plugins/apm/server/lib/index_pattern/create_static_index_pattern.test.ts b/x-pack/legacy/plugins/apm/server/lib/index_pattern/create_static_index_pattern.test.ts index 2a31563b53c2c..861c8fe1ded66 100644 --- a/x-pack/legacy/plugins/apm/server/lib/index_pattern/create_static_index_pattern.test.ts +++ b/x-pack/legacy/plugins/apm/server/lib/index_pattern/create_static_index_pattern.test.ts @@ -6,17 +6,16 @@ import { createStaticIndexPattern } from './create_static_index_pattern'; import { Setup } from '../helpers/setup_request'; -import * as savedObjectsClient from '../helpers/saved_objects_client'; import * as HistoricalAgentData from '../services/get_services/has_historical_agent_data'; import { APMRequestHandlerContext } from '../../routes/typings'; function getMockContext(config: Record) { return ({ config, - __LEGACY: { - server: { - savedObjects: { - getSavedObjectsRepository: jest.fn() + core: { + savedObjects: { + client: { + create: jest.fn() } } } @@ -24,24 +23,13 @@ function getMockContext(config: Record) { } describe('createStaticIndexPattern', () => { - let createSavedObject: jest.Mock; - beforeEach(() => { - createSavedObject = jest.fn(); - jest - .spyOn(savedObjectsClient, 'getInternalSavedObjectsClient') - .mockReturnValue({ - create: createSavedObject - } as any); - }); - it(`should not create index pattern if 'xpack.apm.autocreateApmIndexPattern=false'`, async () => { const setup = {} as Setup; const context = getMockContext({ 'xpack.apm.autocreateApmIndexPattern': false }); await createStaticIndexPattern(setup, context); - - expect(createSavedObject).not.toHaveBeenCalled(); + expect(context.core.savedObjects.client.create).not.toHaveBeenCalled(); }); it(`should not create index pattern if no APM data is found`, async () => { @@ -56,7 +44,7 @@ describe('createStaticIndexPattern', () => { .mockResolvedValue(false); await createStaticIndexPattern(setup, context); - expect(createSavedObject).not.toHaveBeenCalled(); + expect(context.core.savedObjects.client.create).not.toHaveBeenCalled(); }); it(`should create index pattern`, async () => { @@ -71,6 +59,6 @@ describe('createStaticIndexPattern', () => { .mockResolvedValue(true); await createStaticIndexPattern(setup, context); - expect(createSavedObject).toHaveBeenCalled(); + expect(context.core.savedObjects.client.create).toHaveBeenCalled(); }); }); diff --git a/x-pack/legacy/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts b/x-pack/legacy/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts index fefaa30c8c36b..e5636d3a88a9b 100644 --- a/x-pack/legacy/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts +++ b/x-pack/legacy/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { getInternalSavedObjectsClient } from '../helpers/saved_objects_client'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import apmIndexPattern from '../../../../../../plugins/apm/server/tutorial/index_pattern.json'; import { APM_STATIC_INDEX_PATTERN_ID } from '../../../common/index_pattern_constants'; @@ -33,10 +32,8 @@ export async function createStaticIndexPattern( try { const apmIndexPatternTitle = config['apm_oss.indexPattern']; - const internalSavedObjectsClient = getInternalSavedObjectsClient( - context.__LEGACY.server - ); - await internalSavedObjectsClient.create( + const savedObjectsClient = context.core.savedObjects.client; + await savedObjectsClient.create( 'index-pattern', { ...apmIndexPattern.attributes, diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts b/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts index e7b2330b472d8..6356e5631ca7e 100644 --- a/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts +++ b/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts @@ -6,7 +6,7 @@ import { merge } from 'lodash'; import { Server } from 'hapi'; -import { SavedObjectsClientContract } from 'kibana/server'; +import { SavedObjectsClient } from 'src/core/server'; import { PromiseReturnType } from '../../../../typings/common'; import { APM_INDICES_SAVED_OBJECT_TYPE, @@ -15,6 +15,8 @@ import { import { APMConfig } from '../../../../../../../plugins/apm/server'; import { APMRequestHandlerContext } from '../../../routes/typings'; +type ISavedObjectsClient = Pick; + export interface ApmIndicesConfig { 'apm_oss.sourcemapIndices': string; 'apm_oss.errorIndices': string; @@ -32,7 +34,7 @@ export type ScopedSavedObjectsClient = ReturnType< >; async function getApmIndicesSavedObject( - savedObjectsClient: SavedObjectsClientContract + savedObjectsClient: ISavedObjectsClient ) { const apmIndices = await savedObjectsClient.get>( APM_INDICES_SAVED_OBJECT_TYPE, @@ -59,7 +61,7 @@ export async function getApmIndices({ savedObjectsClient }: { config: APMConfig; - savedObjectsClient: SavedObjectsClientContract; + savedObjectsClient: ISavedObjectsClient; }) { try { const apmIndicesSavedObject = await getApmIndicesSavedObject( diff --git a/x-pack/legacy/plugins/apm/server/routes/services.ts b/x-pack/legacy/plugins/apm/server/routes/services.ts index 18777183ea1de..8e8002a8e9975 100644 --- a/x-pack/legacy/plugins/apm/server/routes/services.ts +++ b/x-pack/legacy/plugins/apm/server/routes/services.ts @@ -33,7 +33,7 @@ export const servicesRoute = createRoute(() => ({ ({ agentName }) => agentName as AgentName ); const apmTelemetry = createApmTelementry(agentNames); - storeApmServicesTelemetry(context.__LEGACY.server, apmTelemetry); + storeApmServicesTelemetry(context.core.savedObjects.client, apmTelemetry); return services; } diff --git a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/has_apm_data.ts b/x-pack/legacy/plugins/infra/server/routes/metadata/lib/has_apm_data.ts index 9ca0819d74d46..1f8029db80d86 100644 --- a/x-pack/legacy/plugins/infra/server/routes/metadata/lib/has_apm_data.ts +++ b/x-pack/legacy/plugins/infra/server/routes/metadata/lib/has_apm_data.ts @@ -18,9 +18,7 @@ export const hasAPMData = async ( nodeId: string, nodeType: InventoryItemType ) => { - const apmIndices = await framework.plugins.apm.getApmIndices( - requestContext.core.savedObjects.client - ); + const apmIndices = await framework.plugins.apm.getApmIndices(); const apmIndex = apmIndices['apm_oss.transactionIndices'] || 'apm-*'; const fields = findInventoryFields(nodeType, sourceConfiguration.fields); diff --git a/x-pack/plugins/apm/kibana.json b/x-pack/plugins/apm/kibana.json index d60846131da74..42232a8b89605 100644 --- a/x-pack/plugins/apm/kibana.json +++ b/x-pack/plugins/apm/kibana.json @@ -6,5 +6,5 @@ "configPath": ["xpack", "apm"], "ui": false, "requiredPlugins": ["apm_oss", "data", "home"], - "optionalPlugins": ["cloud"] + "optionalPlugins": ["cloud", "usageCollection"] } diff --git a/x-pack/plugins/apm/server/plugin.ts b/x-pack/plugins/apm/server/plugin.ts index 83ece92aebe45..d5632fa57bc5c 100644 --- a/x-pack/plugins/apm/server/plugin.ts +++ b/x-pack/plugins/apm/server/plugin.ts @@ -3,16 +3,13 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { - PluginInitializerContext, - Plugin, - CoreSetup, - SavedObjectsClientContract, -} from 'src/core/server'; +import { PluginInitializerContext, Plugin, CoreSetup } from 'src/core/server'; import { Observable, combineLatest, AsyncSubject } from 'rxjs'; import { map } from 'rxjs/operators'; import { Server } from 'hapi'; import { once } from 'lodash'; +import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { makeApmUsageCollector } from '../../../legacy/plugins/apm/server/lib/apm_telemetry'; import { Plugin as APMOSSPlugin } from '../../../../src/plugins/apm_oss/server'; import { createApmAgentConfigurationIndex } from '../../../legacy/plugins/apm/server/lib/settings/agent_configuration/create_agent_config_index'; import { createApmApi } from '../../../legacy/plugins/apm/server/routes/create_apm_api'; @@ -29,9 +26,13 @@ export interface LegacySetup { export interface APMPluginContract { config$: Observable; registerLegacyAPI: (__LEGACY: LegacySetup) => void; - getApmIndices: ( - savedObjectsClient: SavedObjectsClientContract - ) => ReturnType; + getApmIndices: () => ReturnType; +} + +async function getInternalSavedObjectClient(core: CoreSetup) { + return core.getStartServices().then(async ([coreStart]) => { + return coreStart.savedObjects.createInternalRepository(); + }); } export class APMPlugin implements Plugin { @@ -49,6 +50,7 @@ export class APMPlugin implements Plugin { apm_oss: APMOSSPlugin extends Plugin ? TSetup : never; home: HomeServerPluginSetup; cloud?: CloudSetup; + usageCollection?: UsageCollectionSetup; } ) { const config$ = this.initContext.config.create(); @@ -88,13 +90,22 @@ export class APMPlugin implements Plugin { }) ); + const usageCollection = plugins.usageCollection; + if (usageCollection) { + core.getStartServices().then(async ([coreStart]) => { + const internalSavedObjectsClient = coreStart.savedObjects.createInternalRepository(); + makeApmUsageCollector(usageCollection, internalSavedObjectsClient); + }); + } + return { config$: mergedConfig$, registerLegacyAPI: once((__LEGACY: LegacySetup) => { this.legacySetup$.next(__LEGACY); this.legacySetup$.complete(); }), - getApmIndices: async (savedObjectsClient: SavedObjectsClientContract) => { + getApmIndices: async () => { + const savedObjectsClient = await getInternalSavedObjectClient(core); return getApmIndices({ savedObjectsClient, config: this.currentConfig }); }, };