mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Watcher] Prevent expensive queries on ES by using PointInTimeFinder to get indexPatterns (#119717)
* Use PointInTimeFinder to paginate through indexPatterns in a more performant way * commit using @elastic.co * Start working on tests * Add tests * Add missing types * Fix tests * Update tests responses * Remove unnecessary mocks * Fix type Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
c6e9da2810
commit
fd741b47e7
9 changed files with 116 additions and 24 deletions
|
@ -50,14 +50,6 @@ jest.mock('../../public/application/lib/api', () => {
|
|||
|
||||
return {
|
||||
...original,
|
||||
loadIndexPatterns: async () => {
|
||||
const INDEX_PATTERNS = [
|
||||
{ attributes: { title: 'index1' } },
|
||||
{ attributes: { title: 'index2' } },
|
||||
{ attributes: { title: 'index3' } },
|
||||
];
|
||||
return await INDEX_PATTERNS;
|
||||
},
|
||||
getHttpClient: () => mockHttpClient,
|
||||
};
|
||||
});
|
||||
|
|
|
@ -23,14 +23,6 @@ jest.mock('../../public/application/lib/api', () => {
|
|||
|
||||
return {
|
||||
...original,
|
||||
loadIndexPatterns: async () => {
|
||||
const INDEX_PATTERNS = [
|
||||
{ attributes: { title: 'index1' } },
|
||||
{ attributes: { title: 'index2' } },
|
||||
{ attributes: { title: 'index3' } },
|
||||
];
|
||||
return await INDEX_PATTERNS;
|
||||
},
|
||||
getHttpClient: () => mockHttpClient,
|
||||
};
|
||||
});
|
||||
|
|
|
@ -151,12 +151,10 @@ export const executeWatch = async (executeWatchDetails: ExecutedWatchDetails, wa
|
|||
};
|
||||
|
||||
export const loadIndexPatterns = async () => {
|
||||
const { savedObjects } = await getSavedObjectsClient().find({
|
||||
type: 'index-pattern',
|
||||
fields: ['title'],
|
||||
perPage: 10000,
|
||||
return sendRequest({
|
||||
path: `${basePath}/indices/index_patterns`,
|
||||
method: 'get',
|
||||
});
|
||||
return savedObjects;
|
||||
};
|
||||
|
||||
const getWatchVisualizationDataDeserializer = (data: { visualizeData: any }) => data?.visualizeData;
|
||||
|
|
|
@ -182,9 +182,8 @@ export const ThresholdWatchEdit = ({ pageTitle }: { pageTitle: string }) => {
|
|||
|
||||
useEffect(() => {
|
||||
const getIndexPatterns = async () => {
|
||||
const indexPatternObjects = await loadIndexPatterns();
|
||||
const titles = indexPatternObjects.map((indexPattern: any) => indexPattern.attributes.title);
|
||||
setIndexPatterns(titles);
|
||||
const { data: indexPatternTitles } = await loadIndexPatterns();
|
||||
setIndexPatterns(indexPatternTitles);
|
||||
};
|
||||
|
||||
const loadData = async () => {
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { SavedObjectsFindResult } from 'src/core/server';
|
||||
import { RouteDependencies } from '../../../types';
|
||||
|
||||
export function registerGetIndexPatternsRoute({
|
||||
router,
|
||||
license,
|
||||
lib: { handleEsError },
|
||||
}: RouteDependencies) {
|
||||
router.get(
|
||||
{
|
||||
path: '/api/watcher/indices/index_patterns',
|
||||
validate: false,
|
||||
},
|
||||
license.guardApiRoute(async ({ core: { savedObjects } }, request, response) => {
|
||||
try {
|
||||
const finder = savedObjects.client.createPointInTimeFinder({
|
||||
type: 'index-pattern',
|
||||
fields: ['title'],
|
||||
perPage: 1000,
|
||||
});
|
||||
|
||||
const responses: string[] = [];
|
||||
|
||||
for await (const result of finder.find()) {
|
||||
responses.push(
|
||||
...result.saved_objects.map(
|
||||
(indexPattern: SavedObjectsFindResult<any>) => indexPattern.attributes.title
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
await finder.close();
|
||||
|
||||
return response.ok({ body: responses });
|
||||
} catch (error) {
|
||||
return handleEsError({ error, response });
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
|
@ -6,8 +6,10 @@
|
|||
*/
|
||||
|
||||
import { registerGetRoute } from './register_get_route';
|
||||
import { registerGetIndexPatternsRoute } from './register_get_index_patterns_route';
|
||||
import { RouteDependencies } from '../../../types';
|
||||
|
||||
export function registerIndicesRoutes(deps: RouteDependencies) {
|
||||
registerGetRoute(deps);
|
||||
registerGetIndexPatternsRoute(deps);
|
||||
}
|
||||
|
|
|
@ -34,5 +34,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
loadTestFile(require.resolve('./painless_lab'));
|
||||
loadTestFile(require.resolve('./file_upload'));
|
||||
loadTestFile(require.resolve('./ml'));
|
||||
loadTestFile(require.resolve('./watcher'));
|
||||
});
|
||||
}
|
||||
|
|
14
x-pack/test/api_integration/apis/watcher/index.ts
Normal file
14
x-pack/test/api_integration/apis/watcher/index.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('Watcher', () => {
|
||||
loadTestFile(require.resolve('./watcher'));
|
||||
});
|
||||
}
|
47
x-pack/test/api_integration/apis/watcher/watcher.ts
Normal file
47
x-pack/test/api_integration/apis/watcher/watcher.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const log = getService('log');
|
||||
const supertest = getService('supertest');
|
||||
const transform = getService('transform');
|
||||
|
||||
describe('watcher', () => {
|
||||
before(async () => {
|
||||
try {
|
||||
await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date');
|
||||
} catch (error) {
|
||||
log.debug('[Setup error] Error creating index pattern');
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
try {
|
||||
await transform.testResources.deleteIndexPatternByTitle('ft_ecommerce');
|
||||
} catch (error) {
|
||||
log.debug('[Cleanup error] Error deleting index pattern');
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
describe('POST /api/watcher/indices/index_patterns', () => {
|
||||
it('returns list of index patterns', async () => {
|
||||
const response = await supertest
|
||||
.get('/api/watcher/indices/index_patterns')
|
||||
.set('kbn-xsrf', 'kibana')
|
||||
.expect(200);
|
||||
|
||||
expect(response.body).to.contain('ft_ecommerce');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue