mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[data] Use versioned router for remaining routes (#161919)
## Summary Uses the versioned router for the remaining routes in the data plugin: KQL telemetry (opt-in stats), and scripting languages list. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
This commit is contained in:
parent
e96dd5cac4
commit
13372c91ce
10 changed files with 145 additions and 68 deletions
|
@ -14,3 +14,6 @@ export const KIBANA_USER_QUERY_LANGUAGE_KEY = 'kibana.userQueryLanguage';
|
|||
export type ValueSuggestionsMethod = 'terms_enum' | 'terms_agg';
|
||||
|
||||
export const SAVED_QUERY_BASE_URL = '/internal/saved_query';
|
||||
|
||||
export const KQL_TELEMETRY_ROUTE_LATEST_VERSION = '1';
|
||||
export const SCRIPT_LANGUAGES_ROUTE_LATEST_VERSION = '1';
|
||||
|
|
|
@ -9,7 +9,13 @@
|
|||
// TODO: https://github.com/elastic/kibana/issues/109904
|
||||
/* eslint-disable @kbn/eslint/no_export_all */
|
||||
|
||||
export { DEFAULT_QUERY_LANGUAGE, KIBANA_USER_QUERY_LANGUAGE_KEY, UI_SETTINGS } from './constants';
|
||||
export {
|
||||
DEFAULT_QUERY_LANGUAGE,
|
||||
KIBANA_USER_QUERY_LANGUAGE_KEY,
|
||||
KQL_TELEMETRY_ROUTE_LATEST_VERSION,
|
||||
SCRIPT_LANGUAGES_ROUTE_LATEST_VERSION,
|
||||
UI_SETTINGS,
|
||||
} from './constants';
|
||||
export type { ValueSuggestionsMethod } from './constants';
|
||||
export { DatatableUtilitiesService } from './datatable_utilities';
|
||||
export { getEsQueryConfig } from './es_query';
|
||||
|
|
|
@ -8,47 +8,64 @@
|
|||
|
||||
import { StartServicesAccessor, IRouter, Logger } from '@kbn/core/server';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { KQL_TELEMETRY_ROUTE_LATEST_VERSION } from '../../common/constants';
|
||||
|
||||
export function registerKqlTelemetryRoute(
|
||||
router: IRouter,
|
||||
getStartServices: StartServicesAccessor,
|
||||
logger: Logger
|
||||
) {
|
||||
router.post(
|
||||
{
|
||||
path: '/api/kibana/kql_opt_in_stats',
|
||||
validate: {
|
||||
body: schema.object({
|
||||
opt_in: schema.boolean(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
async (context, request, response) => {
|
||||
const [{ savedObjects }] = await getStartServices();
|
||||
const internalRepository = savedObjects.createInternalRepository();
|
||||
|
||||
const {
|
||||
body: { opt_in: optIn },
|
||||
} = request;
|
||||
|
||||
const counterName = optIn ? 'optInCount' : 'optOutCount';
|
||||
|
||||
try {
|
||||
await internalRepository.incrementCounter('kql-telemetry', 'kql-telemetry', [counterName]);
|
||||
} catch (error) {
|
||||
logger.warn(`Unable to increment counter: ${error}`);
|
||||
return response.customError({
|
||||
statusCode: error.status,
|
||||
body: {
|
||||
message: 'Something went wrong',
|
||||
attributes: {
|
||||
success: false,
|
||||
router.versioned
|
||||
.post({
|
||||
path: '/internal/kql_opt_in_stats',
|
||||
access: 'internal',
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: KQL_TELEMETRY_ROUTE_LATEST_VERSION,
|
||||
validate: {
|
||||
request: {
|
||||
body: schema.object({
|
||||
opt_in: schema.boolean(),
|
||||
}),
|
||||
},
|
||||
response: {
|
||||
'200': {
|
||||
body: schema.object({
|
||||
success: schema.boolean(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
async (context, request, response) => {
|
||||
const [{ savedObjects }] = await getStartServices();
|
||||
const internalRepository = savedObjects.createInternalRepository();
|
||||
|
||||
return response.ok({ body: { success: true } });
|
||||
}
|
||||
);
|
||||
const {
|
||||
body: { opt_in: optIn },
|
||||
} = request;
|
||||
|
||||
const counterName = optIn ? 'optInCount' : 'optOutCount';
|
||||
|
||||
try {
|
||||
await internalRepository.incrementCounter('kql-telemetry', 'kql-telemetry', [
|
||||
counterName,
|
||||
]);
|
||||
} catch (error) {
|
||||
logger.warn(`Unable to increment counter: ${error}`);
|
||||
return response.customError({
|
||||
statusCode: error.status,
|
||||
body: {
|
||||
message: 'Something went wrong',
|
||||
attributes: {
|
||||
success: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return response.ok({ body: { success: true } });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -7,14 +7,30 @@
|
|||
*/
|
||||
|
||||
import { IRouter } from '@kbn/core/server';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { SCRIPT_LANGUAGES_ROUTE_LATEST_VERSION } from '../../common/constants';
|
||||
|
||||
export function registerScriptsRoute(router: IRouter) {
|
||||
router.get(
|
||||
{ path: '/api/kibana/scripts/languages', validate: false },
|
||||
async (context, request, response) => {
|
||||
return response.ok({
|
||||
body: ['painless', 'expression'],
|
||||
});
|
||||
}
|
||||
);
|
||||
router.versioned
|
||||
.get({
|
||||
path: '/internal/scripts/languages',
|
||||
access: 'internal',
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: SCRIPT_LANGUAGES_ROUTE_LATEST_VERSION,
|
||||
validate: {
|
||||
response: {
|
||||
'200': {
|
||||
body: schema.arrayOf(schema.string()),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
async (context, request, response) => {
|
||||
return response.ok({
|
||||
body: ['painless', 'expression'],
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { HttpStart, NotificationsStart } from '@kbn/core/public';
|
||||
import { SCRIPT_LANGUAGES_ROUTE_LATEST_VERSION } from '@kbn/data-plugin/common';
|
||||
|
||||
export function getSupportedScriptingLanguages(): estypes.ScriptLanguage[] {
|
||||
return ['painless'];
|
||||
|
@ -21,12 +22,16 @@ export const getEnabledScriptingLanguages = (
|
|||
http: HttpStart,
|
||||
toasts: NotificationsStart['toasts']
|
||||
) =>
|
||||
http.get<estypes.ScriptLanguage[]>('/api/kibana/scripts/languages').catch(() => {
|
||||
toasts.addDanger(
|
||||
i18n.translate('indexPatternManagement.scriptingLanguages.errorFetchingToastDescription', {
|
||||
defaultMessage: 'Error getting available scripting languages from Elasticsearch',
|
||||
})
|
||||
);
|
||||
http
|
||||
.get<estypes.ScriptLanguage[]>('/internal/scripts/languages', {
|
||||
version: SCRIPT_LANGUAGES_ROUTE_LATEST_VERSION,
|
||||
})
|
||||
.catch(() => {
|
||||
toasts.addDanger(
|
||||
i18n.translate('indexPatternManagement.scriptingLanguages.errorFetchingToastDescription', {
|
||||
defaultMessage: 'Error getting available scripting languages from Elasticsearch',
|
||||
})
|
||||
);
|
||||
|
||||
return [] as estypes.ScriptLanguage[];
|
||||
});
|
||||
return [] as estypes.ScriptLanguage[];
|
||||
});
|
||||
|
|
|
@ -28,7 +28,11 @@ import {
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { KIBANA_USER_QUERY_LANGUAGE_KEY, UI_SETTINGS } from '@kbn/data-plugin/common';
|
||||
import {
|
||||
KIBANA_USER_QUERY_LANGUAGE_KEY,
|
||||
KQL_TELEMETRY_ROUTE_LATEST_VERSION,
|
||||
UI_SETTINGS,
|
||||
} from '@kbn/data-plugin/common';
|
||||
import type { SavedQueryService, SavedQuery } from '@kbn/data-plugin/public';
|
||||
import type { IUnifiedSearchPluginServices } from '../types';
|
||||
import { fromUser } from './from_user';
|
||||
|
@ -297,7 +301,8 @@ export function QueryBarMenuPanels({
|
|||
};
|
||||
|
||||
const onSelectLanguage = (lang: string) => {
|
||||
http.post('/api/kibana/kql_opt_in_stats', {
|
||||
http.post('/internal/kql_opt_in_stats', {
|
||||
version: KQL_TELEMETRY_ROUTE_LATEST_VERSION,
|
||||
body: JSON.stringify({ opt_in: lang === 'kuery' }),
|
||||
});
|
||||
|
||||
|
|
|
@ -32,7 +32,11 @@ import type { Query } from '@kbn/es-query';
|
|||
import { DataPublicPluginStart, getQueryLog } from '@kbn/data-plugin/public';
|
||||
import { type DataView, DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
|
||||
import type { PersistedLog } from '@kbn/data-plugin/public';
|
||||
import { getFieldSubtypeNested, KIBANA_USER_QUERY_LANGUAGE_KEY } from '@kbn/data-plugin/common';
|
||||
import {
|
||||
getFieldSubtypeNested,
|
||||
KIBANA_USER_QUERY_LANGUAGE_KEY,
|
||||
KQL_TELEMETRY_ROUTE_LATEST_VERSION,
|
||||
} from '@kbn/data-plugin/common';
|
||||
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
|
||||
import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public';
|
||||
import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public';
|
||||
|
@ -592,7 +596,8 @@ export default class QueryStringInputUI extends PureComponent<QueryStringInputPr
|
|||
// Send telemetry info every time the user opts in or out of kuery
|
||||
// As a result it is important this function only ever gets called in the
|
||||
// UI component's change handler.
|
||||
this.props.deps.http.post('/api/kibana/kql_opt_in_stats', {
|
||||
this.props.deps.http.post('/internal/kql_opt_in_stats', {
|
||||
version: KQL_TELEMETRY_ROUTE_LATEST_VERSION,
|
||||
body: JSON.stringify({ opt_in: language === 'kuery' }),
|
||||
});
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
import expect from '@kbn/expect';
|
||||
import { get } from 'lodash';
|
||||
import { ANALYTICS_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server';
|
||||
import { KQL_TELEMETRY_ROUTE_LATEST_VERSION } from '@kbn/data-plugin/common';
|
||||
import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
|
@ -30,8 +32,9 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should increment the opt *in* counter in the .kibana_analytics/kql-telemetry document', async () => {
|
||||
await supertest
|
||||
.post('/api/kibana/kql_opt_in_stats')
|
||||
.post('/internal/kql_opt_in_stats')
|
||||
.set('content-type', 'application/json')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, KQL_TELEMETRY_ROUTE_LATEST_VERSION)
|
||||
.send({ opt_in: true })
|
||||
.expect(200);
|
||||
|
||||
|
@ -48,8 +51,9 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should increment the opt *out* counter in the .kibana_analytics/kql-telemetry document', async () => {
|
||||
await supertest
|
||||
.post('/api/kibana/kql_opt_in_stats')
|
||||
.post('/internal/kql_opt_in_stats')
|
||||
.set('content-type', 'application/json')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, KQL_TELEMETRY_ROUTE_LATEST_VERSION)
|
||||
.send({ opt_in: false })
|
||||
.expect(200);
|
||||
|
||||
|
@ -66,8 +70,9 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should report success when opt *in* is incremented successfully', () => {
|
||||
return supertest
|
||||
.post('/api/kibana/kql_opt_in_stats')
|
||||
.post('/internal/kql_opt_in_stats')
|
||||
.set('content-type', 'application/json')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, KQL_TELEMETRY_ROUTE_LATEST_VERSION)
|
||||
.send({ opt_in: true })
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
|
@ -78,8 +83,9 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
it('should report success when opt *out* is incremented successfully', () => {
|
||||
return supertest
|
||||
.post('/api/kibana/kql_opt_in_stats')
|
||||
.post('/internal/kql_opt_in_stats')
|
||||
.set('content-type', 'application/json')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, KQL_TELEMETRY_ROUTE_LATEST_VERSION)
|
||||
.send({ opt_in: false })
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
|
@ -91,28 +97,33 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
it('should only accept literal boolean values for the opt_in POST body param', function () {
|
||||
return Promise.all([
|
||||
supertest
|
||||
.post('/api/kibana/kql_opt_in_stats')
|
||||
.post('/internal/kql_opt_in_stats')
|
||||
.set('content-type', 'application/json')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, KQL_TELEMETRY_ROUTE_LATEST_VERSION)
|
||||
.send({ opt_in: 'notabool' })
|
||||
.expect(400),
|
||||
supertest
|
||||
.post('/api/kibana/kql_opt_in_stats')
|
||||
.post('/internal/kql_opt_in_stats')
|
||||
.set('content-type', 'application/json')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, KQL_TELEMETRY_ROUTE_LATEST_VERSION)
|
||||
.send({ opt_in: 0 })
|
||||
.expect(400),
|
||||
supertest
|
||||
.post('/api/kibana/kql_opt_in_stats')
|
||||
.post('/internal/kql_opt_in_stats')
|
||||
.set('content-type', 'application/json')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, KQL_TELEMETRY_ROUTE_LATEST_VERSION)
|
||||
.send({ opt_in: null })
|
||||
.expect(400),
|
||||
supertest
|
||||
.post('/api/kibana/kql_opt_in_stats')
|
||||
.post('/internal/kql_opt_in_stats')
|
||||
.set('content-type', 'application/json')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, KQL_TELEMETRY_ROUTE_LATEST_VERSION)
|
||||
.send({ opt_in: undefined })
|
||||
.expect(400),
|
||||
supertest
|
||||
.post('/api/kibana/kql_opt_in_stats')
|
||||
.post('/internal/kql_opt_in_stats')
|
||||
.set('content-type', 'application/json')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, KQL_TELEMETRY_ROUTE_LATEST_VERSION)
|
||||
.send({})
|
||||
.expect(400),
|
||||
]);
|
||||
|
|
|
@ -8,13 +8,17 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
|
||||
import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
|
||||
import { SCRIPT_LANGUAGES_ROUTE_LATEST_VERSION } from '@kbn/data-plugin/common/constants';
|
||||
|
||||
export default function ({ getService }) {
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('Script Languages API', function getLanguages() {
|
||||
it('should return 200 with an array of languages', () =>
|
||||
supertest
|
||||
.get('/api/kibana/scripts/languages')
|
||||
.get('/internal/scripts/languages')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, SCRIPT_LANGUAGES_ROUTE_LATEST_VERSION)
|
||||
.expect(200)
|
||||
.then((response) => {
|
||||
expect(response.body).to.be.an('array');
|
||||
|
@ -23,7 +27,8 @@ export default function ({ getService }) {
|
|||
// eslint-disable-next-line jest/no-disabled-tests
|
||||
it.skip('should only return langs enabled for inline scripting', () =>
|
||||
supertest
|
||||
.get('/api/kibana/scripts/languages')
|
||||
.get('/internal/scripts/languages')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, SCRIPT_LANGUAGES_ROUTE_LATEST_VERSION)
|
||||
.expect(200)
|
||||
.then((response) => {
|
||||
expect(response.body).to.contain('expression');
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { KQL_TELEMETRY_ROUTE_LATEST_VERSION } from '@kbn/data-plugin/common';
|
||||
import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
|
||||
|
||||
export default function ({ getService }) {
|
||||
const supertestNoAuth = getService('supertestWithoutAuth');
|
||||
|
@ -15,9 +17,10 @@ export default function ({ getService }) {
|
|||
describe('no auth', () => {
|
||||
it('should return 401', async () => {
|
||||
return supertestNoAuth
|
||||
.post('/api/kibana/kql_opt_in_stats')
|
||||
.post('/internal/kql_opt_in_stats')
|
||||
.set('content-type', 'application/json')
|
||||
.set('kbn-xsrf', 'much access')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, KQL_TELEMETRY_ROUTE_LATEST_VERSION)
|
||||
.send({ opt_in: true })
|
||||
.expect(401);
|
||||
});
|
||||
|
@ -26,9 +29,10 @@ export default function ({ getService }) {
|
|||
describe('with auth', () => {
|
||||
it('should return 200 for a successful request', async () => {
|
||||
return supertest
|
||||
.post('/api/kibana/kql_opt_in_stats')
|
||||
.post('/internal/kql_opt_in_stats')
|
||||
.set('content-type', 'application/json')
|
||||
.set('kbn-xsrf', 'such token, wow')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, KQL_TELEMETRY_ROUTE_LATEST_VERSION)
|
||||
.send({ opt_in: true })
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue