From 6101b540ecceb349f8a037ba590be90cd620eae4 Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Thu, 16 Jan 2020 08:16:36 -0700 Subject: [PATCH] Move maps telemetry to NP. Some clean-up, some ts conversion --- x-pack/legacy/plugins/maps/index.js | 11 +++- .../maps_telemetry/collectors/register.ts | 27 ++++++++ .../collectors/register_collector.test.js | 38 +++++++++++ .../{maps_telemetry.js => maps_telemetry.ts} | 63 ++++++++++--------- x-pack/legacy/plugins/maps/server/plugin.js | 7 ++- 5 files changed, 112 insertions(+), 34 deletions(-) create mode 100644 x-pack/legacy/plugins/maps/server/maps_telemetry/collectors/register.ts create mode 100644 x-pack/legacy/plugins/maps/server/maps_telemetry/collectors/register_collector.test.js rename x-pack/legacy/plugins/maps/server/maps_telemetry/{maps_telemetry.js => maps_telemetry.ts} (69%) diff --git a/x-pack/legacy/plugins/maps/index.js b/x-pack/legacy/plugins/maps/index.js index d28f483c9b987..6efdee57a56d8 100644 --- a/x-pack/legacy/plugins/maps/index.js +++ b/x-pack/legacy/plugins/maps/index.js @@ -8,7 +8,6 @@ import { i18n } from '@kbn/i18n'; import { resolve } from 'path'; import mappings from './mappings.json'; import { migrations } from './migrations'; -import { initTelemetryCollection } from './server/maps_telemetry'; import { getAppTitle } from './common/i18n_getters'; import _ from 'lodash'; import { MapPlugin } from './server/plugin'; @@ -91,12 +90,10 @@ export function maps(kibana) { init(server) { const mapsEnabled = server.config().get('xpack.maps.enabled'); - const { usageCollection } = server.newPlatform.setup.plugins; if (!mapsEnabled) { server.log(['info', 'maps'], 'Maps app disabled by configuration'); return; } - initTelemetryCollection(usageCollection, server); const coreSetup = server.newPlatform.setup.core; const newPlatformPlugins = server.newPlatform.setup.plugins; @@ -104,6 +101,7 @@ export function maps(kibana) { featuresPlugin: newPlatformPlugins.features, licensing: newPlatformPlugins.licensing, home: newPlatformPlugins.home, + usageCollection: newPlatformPlugins.usageCollection, }; // legacy dependencies @@ -117,6 +115,13 @@ export function maps(kibana) { elasticsearch: server.plugins.elasticsearch, }, savedObjects: { + savedObjectsClient: (() => { + const callCluster = server.plugins.elasticsearch.getCluster('admin') + .callWithInternalUser; + const { SavedObjectsClient, getSavedObjectsRepository } = server.savedObjects; + const internalRepository = getSavedObjectsRepository(callCluster); + return new SavedObjectsClient(internalRepository); + })(), getSavedObjectsRepository: server.savedObjects.getSavedObjectsRepository, }, injectUiAppVars: server.injectUiAppVars, diff --git a/x-pack/legacy/plugins/maps/server/maps_telemetry/collectors/register.ts b/x-pack/legacy/plugins/maps/server/maps_telemetry/collectors/register.ts new file mode 100644 index 0000000000000..ebe3d38ef1428 --- /dev/null +++ b/x-pack/legacy/plugins/maps/server/maps_telemetry/collectors/register.ts @@ -0,0 +1,27 @@ +/* + * 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 { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +// @ts-ignore +import { getMapsTelemetry, TELEMETRY_TYPE } from '../maps_telemetry'; + +export function registerMapsUsageCollector( + usageCollection: UsageCollectionSetup, + savedObjectsClient: any, + config: Function +): void { + if (!usageCollection) { + return; + } + + const mapsUsageCollector = usageCollection.makeUsageCollector({ + type: TELEMETRY_TYPE, + isReady: () => true, + fetch: async () => await getMapsTelemetry(savedObjectsClient, config), + }); + + usageCollection.registerCollector(mapsUsageCollector); +} diff --git a/x-pack/legacy/plugins/maps/server/maps_telemetry/collectors/register_collector.test.js b/x-pack/legacy/plugins/maps/server/maps_telemetry/collectors/register_collector.test.js new file mode 100644 index 0000000000000..33eb33100acdf --- /dev/null +++ b/x-pack/legacy/plugins/maps/server/maps_telemetry/collectors/register_collector.test.js @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { registerMapsUsageCollector } from './register'; + +describe('buildCollectorObj#fetch', () => { + let makeUsageCollectorStub; + let savedObjectsClient; + let registerStub; + let usageCollection; + let config; + + beforeEach(() => { + makeUsageCollectorStub = jest.fn(); + savedObjectsClient = jest.fn(); + registerStub = jest.fn(); + config = jest.fn(); + usageCollection = { + makeUsageCollector: makeUsageCollectorStub, + registerCollector: registerStub, + }; + }); + + test('makes and registers maps usage collector', async () => { + registerMapsUsageCollector(usageCollection, savedObjectsClient, config); + + expect(registerStub).toHaveBeenCalledTimes(1); + expect(makeUsageCollectorStub).toHaveBeenCalledTimes(1); + expect(makeUsageCollectorStub).toHaveBeenCalledWith({ + type: expect.any(String), + isReady: expect.any(Function), + fetch: expect.any(Function), + }); + }); +}); diff --git a/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.js b/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.ts similarity index 69% rename from x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.js rename to x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.ts index 848c964f4b6d4..683399a2e7f68 100644 --- a/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.js +++ b/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.ts @@ -12,20 +12,15 @@ import { TELEMETRY_TYPE, } from '../../common/constants'; -function getSavedObjectsClient(server) { - const { SavedObjectsClient, getSavedObjectsRepository } = server.savedObjects; - const callCluster = server.plugins.elasticsearch.getCluster('admin').callWithInternalUser; - const internalRepository = getSavedObjectsRepository(callCluster); - return new SavedObjectsClient(internalRepository); -} - -function getUniqueLayerCounts(layerCountsList, mapsCount) { +function getUniqueLayerCounts(layerCountsList: any[], mapsCount: number) { const uniqueLayerTypes = _.uniq(_.flatten(layerCountsList.map(lTypes => Object.keys(lTypes)))); - return uniqueLayerTypes.reduce((accu, type) => { - const typeCounts = layerCountsList.reduce((accu, tCounts) => { - tCounts[type] && accu.push(tCounts[type]); - return accu; + return uniqueLayerTypes.reduce((accu: any, type) => { + const typeCounts = layerCountsList.reduce((tCountsAccu, tCounts) => { + if (tCounts[type]) { + tCountsAccu.push(tCounts[type]); + } + return tCountsAccu; }, []); const typeCountsSum = _.sum(typeCounts); accu[type] = { @@ -37,25 +32,33 @@ function getUniqueLayerCounts(layerCountsList, mapsCount) { }, {}); } -function getIndexPatternsWithGeoFieldCount(indexPatterns) { +function getIndexPatternsWithGeoFieldCount(indexPatterns: any[]) { const fieldLists = indexPatterns.map(indexPattern => JSON.parse(indexPattern.attributes.fields)); - const fieldListsWithGeoFields = fieldLists.filter(fields => { - return fields.some( - field => + const fieldListsWithGeoFields = fieldLists.filter(fields => + fields.some( + (field: any) => field.type === ES_GEO_FIELD_TYPE.GEO_POINT || field.type === ES_GEO_FIELD_TYPE.GEO_SHAPE - ); - }); + ) + ); return fieldListsWithGeoFields.length; } -export function buildMapsTelemetry({ mapSavedObjects, indexPatternSavedObjects, settings }) { +export function buildMapsTelemetry({ + mapSavedObjects, + indexPatternSavedObjects, + settings, +}: { + mapSavedObjects: any[]; + indexPatternSavedObjects: any[]; + settings: any; +}) { const layerLists = mapSavedObjects.map(savedMapObject => JSON.parse(savedMapObject.attributes.layerListJSON) ); const mapsCount = layerLists.length; const dataSourcesCount = layerLists.map(lList => { - const sourceIdList = lList.map(layer => layer.sourceDescriptor.id); + const sourceIdList = lList.map((layer: any) => layer.sourceDescriptor.id); return _.uniq(sourceIdList).length; }); @@ -65,7 +68,7 @@ export function buildMapsTelemetry({ mapSavedObjects, indexPatternSavedObjects, // Count of EMS Vector layers used const emsLayersCount = layerLists.map(lList => _(lList) - .countBy(layer => { + .countBy((layer: any) => { const isEmsFile = _.get(layer, 'sourceDescriptor.type') === EMS_FILE; return isEmsFile && _.get(layer, 'sourceDescriptor.id'); }) @@ -110,26 +113,26 @@ export function buildMapsTelemetry({ mapSavedObjects, indexPatternSavedObjects, }, }; } - -async function getMapSavedObjects(savedObjectsClient) { +async function getMapSavedObjects(savedObjectsClient: any) { const mapsSavedObjects = await savedObjectsClient.find({ type: MAP_SAVED_OBJECT_TYPE }); return _.get(mapsSavedObjects, 'saved_objects', []); } -async function getIndexPatternSavedObjects(savedObjectsClient) { +async function getIndexPatternSavedObjects(savedObjectsClient: any) { const indexPatternSavedObjects = await savedObjectsClient.find({ type: 'index-pattern' }); return _.get(indexPatternSavedObjects, 'saved_objects', []); } -export async function getMapsTelemetry(server) { - const savedObjectsClient = getSavedObjectsClient(server); - const mapSavedObjects = await getMapSavedObjects(savedObjectsClient); - const indexPatternSavedObjects = await getIndexPatternSavedObjects(savedObjectsClient); +export async function getMapsTelemetry(savedObjectsClient: any, config: Function) { + const mapSavedObjects: Array> = await getMapSavedObjects(savedObjectsClient); + const indexPatternSavedObjects: Array> = await getIndexPatternSavedObjects( + savedObjectsClient + ); const settings = { - showMapVisualizationTypes: server.config().get('xpack.maps.showMapVisualizationTypes'), + showMapVisualizationTypes: config().get('xpack.maps.showMapVisualizationTypes'), }; const mapsTelemetry = buildMapsTelemetry({ mapSavedObjects, indexPatternSavedObjects, settings }); - return await savedObjectsClient.create(TELEMETRY_TYPE, mapsTelemetry, { + return await savedObjectsClient.create('maps-telemetry', mapsTelemetry, { id: TELEMETRY_TYPE, overwrite: true, }); diff --git a/x-pack/legacy/plugins/maps/server/plugin.js b/x-pack/legacy/plugins/maps/server/plugin.js index 6009cea330ab0..ee4a249c898c7 100644 --- a/x-pack/legacy/plugins/maps/server/plugin.js +++ b/x-pack/legacy/plugins/maps/server/plugin.js @@ -8,12 +8,13 @@ import { APP_ID, APP_ICON, createMapPath, MAP_SAVED_OBJECT_TYPE } from '../commo import { getEcommerceSavedObjects } from './sample_data/ecommerce_saved_objects'; import { getFlightsSavedObjects } from './sample_data/flights_saved_objects.js'; import { getWebLogsSavedObjects } from './sample_data/web_logs_saved_objects.js'; +import { registerMapsUsageCollector } from './maps_telemetry/collectors/register'; import { LICENSE_CHECK_STATE } from '../../../../plugins/licensing/server'; import { initRoutes } from './routes'; export class MapPlugin { setup(core, plugins, __LEGACY) { - const { featuresPlugin, home, licensing } = plugins; + const { featuresPlugin, home, licensing, usageCollection } = plugins; let routesInitialized = false; featuresPlugin.registerFeature({ @@ -51,6 +52,10 @@ export class MapPlugin { } }); + // Init telemetry + const { savedObjectsClient } = __LEGACY.savedObjects; + registerMapsUsageCollector(usageCollection, savedObjectsClient, __LEGACY.config); + const sampleDataLinkLabel = i18n.translate('xpack.maps.sampleDataLinkLabel', { defaultMessage: 'Map', });