Skip to content

Commit

Permalink
also move usage collector over
Browse files Browse the repository at this point in the history
  • Loading branch information
flash1293 committed Dec 11, 2019
1 parent 63737e1 commit 3937a1d
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 46 deletions.
2 changes: 0 additions & 2 deletions src/legacy/core_plugins/kibana/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import { registerTutorials } from './server/tutorials/register';
import * as systemApi from './server/lib/system_api';
import mappings from './mappings.json';
import { getUiSettingDefaults } from './ui_setting_defaults';
import { makeKQLUsageCollector } from './server/lib/kql_usage_collector';
import { registerCspCollector } from './server/lib/csp_usage_collector';
import { injectVars } from './inject_vars';
import { i18n } from '@kbn/i18n';
Expand Down Expand Up @@ -332,7 +331,6 @@ export default function (kibana) {
registerSuggestionsApi(server);
registerFieldFormats(server);
registerTutorials(server);
makeKQLUsageCollector(usageCollection, server);
registerCspCollector(usageCollection, server);
server.expose('systemApi', systemApi);
server.injectUiAppVars('kibana', () => injectVars(server));
Expand Down
3 changes: 2 additions & 1 deletion src/legacy/core_plugins/kibana/ui_setting_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import moment from 'moment-timezone';
import numeralLanguages from '@elastic/numeral/languages';
import { i18n } from '@kbn/i18n';
import { DEFAULT_QUERY_LANGUAGE } from '../../../plugins/data/common';

export function getUiSettingDefaults() {
const weekdays = moment.weekdays().slice();
Expand Down Expand Up @@ -114,7 +115,7 @@ export function getUiSettingDefaults() {
},
'search:queryLanguage': {
name: queryLanguageSettingName,
value: 'kuery',
value: DEFAULT_QUERY_LANGUAGE,
description: i18n.translate('kbn.advancedSettings.searchQueryLanguageText', {
defaultMessage:
'Query language used by the query bar. KQL is a new language built specifically for Kibana.',
Expand Down
20 changes: 20 additions & 0 deletions src/plugins/data/common/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

export const DEFAULT_QUERY_LANGUAGE = 'kuery';
1 change: 1 addition & 0 deletions src/plugins/data/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ export * from './index_patterns';
export * from './es_query';
export * from './utils';
export * from './types';
export * from './constants';
3 changes: 2 additions & 1 deletion src/plugins/data/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"version": "kibana",
"server": true,
"ui": true,
"requiredPlugins": ["uiActions"]
"requiredPlugins": ["uiActions"],
"optionalPlugins": ["usageCollection"]
}
15 changes: 14 additions & 1 deletion src/plugins/data/server/kql_telemetry/kql_telemetry_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,31 @@
* under the License.
*/

import { first } from 'rxjs/operators';
import { CoreSetup, Plugin, PluginInitializerContext } from 'kibana/server';
import { registerKqlTelemetryRoute } from './route';
import { UsageCollectionSetup } from '../../../usage_collection/server';
import { makeKQLUsageCollector } from './usage_collector';

export class KqlTelemetryService implements Plugin<void> {
constructor(private initializerContext: PluginInitializerContext) {}

public setup({ http, savedObjects }: CoreSetup) {
public async setup(
{ http, savedObjects }: CoreSetup,
{ usageCollection }: { usageCollection?: UsageCollectionSetup }
) {
registerKqlTelemetryRoute(
http.createRouter(),
savedObjects,
this.initializerContext.logger.get('data', 'kql-telemetry')
);

if (usageCollection) {
const config = await this.initializerContext.config.legacy.globalConfig$
.pipe(first())
.toPromise();
makeKQLUsageCollector(usageCollection, config.kibana.index);
}
}

public start() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,22 @@
* under the License.
*/

jest.mock('../../../ui_setting_defaults', () => ({
getUiSettingDefaults: () => ({ 'search:queryLanguage': { value: 'lucene' } }),
}));

import { fetchProvider } from './fetch';
import { APICaller } from 'kibana/server';

jest.mock('../../../common', () => ({
DEFAULT_QUERY_LANGUAGE: 'lucene',
}));

let fetch;
let callCluster;
let fetch: ReturnType<typeof fetchProvider>;
let callCluster: APICaller;

function setupMockCallCluster(optCount, language) {
callCluster = jest.fn((method, params) => {
if ('id' in params && params.id === 'kql-telemetry:kql-telemetry') {
function setupMockCallCluster(
optCount: { optInCount?: number; optOutCount?: number } | null,
language: string | undefined | null
) {
callCluster = (jest.fn((method, params) => {
if (params && 'id' in params && params.id === 'kql-telemetry:kql-telemetry') {
if (optCount === null) {
return Promise.resolve({
_index: '.kibana_1',
Expand All @@ -46,9 +50,9 @@ function setupMockCallCluster(optCount, language) {
},
});
}
} else if ('body' in params && params.body.query.term.type === 'config') {
} else if (params && 'body' in params && params.body.query.term.type === 'config') {
if (language === 'missingConfigDoc') {
Promise.resolve({
return Promise.resolve({
hits: {
hits: [],
},
Expand All @@ -69,7 +73,9 @@ function setupMockCallCluster(optCount, language) {
});
}
}
});

throw new Error('invalid call');
}) as unknown) as APICaller;
}

describe('makeKQLUsageCollector', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
* under the License.
*/

import { getUiSettingDefaults } from '../../../ui_setting_defaults';
import { get } from 'lodash';
import { APICaller } from 'kibana/server';
import { DEFAULT_QUERY_LANGUAGE } from '../../../common';

const uiSettingDefaults = getUiSettingDefaults();
const defaultSearchQueryLanguageSetting = uiSettingDefaults['search:queryLanguage'].value;
const defaultSearchQueryLanguageSetting = DEFAULT_QUERY_LANGUAGE;

export function fetchProvider(index) {
return async callCluster => {
export function fetchProvider(index: string) {
return async (callCluster: APICaller) => {
const [response, config] = await Promise.all([
callCluster('get', {
index,
Expand All @@ -38,7 +38,10 @@ export function fetchProvider(index) {
}),
]);

const queryLanguageConfigValue = get(config, 'hits.hits[0]._source.config.search:queryLanguage');
const queryLanguageConfigValue = get(
config,
'hits.hits[0]._source.config.search:queryLanguage'
);

// search:queryLanguage can potentially be in four states in the .kibana index:
// 1. undefined: this means the user has never touched this setting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,26 @@
*/

import { makeKQLUsageCollector } from './make_kql_usage_collector';
import { UsageCollectionSetup } from '../../../../usage_collection/server';

describe('makeKQLUsageCollector', () => {
let server;
let makeUsageCollectorStub;
let registerStub;
let usageCollection;
let usageCollectionMock: jest.Mocked<UsageCollectionSetup>;

beforeEach(() => {
makeUsageCollectorStub = jest.fn();
registerStub = jest.fn();
usageCollection = {
makeUsageCollector: makeUsageCollectorStub,
registerCollector: registerStub,
};
server = {
config: () => ({ get: () => '.kibana' })
};
usageCollectionMock = ({
makeUsageCollector: jest.fn(),
registerCollector: jest.fn(),
} as unknown) as jest.Mocked<UsageCollectionSetup>;
});

it('should call registerCollector', () => {
makeKQLUsageCollector(usageCollection, server);
expect(registerStub).toHaveBeenCalledTimes(1);
makeKQLUsageCollector(usageCollectionMock, '.kibana');
expect(usageCollectionMock.registerCollector).toHaveBeenCalledTimes(1);
});

it('should call makeUsageCollector with type = kql', () => {
makeKQLUsageCollector(usageCollection, server);
expect(makeUsageCollectorStub).toHaveBeenCalledTimes(1);
expect(makeUsageCollectorStub.mock.calls[0][0].type).toBe('kql');
makeKQLUsageCollector(usageCollectionMock, '.kibana');
expect(usageCollectionMock.makeUsageCollector).toHaveBeenCalledTimes(1);
expect(usageCollectionMock.makeUsageCollector.mock.calls[0][0].type).toBe('kql');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
*/

import { fetchProvider } from './fetch';
import { UsageCollectionSetup } from '../../../../usage_collection/server';

export function makeKQLUsageCollector(usageCollection, server) {
const index = server.config().get('kibana.index');
const fetch = fetchProvider(index);
export async function makeKQLUsageCollector(
usageCollection: UsageCollectionSetup,
kibanaIndex: string
) {
const fetch = fetchProvider(kibanaIndex);
const kqlUsageCollector = usageCollection.makeUsageCollector({
type: 'kql',
fetch,
Expand Down
14 changes: 12 additions & 2 deletions src/plugins/data/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,38 @@ import { ISearchSetup } from './search';
import { SearchService } from './search/search_service';
import { ScriptsService } from './scripts';
import { KqlTelemetryService } from './kql_telemetry';
import { UsageCollectionSetup } from '../../usage_collection/server';

export interface DataPluginSetup {
search: ISearchSetup;
}

export interface DataPluginSetupDependencies {
usageCollection?: UsageCollectionSetup;
}

export class DataServerPlugin implements Plugin<DataPluginSetup> {
private readonly searchService: SearchService;
private readonly scriptsService: ScriptsService;
private readonly kqlTelemetryService: KqlTelemetryService;
private readonly indexPatterns = new IndexPatternsService();

constructor(initializerContext: PluginInitializerContext) {
this.searchService = new SearchService(initializerContext);
this.scriptsService = new ScriptsService();
this.kqlTelemetryService = new KqlTelemetryService(initializerContext);
}
public setup(core: CoreSetup) {

public async setup(core: CoreSetup, { usageCollection }: DataPluginSetupDependencies) {
this.indexPatterns.setup(core);
this.scriptsService.setup(core);
this.kqlTelemetryService.setup(core);
await this.kqlTelemetryService.setup(core, { usageCollection });

return {
search: this.searchService.setup(core),
};
}

public start(core: CoreStart) {}
public stop() {}
}
Expand Down

0 comments on commit 3937a1d

Please sign in to comment.