mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Alerts] Replaces legacy es client with the ElasticsearchClient for alerts and triggers_actions_ui plugins. (#93364)
* [Alerts] Replaces legasy es client with the ElasticsearchClient * fixed build * fixed build * fixed ci build * fixed ci build * fixed infra callCLuster * fixed infra callCLuster * fixed infra callCLuster * fixed ci build * fixed ci build * fixed ci build * fixed infra tests * fixed security tests * fixed security tests * fixed security tests * fixed tests * fixed monitoring unit tests * fixed monitoring unit tests * fixed type checks * fixed type checks * fixed type checks * migrated lists plugin * fixed type checks * fixed tests * fixed security tests * fixed type checks * fixed tests * fixed type checks * fixed tests * fixed tests * fixed tests * fixed due to comments * fixed tests * fixed comment * fixed tests * fixed tests * fixed searh * fixed searh * fixed test * fixed due to comment * fixed detections failing test and replaces scopedClusterClient exposure with IScopedClusterClient instead of ElasticsearchClient asCurrentUser * fixed test * fixed test * fixed test * fixed typecheck * fixed typecheck * fixed typecheck * fixed merge
This commit is contained in:
parent
ec41ae3c49
commit
21587dc79e
191 changed files with 2097 additions and 1347 deletions
|
@ -116,9 +116,8 @@ This is the primary function for an alert type. Whenever the alert needs to exec
|
|||
|
||||
|Property|Description|
|
||||
|---|---|
|
||||
|services.callCluster(path, opts)|Use this to do Elasticsearch queries on the cluster Kibana connects to. This function is the same as any other `callCluster` in Kibana but in the context of the user who created the alert when security is enabled.|
|
||||
|services.scopedClusterClient|This is an instance of the Elasticsearch client. Use this to do Elasticsearch queries in the context of the user who created the alert when security is enabled.|
|
||||
|services.savedObjectsClient|This is an instance of the saved objects client. This provides the ability to do CRUD on any saved objects within the same space the alert lives in.<br><br>The scope of the saved objects client is tied to the user who created the alert (only when security isenabled).|
|
||||
|services.getLegacyScopedClusterClient|This function returns an instance of the LegacyScopedClusterClient scoped to the user who created the alert when security is enabled.|
|
||||
|services.alertInstanceFactory(id)|This [alert instance factory](#alert-instance-factory) creates instances of alerts and must be used in order to execute actions. The id you give to the alert instance factory is a unique identifier to the alert instance.|
|
||||
|services.log(tags, [data], [timestamp])|Use this to create server logs. (This is the same function as server.log)|
|
||||
|startedAt|The date and time the alert type started execution.|
|
||||
|
|
|
@ -70,10 +70,8 @@ const createAlertServicesMock = <
|
|||
alertInstanceFactory: jest
|
||||
.fn<jest.Mocked<AlertInstance<InstanceState, InstanceContext>>, [string]>()
|
||||
.mockReturnValue(alertInstanceFactoryMock),
|
||||
callCluster: elasticsearchServiceMock.createLegacyScopedClusterClient().callAsCurrentUser,
|
||||
getLegacyScopedClusterClient: jest.fn(),
|
||||
savedObjectsClient: savedObjectsClientMock.create(),
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient().asCurrentUser,
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
};
|
||||
};
|
||||
export type AlertServicesMock = ReturnType<typeof createAlertServicesMock>;
|
||||
|
|
|
@ -31,7 +31,6 @@ import {
|
|||
SavedObjectsServiceStart,
|
||||
IContextProvider,
|
||||
ElasticsearchServiceStart,
|
||||
ILegacyClusterClient,
|
||||
StatusServiceSetup,
|
||||
ServiceStatus,
|
||||
SavedObjectsBulkGetObject,
|
||||
|
@ -420,12 +419,8 @@ export class AlertingPlugin {
|
|||
elasticsearch: ElasticsearchServiceStart
|
||||
): (request: KibanaRequest) => Services {
|
||||
return (request) => ({
|
||||
callCluster: elasticsearch.legacy.client.asScoped(request).callAsCurrentUser,
|
||||
savedObjectsClient: this.getScopedClientWithAlertSavedObjectType(savedObjects, request),
|
||||
scopedClusterClient: elasticsearch.client.asScoped(request).asCurrentUser,
|
||||
getLegacyScopedClusterClient(clusterClient: ILegacyClusterClient) {
|
||||
return clusterClient.asScoped(request);
|
||||
},
|
||||
scopedClusterClient: elasticsearch.client.asScoped(request),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { KibanaRequest, KibanaResponseFactory, ILegacyClusterClient } from 'kibana/server';
|
||||
import { KibanaRequest, KibanaResponseFactory } from 'kibana/server';
|
||||
import { identity } from 'lodash';
|
||||
import type { MethodKeysOf } from '@kbn/utility-types';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { ScopedClusterClientMock } from '../../../../../src/core/server/elasticsearch/client/mocks';
|
||||
import { httpServerMock } from '../../../../../src/core/server/mocks';
|
||||
import { alertsClientMock, AlertsClientMock } from '../alerts_client.mock';
|
||||
import { AlertsHealth, AlertType } from '../../common';
|
||||
|
@ -18,12 +20,12 @@ export function mockHandlerArguments(
|
|||
{
|
||||
alertsClient = alertsClientMock.create(),
|
||||
listTypes: listTypesRes = [],
|
||||
esClient = elasticsearchServiceMock.createLegacyClusterClient(),
|
||||
esClient = elasticsearchServiceMock.createScopedClusterClient(),
|
||||
getFrameworkHealth,
|
||||
}: {
|
||||
alertsClient?: AlertsClientMock;
|
||||
listTypes?: AlertType[];
|
||||
esClient?: jest.Mocked<ILegacyClusterClient>;
|
||||
esClient?: jest.Mocked<ScopedClusterClientMock>;
|
||||
getFrameworkHealth?: jest.MockInstance<Promise<AlertsHealth>, []> &
|
||||
(() => Promise<AlertsHealth>);
|
||||
},
|
||||
|
@ -37,7 +39,7 @@ export function mockHandlerArguments(
|
|||
const listTypes = jest.fn(() => listTypesRes);
|
||||
return [
|
||||
({
|
||||
core: { elasticsearch: { legacy: { client: esClient } } },
|
||||
core: { elasticsearch: { client: esClient } },
|
||||
alerting: {
|
||||
listTypes,
|
||||
getAlertsClient() {
|
||||
|
|
|
@ -15,6 +15,8 @@ import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/serv
|
|||
import { alertsClientMock } from '../alerts_client.mock';
|
||||
import { HealthStatus } from '../types';
|
||||
import { alertsMock } from '../mocks';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from '../../../../../src/core/server/elasticsearch/client/mocks';
|
||||
const alertsClient = alertsClientMock.create();
|
||||
|
||||
jest.mock('../lib/license_api_access.ts', () => ({
|
||||
|
@ -63,8 +65,10 @@ describe('healthRoute', () => {
|
|||
healthRoute(router, licenseState, encryptedSavedObjects);
|
||||
const [, handler] = router.get.mock.calls[0];
|
||||
|
||||
const esClient = elasticsearchServiceMock.createLegacyClusterClient();
|
||||
esClient.callAsInternalUser.mockReturnValue(Promise.resolve({}));
|
||||
const esClient = elasticsearchServiceMock.createScopedClusterClient();
|
||||
esClient.asInternalUser.transport.request.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({})
|
||||
);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments({ esClient, alertsClient }, {}, ['ok']);
|
||||
|
||||
|
@ -72,9 +76,8 @@ describe('healthRoute', () => {
|
|||
|
||||
expect(verifyApiAccess).toHaveBeenCalledWith(licenseState);
|
||||
|
||||
expect(esClient.callAsInternalUser.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
expect(esClient.asInternalUser.transport.request.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"transport.request",
|
||||
Object {
|
||||
"method": "GET",
|
||||
"path": "/_xpack/usage",
|
||||
|
@ -91,8 +94,10 @@ describe('healthRoute', () => {
|
|||
healthRoute(router, licenseState, encryptedSavedObjects);
|
||||
const [, handler] = router.get.mock.calls[0];
|
||||
|
||||
const esClient = elasticsearchServiceMock.createLegacyClusterClient();
|
||||
esClient.callAsInternalUser.mockReturnValue(Promise.resolve({}));
|
||||
const esClient = elasticsearchServiceMock.createScopedClusterClient();
|
||||
esClient.asInternalUser.transport.request.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({})
|
||||
);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ esClient, alertsClient, getFrameworkHealth: alerting.getFrameworkHealth },
|
||||
|
@ -130,8 +135,10 @@ describe('healthRoute', () => {
|
|||
healthRoute(router, licenseState, encryptedSavedObjects);
|
||||
const [, handler] = router.get.mock.calls[0];
|
||||
|
||||
const esClient = elasticsearchServiceMock.createLegacyClusterClient();
|
||||
esClient.callAsInternalUser.mockReturnValue(Promise.resolve({}));
|
||||
const esClient = elasticsearchServiceMock.createScopedClusterClient();
|
||||
esClient.asInternalUser.transport.request.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({})
|
||||
);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ esClient, alertsClient, getFrameworkHealth: alerting.getFrameworkHealth },
|
||||
|
@ -169,8 +176,10 @@ describe('healthRoute', () => {
|
|||
healthRoute(router, licenseState, encryptedSavedObjects);
|
||||
const [, handler] = router.get.mock.calls[0];
|
||||
|
||||
const esClient = elasticsearchServiceMock.createLegacyClusterClient();
|
||||
esClient.callAsInternalUser.mockReturnValue(Promise.resolve({ security: {} }));
|
||||
const esClient = elasticsearchServiceMock.createScopedClusterClient();
|
||||
esClient.asInternalUser.transport.request.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({ security: {} })
|
||||
);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ esClient, alertsClient, getFrameworkHealth: alerting.getFrameworkHealth },
|
||||
|
@ -208,8 +217,10 @@ describe('healthRoute', () => {
|
|||
healthRoute(router, licenseState, encryptedSavedObjects);
|
||||
const [, handler] = router.get.mock.calls[0];
|
||||
|
||||
const esClient = elasticsearchServiceMock.createLegacyClusterClient();
|
||||
esClient.callAsInternalUser.mockReturnValue(Promise.resolve({ security: { enabled: true } }));
|
||||
const esClient = elasticsearchServiceMock.createScopedClusterClient();
|
||||
esClient.asInternalUser.transport.request.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({ security: { enabled: true } })
|
||||
);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ esClient, alertsClient, getFrameworkHealth: alerting.getFrameworkHealth },
|
||||
|
@ -247,9 +258,11 @@ describe('healthRoute', () => {
|
|||
healthRoute(router, licenseState, encryptedSavedObjects);
|
||||
const [, handler] = router.get.mock.calls[0];
|
||||
|
||||
const esClient = elasticsearchServiceMock.createLegacyClusterClient();
|
||||
esClient.callAsInternalUser.mockReturnValue(
|
||||
Promise.resolve({ security: { enabled: true, ssl: {} } })
|
||||
const esClient = elasticsearchServiceMock.createScopedClusterClient();
|
||||
esClient.asInternalUser.transport.request.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({
|
||||
security: { enabled: true, ssl: {} },
|
||||
})
|
||||
);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
|
@ -288,9 +301,11 @@ describe('healthRoute', () => {
|
|||
healthRoute(router, licenseState, encryptedSavedObjects);
|
||||
const [, handler] = router.get.mock.calls[0];
|
||||
|
||||
const esClient = elasticsearchServiceMock.createLegacyClusterClient();
|
||||
esClient.callAsInternalUser.mockReturnValue(
|
||||
Promise.resolve({ security: { enabled: true, ssl: { http: { enabled: true } } } })
|
||||
const esClient = elasticsearchServiceMock.createScopedClusterClient();
|
||||
esClient.asInternalUser.transport.request.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({
|
||||
security: { enabled: true, ssl: { http: { enabled: true } } },
|
||||
})
|
||||
);
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ApiResponse } from '@elastic/elasticsearch';
|
||||
import type { AlertingRouter } from '../types';
|
||||
import { ILicenseState } from '../lib/license_state';
|
||||
import { verifyApiAccess } from '../lib/license_api_access';
|
||||
|
@ -39,14 +40,14 @@ export function healthRoute(
|
|||
}
|
||||
try {
|
||||
const {
|
||||
security: {
|
||||
enabled: isSecurityEnabled = false,
|
||||
ssl: { http: { enabled: isTLSEnabled = false } = {} } = {},
|
||||
} = {},
|
||||
}: XPackUsageSecurity = await context.core.elasticsearch.legacy.client
|
||||
// `transport.request` is potentially unsafe when combined with untrusted user input.
|
||||
// Do not augment with such input.
|
||||
.callAsInternalUser('transport.request', {
|
||||
body: {
|
||||
security: {
|
||||
enabled: isSecurityEnabled = false,
|
||||
ssl: { http: { enabled: isTLSEnabled = false } = {} } = {},
|
||||
} = {},
|
||||
},
|
||||
}: ApiResponse<XPackUsageSecurity> = await context.core.elasticsearch.client.asInternalUser.transport // Do not augment with such input. // `transport.request` is potentially unsafe when combined with untrusted user input.
|
||||
.request({
|
||||
method: 'GET',
|
||||
path: '/_xpack/usage',
|
||||
});
|
||||
|
|
|
@ -206,7 +206,7 @@ describe('Task Runner', () => {
|
|||
expect(call.createdBy).toBe('alert-creator');
|
||||
expect(call.updatedBy).toBe('alert-updater');
|
||||
expect(call.services.alertInstanceFactory).toBeTruthy();
|
||||
expect(call.services.callCluster).toBeTruthy();
|
||||
expect(call.services.scopedClusterClient).toBeTruthy();
|
||||
expect(call.services).toBeTruthy();
|
||||
|
||||
const logger = taskRunnerFactoryInitializerParams.logger;
|
||||
|
|
|
@ -13,9 +13,7 @@ import { PluginSetupContract, PluginStartContract } from './plugin';
|
|||
import { AlertsClient } from './alerts_client';
|
||||
export * from '../common';
|
||||
import {
|
||||
ElasticsearchClient,
|
||||
ILegacyClusterClient,
|
||||
ILegacyScopedClusterClient,
|
||||
IScopedClusterClient,
|
||||
KibanaRequest,
|
||||
SavedObjectAttributes,
|
||||
SavedObjectsClientContract,
|
||||
|
@ -63,13 +61,8 @@ export interface AlertingRequestHandlerContext extends RequestHandlerContext {
|
|||
export type AlertingRouter = IRouter<AlertingRequestHandlerContext>;
|
||||
|
||||
export interface Services {
|
||||
/**
|
||||
* @deprecated Use `scopedClusterClient` instead.
|
||||
*/
|
||||
callCluster: ILegacyScopedClusterClient['callAsCurrentUser'];
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
scopedClusterClient: ElasticsearchClient;
|
||||
getLegacyScopedClusterClient(clusterClient: ILegacyClusterClient): ILegacyScopedClusterClient;
|
||||
scopedClusterClient: IScopedClusterClient;
|
||||
}
|
||||
|
||||
export interface AlertServices<
|
||||
|
|
|
@ -5,27 +5,31 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from '../../../../../src/core/server/elasticsearch/client/mocks';
|
||||
import { getTotalCountInUse } from './alerts_telemetry';
|
||||
|
||||
describe('alerts telemetry', () => {
|
||||
test('getTotalCountInUse should replace first "." symbol to "__" in alert types names', async () => {
|
||||
const mockEsClient = jest.fn();
|
||||
mockEsClient.mockReturnValue({
|
||||
aggregations: {
|
||||
byAlertTypeId: {
|
||||
value: {
|
||||
types: { '.index-threshold': 2, 'logs.alert.document.count': 1, 'document.test.': 1 },
|
||||
const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser;
|
||||
mockEsClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({
|
||||
aggregations: {
|
||||
byAlertTypeId: {
|
||||
value: {
|
||||
types: { '.index-threshold': 2, 'logs.alert.document.count': 1, 'document.test.': 1 },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
hits: {
|
||||
hits: [],
|
||||
},
|
||||
});
|
||||
hits: {
|
||||
hits: [],
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
const telemetry = await getTotalCountInUse(mockEsClient, 'test');
|
||||
|
||||
expect(mockEsClient).toHaveBeenCalledTimes(1);
|
||||
expect(mockEsClient.search).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(telemetry).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { SearchResponse } from 'elasticsearch';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { AlertsUsage } from './types';
|
||||
|
||||
const alertTypeMetric = {
|
||||
|
@ -36,7 +35,7 @@ const alertTypeMetric = {
|
|||
};
|
||||
|
||||
export async function getTotalCountAggregations(
|
||||
callCluster: LegacyAPICaller,
|
||||
esClient: ElasticsearchClient,
|
||||
kibanaInex: string
|
||||
): Promise<
|
||||
Pick<
|
||||
|
@ -223,7 +222,7 @@ export async function getTotalCountAggregations(
|
|||
},
|
||||
};
|
||||
|
||||
const results = await callCluster('search', {
|
||||
const { body: results } = await esClient.search({
|
||||
index: kibanaInex,
|
||||
body: {
|
||||
query: {
|
||||
|
@ -256,7 +255,7 @@ export async function getTotalCountAggregations(
|
|||
return {
|
||||
count_total: totalAlertsCount,
|
||||
count_by_type: Object.keys(results.aggregations.byAlertTypeId.value.types).reduce(
|
||||
// ES DSL aggregations are returned as `any` by callCluster
|
||||
// ES DSL aggregations are returned as `any` by esClient.search
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(obj: any, key: string) => ({
|
||||
...obj,
|
||||
|
@ -295,8 +294,8 @@ export async function getTotalCountAggregations(
|
|||
};
|
||||
}
|
||||
|
||||
export async function getTotalCountInUse(callCluster: LegacyAPICaller, kibanaInex: string) {
|
||||
const searchResult: SearchResponse<unknown> = await callCluster('search', {
|
||||
export async function getTotalCountInUse(esClient: ElasticsearchClient, kibanaInex: string) {
|
||||
const { body: searchResult } = await esClient.search({
|
||||
index: kibanaInex,
|
||||
body: {
|
||||
query: {
|
||||
|
@ -316,7 +315,7 @@ export async function getTotalCountInUse(callCluster: LegacyAPICaller, kibanaIne
|
|||
0
|
||||
),
|
||||
countByType: Object.keys(searchResult.aggregations.byAlertTypeId.value.types).reduce(
|
||||
// ES DSL aggregations are returned as `any` by callCluster
|
||||
// ES DSL aggregations are returned as `any` by esClient.search
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(obj: any, key: string) => ({
|
||||
...obj,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Logger, CoreSetup, LegacyAPICaller } from 'kibana/server';
|
||||
import { Logger, CoreSetup } from 'kibana/server';
|
||||
import moment from 'moment';
|
||||
import {
|
||||
RunContext,
|
||||
|
@ -65,17 +65,21 @@ async function scheduleTasks(logger: Logger, taskManager: TaskManagerStartContra
|
|||
export function telemetryTaskRunner(logger: Logger, core: CoreSetup, kibanaIndex: string) {
|
||||
return ({ taskInstance }: RunContext) => {
|
||||
const { state } = taskInstance;
|
||||
const callCluster = (...args: Parameters<LegacyAPICaller>) => {
|
||||
return core.getStartServices().then(([{ elasticsearch: { legacy: { client } } }]) =>
|
||||
client.callAsInternalUser(...args)
|
||||
const getEsClient = () =>
|
||||
core.getStartServices().then(
|
||||
([
|
||||
{
|
||||
elasticsearch: { client },
|
||||
},
|
||||
]) => client.asInternalUser
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
async run() {
|
||||
const esClient = await getEsClient();
|
||||
return Promise.all([
|
||||
getTotalCountAggregations(callCluster, kibanaIndex),
|
||||
getTotalCountInUse(callCluster, kibanaIndex),
|
||||
getTotalCountAggregations(esClient, kibanaIndex),
|
||||
getTotalCountInUse(esClient, kibanaIndex),
|
||||
])
|
||||
.then(([totalCountAggregations, totalInUse]) => {
|
||||
return {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ApiResponse } from '@elastic/elasticsearch';
|
||||
import { ThresholdMetActionGroupId } from '../../../common/alert_types';
|
||||
import {
|
||||
ESSearchRequest,
|
||||
|
@ -23,8 +24,8 @@ export function alertingEsClient<TParams extends ESSearchRequest>(
|
|||
ThresholdMetActionGroupId
|
||||
>,
|
||||
params: TParams
|
||||
): Promise<ESSearchResponse<unknown, TParams>> {
|
||||
return services.callCluster('search', {
|
||||
): Promise<ApiResponse<ESSearchResponse<unknown, TParams>>> {
|
||||
return services.scopedClusterClient.asCurrentUser.search({
|
||||
...params,
|
||||
ignore_unavailable: true,
|
||||
});
|
||||
|
|
|
@ -13,6 +13,9 @@ import { AlertingPlugin } from '../../../../alerting/server';
|
|||
import { APMConfig } from '../..';
|
||||
|
||||
import { registerErrorCountAlertType } from './register_error_count_alert_type';
|
||||
import { elasticsearchServiceMock } from 'src/core/server/mocks';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
type Operator<T1, T2> = (source: Rx.Observable<T1>) => Rx.Observable<T2>;
|
||||
const pipeClosure = <T1, T2>(fn: Operator<T1, T2>): Operator<T1, T2> => {
|
||||
|
@ -43,16 +46,20 @@ describe('Error count alert', () => {
|
|||
expect(alertExecutor).toBeDefined();
|
||||
|
||||
const services = {
|
||||
callCluster: jest.fn(() => ({
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn(),
|
||||
};
|
||||
const params = { threshold: 1 };
|
||||
|
||||
services.scopedClusterClient.asCurrentUser.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({
|
||||
hits: {
|
||||
total: {
|
||||
value: 0,
|
||||
},
|
||||
},
|
||||
})),
|
||||
alertInstanceFactory: jest.fn(),
|
||||
};
|
||||
const params = { threshold: 1 };
|
||||
})
|
||||
);
|
||||
|
||||
await alertExecutor!({ services, params });
|
||||
expect(services.alertInstanceFactory).not.toBeCalled();
|
||||
|
@ -74,7 +81,13 @@ describe('Error count alert', () => {
|
|||
|
||||
const scheduleActions = jest.fn();
|
||||
const services = {
|
||||
callCluster: jest.fn(() => ({
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn(() => ({ scheduleActions })),
|
||||
};
|
||||
const params = { threshold: 1, windowSize: 5, windowUnit: 'm' };
|
||||
|
||||
services.scopedClusterClient.asCurrentUser.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({
|
||||
hits: {
|
||||
total: {
|
||||
value: 2,
|
||||
|
@ -98,10 +111,8 @@ describe('Error count alert', () => {
|
|||
],
|
||||
},
|
||||
},
|
||||
})),
|
||||
alertInstanceFactory: jest.fn(() => ({ scheduleActions })),
|
||||
};
|
||||
const params = { threshold: 1, windowSize: 5, windowUnit: 'm' };
|
||||
})
|
||||
);
|
||||
|
||||
await alertExecutor!({ services, params });
|
||||
[
|
||||
|
@ -158,7 +169,13 @@ describe('Error count alert', () => {
|
|||
|
||||
const scheduleActions = jest.fn();
|
||||
const services = {
|
||||
callCluster: jest.fn(() => ({
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn(() => ({ scheduleActions })),
|
||||
};
|
||||
const params = { threshold: 1, windowSize: 5, windowUnit: 'm' };
|
||||
|
||||
services.scopedClusterClient.asCurrentUser.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({
|
||||
hits: {
|
||||
total: {
|
||||
value: 2,
|
||||
|
@ -176,10 +193,8 @@ describe('Error count alert', () => {
|
|||
],
|
||||
},
|
||||
},
|
||||
})),
|
||||
alertInstanceFactory: jest.fn(() => ({ scheduleActions })),
|
||||
};
|
||||
const params = { threshold: 1, windowSize: 5, windowUnit: 'm' };
|
||||
})
|
||||
);
|
||||
|
||||
await alertExecutor!({ services, params });
|
||||
['apm.error_rate_foo', 'apm.error_rate_bar'].forEach((instanceName) =>
|
||||
|
|
|
@ -127,7 +127,7 @@ export function registerErrorCountAlertType({
|
|||
},
|
||||
};
|
||||
|
||||
const response = await alertingEsClient(services, searchParams);
|
||||
const { body: response } = await alertingEsClient(services, searchParams);
|
||||
const errorCount = response.hits.total.value;
|
||||
|
||||
if (errorCount > alertParams.threshold) {
|
||||
|
|
|
@ -122,7 +122,7 @@ export function registerTransactionDurationAlertType({
|
|||
},
|
||||
};
|
||||
|
||||
const response = await alertingEsClient(services, searchParams);
|
||||
const { body: response } = await alertingEsClient(services, searchParams);
|
||||
|
||||
if (!response.aggregations) {
|
||||
return;
|
||||
|
|
|
@ -11,6 +11,9 @@ import { toArray, map } from 'rxjs/operators';
|
|||
import { AlertingPlugin } from '../../../../alerting/server';
|
||||
import { APMConfig } from '../..';
|
||||
import { registerTransactionErrorRateAlertType } from './register_transaction_error_rate_alert_type';
|
||||
import { elasticsearchServiceMock } from 'src/core/server/mocks';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
type Operator<T1, T2> = (source: Rx.Observable<T1>) => Rx.Observable<T2>;
|
||||
const pipeClosure = <T1, T2>(fn: Operator<T1, T2>): Operator<T1, T2> => {
|
||||
|
@ -41,16 +44,20 @@ describe('Transaction error rate alert', () => {
|
|||
expect(alertExecutor).toBeDefined();
|
||||
|
||||
const services = {
|
||||
callCluster: jest.fn(() => ({
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn(),
|
||||
};
|
||||
const params = { threshold: 1 };
|
||||
|
||||
services.scopedClusterClient.asCurrentUser.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({
|
||||
hits: {
|
||||
total: {
|
||||
value: 0,
|
||||
},
|
||||
},
|
||||
})),
|
||||
alertInstanceFactory: jest.fn(),
|
||||
};
|
||||
const params = { threshold: 1 };
|
||||
})
|
||||
);
|
||||
|
||||
await alertExecutor!({ services, params });
|
||||
expect(services.alertInstanceFactory).not.toBeCalled();
|
||||
|
@ -72,7 +79,13 @@ describe('Transaction error rate alert', () => {
|
|||
|
||||
const scheduleActions = jest.fn();
|
||||
const services = {
|
||||
callCluster: jest.fn(() => ({
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn(() => ({ scheduleActions })),
|
||||
};
|
||||
const params = { threshold: 10, windowSize: 5, windowUnit: 'm' };
|
||||
|
||||
services.scopedClusterClient.asCurrentUser.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({
|
||||
hits: {
|
||||
total: {
|
||||
value: 4,
|
||||
|
@ -113,10 +126,8 @@ describe('Transaction error rate alert', () => {
|
|||
],
|
||||
},
|
||||
},
|
||||
})),
|
||||
alertInstanceFactory: jest.fn(() => ({ scheduleActions })),
|
||||
};
|
||||
const params = { threshold: 10, windowSize: 5, windowUnit: 'm' };
|
||||
})
|
||||
);
|
||||
|
||||
await alertExecutor!({ services, params });
|
||||
[
|
||||
|
@ -177,7 +188,13 @@ describe('Transaction error rate alert', () => {
|
|||
|
||||
const scheduleActions = jest.fn();
|
||||
const services = {
|
||||
callCluster: jest.fn(() => ({
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn(() => ({ scheduleActions })),
|
||||
};
|
||||
const params = { threshold: 10, windowSize: 5, windowUnit: 'm' };
|
||||
|
||||
services.scopedClusterClient.asCurrentUser.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({
|
||||
hits: {
|
||||
total: {
|
||||
value: 4,
|
||||
|
@ -204,10 +221,8 @@ describe('Transaction error rate alert', () => {
|
|||
],
|
||||
},
|
||||
},
|
||||
})),
|
||||
alertInstanceFactory: jest.fn(() => ({ scheduleActions })),
|
||||
};
|
||||
const params = { threshold: 10, windowSize: 5, windowUnit: 'm' };
|
||||
})
|
||||
);
|
||||
|
||||
await alertExecutor!({ services, params });
|
||||
[
|
||||
|
@ -251,7 +266,13 @@ describe('Transaction error rate alert', () => {
|
|||
|
||||
const scheduleActions = jest.fn();
|
||||
const services = {
|
||||
callCluster: jest.fn(() => ({
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn(() => ({ scheduleActions })),
|
||||
};
|
||||
const params = { threshold: 10, windowSize: 5, windowUnit: 'm' };
|
||||
|
||||
services.scopedClusterClient.asCurrentUser.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({
|
||||
hits: {
|
||||
total: {
|
||||
value: 4,
|
||||
|
@ -265,10 +286,8 @@ describe('Transaction error rate alert', () => {
|
|||
buckets: [{ key: 'foo' }, { key: 'bar' }],
|
||||
},
|
||||
},
|
||||
})),
|
||||
alertInstanceFactory: jest.fn(() => ({ scheduleActions })),
|
||||
};
|
||||
const params = { threshold: 10, windowSize: 5, windowUnit: 'm' };
|
||||
})
|
||||
);
|
||||
|
||||
await alertExecutor!({ services, params });
|
||||
[
|
||||
|
|
|
@ -134,7 +134,7 @@ export function registerTransactionErrorRateAlertType({
|
|||
},
|
||||
};
|
||||
|
||||
const response = await alertingEsClient(services, searchParams);
|
||||
const { body: response } = await alertingEsClient(services, searchParams);
|
||||
if (!response.aggregations) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
IndicesExistsAlias,
|
||||
IndicesGet,
|
||||
MlGetBuckets,
|
||||
Msearch,
|
||||
} from '@elastic/elasticsearch/api/requestParams';
|
||||
import { TransportRequestParams } from '@elastic/elasticsearch/lib/Transport';
|
||||
import {
|
||||
InfraRouteConfig,
|
||||
InfraTSVBResponse,
|
||||
|
@ -134,10 +141,58 @@ export class KibanaFramework {
|
|||
}
|
||||
: {};
|
||||
|
||||
return elasticsearch.legacy.client.callAsCurrentUser(endpoint, {
|
||||
...params,
|
||||
...frozenIndicesParams,
|
||||
});
|
||||
let apiResult;
|
||||
switch (endpoint) {
|
||||
case 'search':
|
||||
apiResult = elasticsearch.client.asCurrentUser.search({
|
||||
...params,
|
||||
...frozenIndicesParams,
|
||||
});
|
||||
break;
|
||||
case 'msearch':
|
||||
apiResult = elasticsearch.client.asCurrentUser.msearch({
|
||||
...params,
|
||||
...frozenIndicesParams,
|
||||
} as Msearch<any>);
|
||||
break;
|
||||
case 'fieldCaps':
|
||||
apiResult = elasticsearch.client.asCurrentUser.fieldCaps({
|
||||
...params,
|
||||
...frozenIndicesParams,
|
||||
});
|
||||
break;
|
||||
case 'indices.existsAlias':
|
||||
apiResult = elasticsearch.client.asCurrentUser.indices.existsAlias({
|
||||
...params,
|
||||
...frozenIndicesParams,
|
||||
} as IndicesExistsAlias);
|
||||
break;
|
||||
case 'indices.getAlias':
|
||||
apiResult = elasticsearch.client.asCurrentUser.indices.getAlias({
|
||||
...params,
|
||||
...frozenIndicesParams,
|
||||
});
|
||||
break;
|
||||
case 'indices.get':
|
||||
apiResult = elasticsearch.client.asCurrentUser.indices.get({
|
||||
...params,
|
||||
...frozenIndicesParams,
|
||||
} as IndicesGet);
|
||||
break;
|
||||
case 'transport.request':
|
||||
apiResult = elasticsearch.client.asCurrentUser.transport.request({
|
||||
...params,
|
||||
...frozenIndicesParams,
|
||||
} as TransportRequestParams);
|
||||
break;
|
||||
case 'ml.getBuckets':
|
||||
apiResult = elasticsearch.client.asCurrentUser.ml.getBuckets({
|
||||
...params,
|
||||
...frozenIndicesParams,
|
||||
} as MlGetBuckets<any>);
|
||||
break;
|
||||
}
|
||||
return apiResult ? (await apiResult).body : undefined;
|
||||
}
|
||||
|
||||
public getIndexPatternsService(
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { mapValues, last, first } from 'lodash';
|
||||
import moment from 'moment';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { SnapshotCustomMetricInput } from '../../../../common/http_api/snapshot_api';
|
||||
import {
|
||||
isTooManyBucketsPreviewException,
|
||||
|
@ -17,7 +18,6 @@ import {
|
|||
CallWithRequestParams,
|
||||
} from '../../adapters/framework/adapter_types';
|
||||
import { Comparator, InventoryMetricConditions } from './types';
|
||||
import { AlertServices } from '../../../../../alerting/server';
|
||||
import { InventoryItemType, SnapshotMetricType } from '../../../../common/inventory_models/types';
|
||||
import { InfraTimerangeInput, SnapshotRequest } from '../../../../common/http_api/snapshot_api';
|
||||
import { InfraSource } from '../../sources';
|
||||
|
@ -36,7 +36,7 @@ export const evaluateCondition = async (
|
|||
condition: InventoryMetricConditions,
|
||||
nodeType: InventoryItemType,
|
||||
source: InfraSource,
|
||||
callCluster: AlertServices['callCluster'],
|
||||
esClient: ElasticsearchClient,
|
||||
filterQuery?: string,
|
||||
lookbackSize?: number
|
||||
): Promise<Record<string, ConditionResult>> => {
|
||||
|
@ -53,7 +53,7 @@ export const evaluateCondition = async (
|
|||
}
|
||||
|
||||
const currentValues = await getData(
|
||||
callCluster,
|
||||
esClient,
|
||||
nodeType,
|
||||
metric,
|
||||
timerange,
|
||||
|
@ -96,7 +96,7 @@ const getCurrentValue: (value: any) => number = (value) => {
|
|||
|
||||
type DataValue = number | null | Array<number | string | null | undefined>;
|
||||
const getData = async (
|
||||
callCluster: AlertServices['callCluster'],
|
||||
esClient: ElasticsearchClient,
|
||||
nodeType: InventoryItemType,
|
||||
metric: SnapshotMetricType,
|
||||
timerange: InfraTimerangeInput,
|
||||
|
@ -104,9 +104,10 @@ const getData = async (
|
|||
filterQuery?: string,
|
||||
customMetric?: SnapshotCustomMetricInput
|
||||
) => {
|
||||
const client = <Hit = {}, Aggregation = undefined>(
|
||||
const client = async <Hit = {}, Aggregation = undefined>(
|
||||
options: CallWithRequestParams
|
||||
): Promise<InfraDatabaseSearchResponse<Hit, Aggregation>> => callCluster('search', options);
|
||||
): Promise<InfraDatabaseSearchResponse<Hit, Aggregation>> =>
|
||||
(await esClient.search(options)).body as InfraDatabaseSearchResponse<Hit, Aggregation>;
|
||||
|
||||
const metrics = [
|
||||
metric === 'custom' ? (customMetric as SnapshotCustomMetricInput) : { type: metric },
|
||||
|
|
|
@ -69,7 +69,15 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) =
|
|||
);
|
||||
|
||||
const results = await Promise.all(
|
||||
criteria.map((c) => evaluateCondition(c, nodeType, source, services.callCluster, filterQuery))
|
||||
criteria.map((c) =>
|
||||
evaluateCondition(
|
||||
c,
|
||||
nodeType,
|
||||
source,
|
||||
services.scopedClusterClient.asCurrentUser,
|
||||
filterQuery
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const inventoryItems = Object.keys(first(results)!);
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
TOO_MANY_BUCKETS_PREVIEW_EXCEPTION,
|
||||
isTooManyBucketsPreviewException,
|
||||
} from '../../../../common/alerting/metrics';
|
||||
import { ILegacyScopedClusterClient } from '../../../../../../../src/core/server';
|
||||
import { ElasticsearchClient } from '../../../../../../../src/core/server';
|
||||
import { InfraSource } from '../../../../common/http_api/source_api';
|
||||
import { getIntervalInSeconds } from '../../../utils/get_interval_in_seconds';
|
||||
import { InventoryItemType } from '../../../../common/inventory_models/types';
|
||||
|
@ -27,7 +27,7 @@ interface InventoryMetricThresholdParams {
|
|||
}
|
||||
|
||||
interface PreviewInventoryMetricThresholdAlertParams {
|
||||
callCluster: ILegacyScopedClusterClient['callAsCurrentUser'];
|
||||
esClient: ElasticsearchClient;
|
||||
params: InventoryMetricThresholdParams;
|
||||
source: InfraSource;
|
||||
lookback: Unit;
|
||||
|
@ -40,7 +40,7 @@ interface PreviewInventoryMetricThresholdAlertParams {
|
|||
export const previewInventoryMetricThresholdAlert: (
|
||||
params: PreviewInventoryMetricThresholdAlertParams
|
||||
) => Promise<PreviewResult[]> = async ({
|
||||
callCluster,
|
||||
esClient,
|
||||
params,
|
||||
source,
|
||||
lookback,
|
||||
|
@ -68,7 +68,7 @@ export const previewInventoryMetricThresholdAlert: (
|
|||
try {
|
||||
const results = await Promise.all(
|
||||
criteria.map((c) =>
|
||||
evaluateCondition(c, nodeType, source, callCluster, filterQuery, lookbackSize)
|
||||
evaluateCondition(c, nodeType, source, esClient, filterQuery, lookbackSize)
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import {
|
||||
AlertExecutorOptions,
|
||||
AlertServices,
|
||||
|
@ -67,7 +68,7 @@ const checkValueAgainstComparatorMap: {
|
|||
|
||||
export const createLogThresholdExecutor = (libs: InfraBackendLibs) =>
|
||||
async function ({ services, params }: LogThresholdAlertExecutorOptions) {
|
||||
const { alertInstanceFactory, savedObjectsClient, callCluster } = services;
|
||||
const { alertInstanceFactory, savedObjectsClient, scopedClusterClient } = services;
|
||||
const { sources } = libs;
|
||||
|
||||
const sourceConfiguration = await sources.getSourceConfiguration(savedObjectsClient, 'default');
|
||||
|
@ -82,7 +83,7 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) =>
|
|||
validatedParams,
|
||||
timestampField,
|
||||
indexPattern,
|
||||
callCluster,
|
||||
scopedClusterClient.asCurrentUser,
|
||||
alertInstanceFactory
|
||||
);
|
||||
} else {
|
||||
|
@ -90,7 +91,7 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) =>
|
|||
validatedParams,
|
||||
timestampField,
|
||||
indexPattern,
|
||||
callCluster,
|
||||
scopedClusterClient.asCurrentUser,
|
||||
alertInstanceFactory
|
||||
);
|
||||
}
|
||||
|
@ -103,7 +104,7 @@ async function executeAlert(
|
|||
alertParams: CountAlertParams,
|
||||
timestampField: string,
|
||||
indexPattern: string,
|
||||
callCluster: LogThresholdAlertServices['callCluster'],
|
||||
esClient: ElasticsearchClient,
|
||||
alertInstanceFactory: LogThresholdAlertServices['alertInstanceFactory']
|
||||
) {
|
||||
const query = getESQuery(alertParams, timestampField, indexPattern);
|
||||
|
@ -114,14 +115,14 @@ async function executeAlert(
|
|||
|
||||
if (hasGroupBy(alertParams)) {
|
||||
processGroupByResults(
|
||||
await getGroupedResults(query, callCluster),
|
||||
await getGroupedResults(query, esClient),
|
||||
alertParams,
|
||||
alertInstanceFactory,
|
||||
updateAlertInstance
|
||||
);
|
||||
} else {
|
||||
processUngroupedResults(
|
||||
await getUngroupedResults(query, callCluster),
|
||||
await getUngroupedResults(query, esClient),
|
||||
alertParams,
|
||||
alertInstanceFactory,
|
||||
updateAlertInstance
|
||||
|
@ -133,7 +134,7 @@ async function executeRatioAlert(
|
|||
alertParams: RatioAlertParams,
|
||||
timestampField: string,
|
||||
indexPattern: string,
|
||||
callCluster: LogThresholdAlertServices['callCluster'],
|
||||
esClient: ElasticsearchClient,
|
||||
alertInstanceFactory: LogThresholdAlertServices['alertInstanceFactory']
|
||||
) {
|
||||
// Ratio alert params are separated out into two standard sets of alert params
|
||||
|
@ -155,8 +156,8 @@ async function executeRatioAlert(
|
|||
}
|
||||
|
||||
if (hasGroupBy(alertParams)) {
|
||||
const numeratorGroupedResults = await getGroupedResults(numeratorQuery, callCluster);
|
||||
const denominatorGroupedResults = await getGroupedResults(denominatorQuery, callCluster);
|
||||
const numeratorGroupedResults = await getGroupedResults(numeratorQuery, esClient);
|
||||
const denominatorGroupedResults = await getGroupedResults(denominatorQuery, esClient);
|
||||
processGroupByRatioResults(
|
||||
numeratorGroupedResults,
|
||||
denominatorGroupedResults,
|
||||
|
@ -165,8 +166,8 @@ async function executeRatioAlert(
|
|||
updateAlertInstance
|
||||
);
|
||||
} else {
|
||||
const numeratorUngroupedResults = await getUngroupedResults(numeratorQuery, callCluster);
|
||||
const denominatorUngroupedResults = await getUngroupedResults(denominatorQuery, callCluster);
|
||||
const numeratorUngroupedResults = await getUngroupedResults(numeratorQuery, esClient);
|
||||
const denominatorUngroupedResults = await getUngroupedResults(denominatorQuery, esClient);
|
||||
processUngroupedRatioResults(
|
||||
numeratorUngroupedResults,
|
||||
denominatorUngroupedResults,
|
||||
|
@ -605,17 +606,11 @@ const getQueryMappingForComparator = (comparator: Comparator) => {
|
|||
return queryMappings[comparator];
|
||||
};
|
||||
|
||||
const getUngroupedResults = async (
|
||||
query: object,
|
||||
callCluster: LogThresholdAlertServices['callCluster']
|
||||
) => {
|
||||
return decodeOrThrow(UngroupedSearchQueryResponseRT)(await callCluster('search', query));
|
||||
const getUngroupedResults = async (query: object, esClient: ElasticsearchClient) => {
|
||||
return decodeOrThrow(UngroupedSearchQueryResponseRT)((await esClient.search(query)).body);
|
||||
};
|
||||
|
||||
const getGroupedResults = async (
|
||||
query: object,
|
||||
callCluster: LogThresholdAlertServices['callCluster']
|
||||
) => {
|
||||
const getGroupedResults = async (query: object, esClient: ElasticsearchClient) => {
|
||||
let compositeGroupBuckets: GroupedSearchQueryResponse['aggregations']['groups']['buckets'] = [];
|
||||
let lastAfterKey: GroupedSearchQueryResponse['aggregations']['groups']['after_key'] | undefined;
|
||||
|
||||
|
@ -623,7 +618,7 @@ const getGroupedResults = async (
|
|||
const queryWithAfterKey: any = { ...query };
|
||||
queryWithAfterKey.body.aggregations.groups.composite.after = lastAfterKey;
|
||||
const groupResponse: GroupedSearchQueryResponse = decodeOrThrow(GroupedSearchQueryResponseRT)(
|
||||
await callCluster('search', queryWithAfterKey)
|
||||
(await esClient.search(queryWithAfterKey)).body
|
||||
);
|
||||
compositeGroupBuckets = [
|
||||
...compositeGroupBuckets,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { mapValues, first, last, isNaN } from 'lodash';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import {
|
||||
isTooManyBucketsPreviewException,
|
||||
TOO_MANY_BUCKETS_PREVIEW_EXCEPTION,
|
||||
|
@ -13,7 +14,6 @@ import {
|
|||
import { InfraSource } from '../../../../../common/http_api/source_api';
|
||||
import { InfraDatabaseSearchResponse } from '../../../adapters/framework/adapter_types';
|
||||
import { createAfterKeyHandler } from '../../../../utils/create_afterkey_handler';
|
||||
import { AlertServices } from '../../../../../../alerting/server';
|
||||
import { getAllCompositeData } from '../../../../utils/get_all_composite_data';
|
||||
import { DOCUMENT_COUNT_I18N } from '../../common/messages';
|
||||
import { UNGROUPED_FACTORY_KEY } from '../../common/utils';
|
||||
|
@ -43,7 +43,7 @@ export interface EvaluatedAlertParams {
|
|||
}
|
||||
|
||||
export const evaluateAlert = <Params extends EvaluatedAlertParams = EvaluatedAlertParams>(
|
||||
callCluster: AlertServices['callCluster'],
|
||||
esClient: ElasticsearchClient,
|
||||
params: Params,
|
||||
config: InfraSource['configuration'],
|
||||
timeframe?: { start: number; end: number }
|
||||
|
@ -52,7 +52,7 @@ export const evaluateAlert = <Params extends EvaluatedAlertParams = EvaluatedAle
|
|||
return Promise.all(
|
||||
criteria.map(async (criterion) => {
|
||||
const currentValues = await getMetric(
|
||||
callCluster,
|
||||
esClient,
|
||||
criterion,
|
||||
config.metricAlias,
|
||||
config.fields.timestamp,
|
||||
|
@ -91,7 +91,7 @@ export const evaluateAlert = <Params extends EvaluatedAlertParams = EvaluatedAle
|
|||
};
|
||||
|
||||
const getMetric: (
|
||||
callCluster: AlertServices['callCluster'],
|
||||
esClient: ElasticsearchClient,
|
||||
params: MetricExpressionParams,
|
||||
index: string,
|
||||
timefield: string,
|
||||
|
@ -99,7 +99,7 @@ const getMetric: (
|
|||
filterQuery: string | undefined,
|
||||
timeframe?: { start: number; end: number }
|
||||
) => Promise<Record<string, number[]>> = async function (
|
||||
callCluster,
|
||||
esClient,
|
||||
params,
|
||||
index,
|
||||
timefield,
|
||||
|
@ -127,7 +127,7 @@ const getMetric: (
|
|||
(response) => response.aggregations?.groupings?.after_key
|
||||
);
|
||||
const compositeBuckets = (await getAllCompositeData(
|
||||
(body) => callCluster('search', { body, index }),
|
||||
(body) => esClient.search({ body, index }),
|
||||
searchBody,
|
||||
bucketSelector,
|
||||
afterKeyHandler
|
||||
|
@ -142,7 +142,7 @@ const getMetric: (
|
|||
{}
|
||||
);
|
||||
}
|
||||
const result = await callCluster('search', {
|
||||
const { body: result } = await esClient.search({
|
||||
body: searchBody,
|
||||
index,
|
||||
});
|
||||
|
|
|
@ -16,6 +16,8 @@ import {
|
|||
} from '../../../../../alerting/server/mocks';
|
||||
import { InfraSources } from '../../sources';
|
||||
import { MetricThresholdAlertExecutorOptions } from './register_metric_threshold_alert_type';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
interface AlertTestInstance {
|
||||
instance: AlertInstanceMock;
|
||||
|
@ -439,26 +441,36 @@ const mockLibs: any = {
|
|||
const executor = createMetricThresholdExecutor(mockLibs);
|
||||
|
||||
const services: AlertServicesMock = alertsMock.createAlertServices();
|
||||
services.callCluster.mockImplementation(async (_: string, { body, index }: any) => {
|
||||
if (index === 'alternatebeat-*') return mocks.changedSourceIdResponse;
|
||||
const metric = body.query.bool.filter[1]?.exists.field;
|
||||
if (body.aggs.groupings) {
|
||||
if (body.aggs.groupings.composite.after) {
|
||||
return mocks.compositeEndResponse;
|
||||
services.scopedClusterClient.asCurrentUser.search.mockImplementation((params?: any): any => {
|
||||
if (params.index === 'alternatebeat-*') return mocks.changedSourceIdResponse;
|
||||
const metric = params?.body.query.bool.filter[1]?.exists.field;
|
||||
if (params?.body.aggs.groupings) {
|
||||
if (params?.body.aggs.groupings.composite.after) {
|
||||
return elasticsearchClientMock.createSuccessTransportRequestPromise(
|
||||
mocks.compositeEndResponse
|
||||
);
|
||||
}
|
||||
if (metric === 'test.metric.2') {
|
||||
return mocks.alternateCompositeResponse;
|
||||
return elasticsearchClientMock.createSuccessTransportRequestPromise(
|
||||
mocks.alternateCompositeResponse
|
||||
);
|
||||
}
|
||||
return mocks.basicCompositeResponse;
|
||||
return elasticsearchClientMock.createSuccessTransportRequestPromise(
|
||||
mocks.basicCompositeResponse
|
||||
);
|
||||
}
|
||||
if (metric === 'test.metric.2') {
|
||||
return mocks.alternateMetricResponse;
|
||||
return elasticsearchClientMock.createSuccessTransportRequestPromise(
|
||||
mocks.alternateMetricResponse
|
||||
);
|
||||
} else if (metric === 'test.metric.3') {
|
||||
return body.aggs.aggregatedIntervals.aggregations.aggregatedValue_max
|
||||
? mocks.emptyRateResponse
|
||||
: mocks.emptyMetricResponse;
|
||||
return elasticsearchClientMock.createSuccessTransportRequestPromise(
|
||||
params?.body.aggs.aggregatedIntervals.aggregations.aggregatedValue_max
|
||||
? mocks.emptyRateResponse
|
||||
: mocks.emptyMetricResponse
|
||||
);
|
||||
}
|
||||
return mocks.basicMetricResponse;
|
||||
return elasticsearchClientMock.createSuccessTransportRequestPromise(mocks.basicMetricResponse);
|
||||
});
|
||||
services.savedObjectsClient.get.mockImplementation(async (type: string, sourceId: string) => {
|
||||
if (sourceId === 'alternate')
|
||||
|
|
|
@ -44,7 +44,7 @@ export const createMetricThresholdExecutor = (
|
|||
);
|
||||
const config = source.configuration;
|
||||
const alertResults = await evaluateAlert(
|
||||
services.callCluster,
|
||||
services.scopedClusterClient.asCurrentUser,
|
||||
params as EvaluatedAlertParams,
|
||||
config
|
||||
);
|
||||
|
|
|
@ -9,6 +9,8 @@ import * as mocks from './test_mocks';
|
|||
import { Comparator, Aggregators, MetricExpressionParams } from './types';
|
||||
import { alertsMock, AlertServicesMock } from '../../../../../alerting/server/mocks';
|
||||
import { previewMetricThresholdAlert } from './preview_metric_threshold_alert';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
describe('Previewing the metric threshold alert type', () => {
|
||||
describe('querying the entire infrastructure', () => {
|
||||
|
@ -163,21 +165,32 @@ describe('Previewing the metric threshold alert type', () => {
|
|||
});
|
||||
|
||||
const services: AlertServicesMock = alertsMock.createAlertServices();
|
||||
services.callCluster.mockImplementation(async (_: string, { body, index }: any) => {
|
||||
const metric = body.query.bool.filter[1]?.exists.field;
|
||||
if (body.aggs.groupings) {
|
||||
if (body.aggs.groupings.composite.after) {
|
||||
return mocks.compositeEndResponse;
|
||||
|
||||
services.scopedClusterClient.asCurrentUser.search.mockImplementation((params?: any): any => {
|
||||
const metric = params?.body.query.bool.filter[1]?.exists.field;
|
||||
if (params?.body.aggs.groupings) {
|
||||
if (params?.body.aggs.groupings.composite.after) {
|
||||
return elasticsearchClientMock.createSuccessTransportRequestPromise(
|
||||
mocks.compositeEndResponse
|
||||
);
|
||||
}
|
||||
return mocks.basicCompositePreviewResponse;
|
||||
return elasticsearchClientMock.createSuccessTransportRequestPromise(
|
||||
mocks.basicCompositePreviewResponse
|
||||
);
|
||||
}
|
||||
if (metric === 'test.metric.2') {
|
||||
return mocks.alternateMetricPreviewResponse;
|
||||
return elasticsearchClientMock.createSuccessTransportRequestPromise(
|
||||
mocks.alternateMetricPreviewResponse
|
||||
);
|
||||
}
|
||||
if (metric === 'test.metric.3') {
|
||||
return mocks.repeatingMetricPreviewResponse;
|
||||
return elasticsearchClientMock.createSuccessTransportRequestPromise(
|
||||
mocks.repeatingMetricPreviewResponse
|
||||
);
|
||||
}
|
||||
return mocks.basicMetricPreviewResponse;
|
||||
return elasticsearchClientMock.createSuccessTransportRequestPromise(
|
||||
mocks.basicMetricPreviewResponse
|
||||
);
|
||||
});
|
||||
|
||||
const baseCriterion = {
|
||||
|
@ -197,7 +210,7 @@ const config = {
|
|||
} as any;
|
||||
|
||||
const baseParams = {
|
||||
callCluster: services.callCluster,
|
||||
esClient: services.scopedClusterClient.asCurrentUser,
|
||||
params: {
|
||||
criteria: [baseCriterion],
|
||||
groupBy: undefined,
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
TOO_MANY_BUCKETS_PREVIEW_EXCEPTION,
|
||||
isTooManyBucketsPreviewException,
|
||||
} from '../../../../common/alerting/metrics';
|
||||
import { ILegacyScopedClusterClient } from '../../../../../../../src/core/server';
|
||||
import { ElasticsearchClient } from '../../../../../../../src/core/server';
|
||||
import { InfraSource } from '../../../../common/http_api/source_api';
|
||||
import { getIntervalInSeconds } from '../../../utils/get_interval_in_seconds';
|
||||
import { PreviewResult } from '../common/types';
|
||||
|
@ -21,7 +21,7 @@ import { evaluateAlert } from './lib/evaluate_alert';
|
|||
const MAX_ITERATIONS = 50;
|
||||
|
||||
interface PreviewMetricThresholdAlertParams {
|
||||
callCluster: ILegacyScopedClusterClient['callAsCurrentUser'];
|
||||
esClient: ElasticsearchClient;
|
||||
params: {
|
||||
criteria: MetricExpressionParams[];
|
||||
groupBy: string | undefined | string[];
|
||||
|
@ -43,7 +43,7 @@ export const previewMetricThresholdAlert: (
|
|||
precalculatedNumberOfGroups?: number
|
||||
) => Promise<PreviewResult[]> = async (
|
||||
{
|
||||
callCluster,
|
||||
esClient,
|
||||
params,
|
||||
config,
|
||||
lookback,
|
||||
|
@ -79,7 +79,7 @@ export const previewMetricThresholdAlert: (
|
|||
|
||||
// Get a date histogram using the bucket interval and the lookback interval
|
||||
try {
|
||||
const alertResults = await evaluateAlert(callCluster, params, config, timeframe);
|
||||
const alertResults = await evaluateAlert(esClient, params, config, timeframe);
|
||||
const groups = Object.keys(first(alertResults)!);
|
||||
|
||||
// Now determine how to interpolate this histogram based on the alert interval
|
||||
|
@ -174,7 +174,7 @@ export const previewMetricThresholdAlert: (
|
|||
// If there's too much data on the first request, recursively slice the lookback interval
|
||||
// until all the data can be retrieved
|
||||
const basePreviewParams = {
|
||||
callCluster,
|
||||
esClient,
|
||||
params,
|
||||
config,
|
||||
lookback,
|
||||
|
@ -187,7 +187,7 @@ export const previewMetricThresholdAlert: (
|
|||
// If this is still the first iteration, try to get the number of groups in order to
|
||||
// calculate max buckets. If this fails, just estimate based on 1 group
|
||||
const currentAlertResults = !precalculatedNumberOfGroups
|
||||
? await evaluateAlert(callCluster, params, config)
|
||||
? await evaluateAlert(esClient, params, config)
|
||||
: [];
|
||||
const numberOfGroups =
|
||||
precalculatedNumberOfGroups ?? Math.max(Object.keys(first(currentAlertResults)!).length, 1);
|
||||
|
|
|
@ -26,7 +26,6 @@ import { InfraBackendLibs } from '../../lib/infra_types';
|
|||
import { assertHasInfraMlPlugins } from '../../utils/request_context';
|
||||
|
||||
export const initAlertPreviewRoute = ({ framework, sources }: InfraBackendLibs) => {
|
||||
const { callWithRequest } = framework;
|
||||
framework.registerRoute(
|
||||
{
|
||||
method: 'post',
|
||||
|
@ -46,9 +45,7 @@ export const initAlertPreviewRoute = ({ framework, sources }: InfraBackendLibs)
|
|||
alertNotifyWhen,
|
||||
} = request.body;
|
||||
|
||||
const callCluster = (endpoint: string, opts: Record<string, any>) => {
|
||||
return callWithRequest(requestContext, endpoint, opts);
|
||||
};
|
||||
const esClient = requestContext.core.elasticsearch.client.asCurrentUser;
|
||||
|
||||
const source = await sources.getSourceConfiguration(
|
||||
requestContext.core.savedObjects.client,
|
||||
|
@ -64,7 +61,7 @@ export const initAlertPreviewRoute = ({ framework, sources }: InfraBackendLibs)
|
|||
filterQuery,
|
||||
} = request.body as MetricThresholdAlertPreviewRequestParams;
|
||||
const previewResult = await previewMetricThresholdAlert({
|
||||
callCluster,
|
||||
esClient,
|
||||
params: { criteria, filterQuery, groupBy },
|
||||
lookback,
|
||||
config: source.configuration,
|
||||
|
@ -86,7 +83,7 @@ export const initAlertPreviewRoute = ({ framework, sources }: InfraBackendLibs)
|
|||
filterQuery,
|
||||
} = request.body as InventoryAlertPreviewRequestParams;
|
||||
const previewResult = await previewInventoryMetricThresholdAlert({
|
||||
callCluster,
|
||||
esClient,
|
||||
params: { criteria, filterQuery, nodeType },
|
||||
lookback,
|
||||
source,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ApiResponse } from '@elastic/elasticsearch/lib/Transport';
|
||||
import { InfraDatabaseSearchResponse } from '../lib/adapters/framework';
|
||||
|
||||
export const getAllCompositeData = async <
|
||||
|
@ -12,13 +13,15 @@ export const getAllCompositeData = async <
|
|||
Bucket = {},
|
||||
Options extends object = {}
|
||||
>(
|
||||
callCluster: (options: Options) => Promise<InfraDatabaseSearchResponse<{}, Aggregation>>,
|
||||
esClientSearch: (
|
||||
options: Options
|
||||
) => Promise<ApiResponse<InfraDatabaseSearchResponse<{}, Aggregation>>>,
|
||||
options: Options,
|
||||
bucketSelector: (response: InfraDatabaseSearchResponse<{}, Aggregation>) => Bucket[],
|
||||
onAfterKey: (options: Options, response: InfraDatabaseSearchResponse<{}, Aggregation>) => Options,
|
||||
previousBuckets: Bucket[] = []
|
||||
): Promise<Bucket[]> => {
|
||||
const response = await callCluster(options);
|
||||
const { body: response } = await esClientSearch(options);
|
||||
|
||||
// Nothing available, return the previous buckets.
|
||||
if (response.hits.total.value === 0) {
|
||||
|
@ -40,7 +43,7 @@ export const getAllCompositeData = async <
|
|||
// There is possibly more data, concat previous and current buckets and call ourselves recursively.
|
||||
const newOptions = onAfterKey(options, response);
|
||||
return getAllCompositeData(
|
||||
callCluster,
|
||||
esClientSearch,
|
||||
newOptions,
|
||||
bucketSelector,
|
||||
onAfterKey,
|
||||
|
|
|
@ -58,10 +58,10 @@ export class ListPlugin
|
|||
user,
|
||||
});
|
||||
},
|
||||
getListClient: (callCluster, spaceId, user): ListClient => {
|
||||
getListClient: (esClient, spaceId, user): ListClient => {
|
||||
return new ListClient({
|
||||
callCluster,
|
||||
config,
|
||||
esClient,
|
||||
spaceId,
|
||||
user,
|
||||
});
|
||||
|
@ -86,9 +86,7 @@ export class ListPlugin
|
|||
core: {
|
||||
savedObjects: { client: savedObjectsClient },
|
||||
elasticsearch: {
|
||||
legacy: {
|
||||
client: { callAsCurrentUser: callCluster },
|
||||
},
|
||||
client: { asCurrentUser: esClient },
|
||||
},
|
||||
},
|
||||
} = context;
|
||||
|
@ -105,8 +103,8 @@ export class ListPlugin
|
|||
}),
|
||||
getListClient: (): ListClient =>
|
||||
new ListClient({
|
||||
callCluster,
|
||||
config,
|
||||
esClient,
|
||||
spaceId,
|
||||
user,
|
||||
}),
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { CreateListItemOptions } from '../items';
|
||||
import {
|
||||
DATE_NOW,
|
||||
|
@ -19,9 +21,9 @@ import {
|
|||
} from '../../../common/constants.mock';
|
||||
|
||||
export const getCreateListItemOptionsMock = (): CreateListItemOptions => ({
|
||||
callCluster: getCallClusterMock(),
|
||||
dateNow: DATE_NOW,
|
||||
deserializer: undefined,
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
id: LIST_ITEM_ID,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { getListItemResponseMock } from '../../../common/schemas/response/list_item_schema.mock';
|
||||
import { getIndexESListItemMock } from '../../../common/schemas/elastic_query/index_es_list_item_schema.mock';
|
||||
import { LIST_ITEM_ID, LIST_ITEM_INDEX } from '../../../common/constants.mock';
|
||||
|
@ -23,13 +26,17 @@ describe('crete_list_item', () => {
|
|||
|
||||
test('it returns a list item as expected with the id changed out for the elastic id', async () => {
|
||||
const options = getCreateListItemOptionsMock();
|
||||
const listItem = await createListItem(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.index.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' })
|
||||
);
|
||||
const listItem = await createListItem({ ...options, esClient });
|
||||
const expected = getListItemResponseMock();
|
||||
expected.id = 'elastic-id-123';
|
||||
expect(listItem).toEqual(expected);
|
||||
});
|
||||
|
||||
test('It calls "callCluster" with body, index, and listIndex', async () => {
|
||||
test('It calls "esClient" with body, index, and listIndex', async () => {
|
||||
const options = getCreateListItemOptionsMock();
|
||||
await createListItem(options);
|
||||
const body = getIndexESListItemMock();
|
||||
|
@ -39,13 +46,17 @@ describe('crete_list_item', () => {
|
|||
index: LIST_ITEM_INDEX,
|
||||
refresh: 'wait_for',
|
||||
};
|
||||
expect(options.callCluster).toBeCalledWith('index', expected);
|
||||
expect(options.esClient.index).toBeCalledWith(expected);
|
||||
});
|
||||
|
||||
test('It returns an auto-generated id if id is sent in undefined', async () => {
|
||||
const options = getCreateListItemOptionsMock();
|
||||
options.id = undefined;
|
||||
const list = await createListItem(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.index.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' })
|
||||
);
|
||||
const list = await createListItem({ ...options, esClient });
|
||||
const expected = getListItemResponseMock();
|
||||
expected.id = 'elastic-id-123';
|
||||
expect(list).toEqual(expected);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import uuid from 'uuid';
|
||||
import { CreateDocumentResponse } from 'elasticsearch';
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import {
|
||||
DeserializerOrUndefined,
|
||||
|
@ -28,7 +28,7 @@ export interface CreateListItemOptions {
|
|||
listId: string;
|
||||
type: Type;
|
||||
value: string;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listItemIndex: string;
|
||||
user: string;
|
||||
meta: MetaOrUndefined;
|
||||
|
@ -43,7 +43,7 @@ export const createListItem = async ({
|
|||
listId,
|
||||
type,
|
||||
value,
|
||||
callCluster,
|
||||
esClient,
|
||||
listItemIndex,
|
||||
user,
|
||||
meta,
|
||||
|
@ -69,7 +69,7 @@ export const createListItem = async ({
|
|||
...baseBody,
|
||||
...elasticQuery,
|
||||
};
|
||||
const response = await callCluster<CreateDocumentResponse>('index', {
|
||||
const { body: response } = await esClient.index<CreateDocumentResponse>({
|
||||
body,
|
||||
id,
|
||||
index: listItemIndex,
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { CreateListItemsBulkOptions } from '../items';
|
||||
import {
|
||||
DATE_NOW,
|
||||
|
@ -20,9 +22,9 @@ import {
|
|||
} from '../../../common/constants.mock';
|
||||
|
||||
export const getCreateListItemBulkOptionsMock = (): CreateListItemsBulkOptions => ({
|
||||
callCluster: getCallClusterMock(),
|
||||
dateNow: DATE_NOW,
|
||||
deserializer: undefined,
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
meta: META,
|
||||
|
|
|
@ -20,13 +20,13 @@ describe('crete_list_item_bulk', () => {
|
|||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('It calls "callCluster" with body, index, and the bulk items', async () => {
|
||||
test('It calls "esClient" with body, index, and the bulk items', async () => {
|
||||
const options = getCreateListItemBulkOptionsMock();
|
||||
await createListItemsBulk(options);
|
||||
const firstRecord = getIndexESListItemMock();
|
||||
const secondRecord = getIndexESListItemMock(VALUE_2);
|
||||
[firstRecord.tie_breaker_id, secondRecord.tie_breaker_id] = TIE_BREAKERS;
|
||||
expect(options.callCluster).toBeCalledWith('bulk', {
|
||||
expect(options.esClient.bulk).toBeCalledWith({
|
||||
body: [
|
||||
{ create: { _index: LIST_ITEM_INDEX } },
|
||||
firstRecord,
|
||||
|
@ -41,7 +41,7 @@ describe('crete_list_item_bulk', () => {
|
|||
test('It should not call the dataClient when the values are empty', async () => {
|
||||
const options = getCreateListItemBulkOptionsMock();
|
||||
options.value = [];
|
||||
expect(options.callCluster).not.toBeCalled();
|
||||
expect(options.esClient.bulk).not.toBeCalled();
|
||||
});
|
||||
|
||||
test('It should skip over a value if it is not able to add that item because it is not parsable such as an ip_range with a serializer that only matches one ip', async () => {
|
||||
|
@ -52,7 +52,7 @@ describe('crete_list_item_bulk', () => {
|
|||
value: ['127.0.0.1', '127.0.0.2'],
|
||||
};
|
||||
await createListItemsBulk(options);
|
||||
expect(options.callCluster).toBeCalledWith('bulk', {
|
||||
expect(options.esClient.bulk).toBeCalledWith({
|
||||
body: [
|
||||
{ create: { _index: LIST_ITEM_INDEX } },
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import uuid from 'uuid';
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import { transformListItemToElasticQuery } from '../utils';
|
||||
import {
|
||||
|
@ -24,7 +24,7 @@ export interface CreateListItemsBulkOptions {
|
|||
listId: string;
|
||||
type: Type;
|
||||
value: string[];
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listItemIndex: string;
|
||||
user: string;
|
||||
meta: MetaOrUndefined;
|
||||
|
@ -38,7 +38,7 @@ export const createListItemsBulk = async ({
|
|||
deserializer,
|
||||
serializer,
|
||||
value,
|
||||
callCluster,
|
||||
esClient,
|
||||
listItemIndex,
|
||||
user,
|
||||
meta,
|
||||
|
@ -82,7 +82,7 @@ export const createListItemsBulk = async ({
|
|||
[]
|
||||
);
|
||||
try {
|
||||
await callCluster('bulk', {
|
||||
await esClient.bulk({
|
||||
body,
|
||||
index: listItemIndex,
|
||||
refresh: 'wait_for',
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { DeleteListItemOptions } from '../items';
|
||||
import { LIST_ITEM_ID, LIST_ITEM_INDEX } from '../../../common/constants.mock';
|
||||
|
||||
export const getDeleteListItemOptionsMock = (): DeleteListItemOptions => ({
|
||||
callCluster: getCallClusterMock(),
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
id: LIST_ITEM_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
});
|
||||
|
|
|
@ -50,6 +50,6 @@ describe('delete_list_item', () => {
|
|||
index: LIST_ITEM_INDEX,
|
||||
refresh: 'wait_for',
|
||||
};
|
||||
expect(options.callCluster).toBeCalledWith('delete', deleteQuery);
|
||||
expect(options.esClient.delete).toBeCalledWith(deleteQuery);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import { Id, ListItemSchema } from '../../../common/schemas';
|
||||
|
||||
|
@ -13,20 +13,20 @@ import { getListItem } from '.';
|
|||
|
||||
export interface DeleteListItemOptions {
|
||||
id: Id;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listItemIndex: string;
|
||||
}
|
||||
|
||||
export const deleteListItem = async ({
|
||||
id,
|
||||
callCluster,
|
||||
esClient,
|
||||
listItemIndex,
|
||||
}: DeleteListItemOptions): Promise<ListItemSchema | null> => {
|
||||
const listItem = await getListItem({ callCluster, id, listItemIndex });
|
||||
const listItem = await getListItem({ esClient, id, listItemIndex });
|
||||
if (listItem == null) {
|
||||
return null;
|
||||
} else {
|
||||
await callCluster('delete', {
|
||||
await esClient.delete({
|
||||
id,
|
||||
index: listItemIndex,
|
||||
refresh: 'wait_for',
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { DeleteListItemByValueOptions } from '../items';
|
||||
import { LIST_ID, LIST_ITEM_INDEX, TYPE, VALUE } from '../../../common/constants.mock';
|
||||
|
||||
export const getDeleteListItemByValueOptionsMock = (): DeleteListItemByValueOptions => ({
|
||||
callCluster: getCallClusterMock(),
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
type: TYPE,
|
||||
|
|
|
@ -61,8 +61,8 @@ describe('delete_list_item_by_value', () => {
|
|||
},
|
||||
},
|
||||
index: '.items',
|
||||
refresh: 'wait_for',
|
||||
refresh: false,
|
||||
};
|
||||
expect(options.callCluster).toBeCalledWith('deleteByQuery', deleteByQuery);
|
||||
expect(options.esClient.deleteByQuery).toBeCalledWith(deleteByQuery);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import { ListItemArraySchema, Type } from '../../../common/schemas';
|
||||
import { getQueryFilterFromTypeValue } from '../utils';
|
||||
|
@ -16,7 +16,7 @@ export interface DeleteListItemByValueOptions {
|
|||
listId: string;
|
||||
type: Type;
|
||||
value: string;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listItemIndex: string;
|
||||
}
|
||||
|
||||
|
@ -24,11 +24,11 @@ export const deleteListItemByValue = async ({
|
|||
listId,
|
||||
value,
|
||||
type,
|
||||
callCluster,
|
||||
esClient,
|
||||
listItemIndex,
|
||||
}: DeleteListItemByValueOptions): Promise<ListItemArraySchema> => {
|
||||
const listItems = await getListItemByValues({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId,
|
||||
listItemIndex,
|
||||
type,
|
||||
|
@ -40,7 +40,7 @@ export const deleteListItemByValue = async ({
|
|||
type,
|
||||
value: values,
|
||||
});
|
||||
await callCluster('deleteByQuery', {
|
||||
await esClient.deleteByQuery({
|
||||
body: {
|
||||
query: {
|
||||
bool: {
|
||||
|
@ -49,7 +49,7 @@ export const deleteListItemByValue = async ({
|
|||
},
|
||||
},
|
||||
index: listItemIndex,
|
||||
refresh: 'wait_for',
|
||||
refresh: false,
|
||||
});
|
||||
return listItems;
|
||||
};
|
||||
|
|
|
@ -6,11 +6,10 @@
|
|||
*/
|
||||
|
||||
import { Client } from 'elasticsearch';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { getSearchListMock } from '../../../common/schemas/elastic_response/search_es_list_schema.mock';
|
||||
import { getShardMock } from '../../../common/get_shard.mock';
|
||||
import { getSearchListItemMock } from '../../../common/schemas/elastic_response/search_es_list_item_schema.mock';
|
||||
import { getCallClusterMockMultiTimes } from '../../../common/get_call_cluster.mock';
|
||||
import { LIST_ID, LIST_INDEX, LIST_ITEM_INDEX } from '../../../common/constants.mock';
|
||||
|
||||
import { FindListItemOptions } from './find_list_item';
|
||||
|
@ -23,14 +22,9 @@ export const getFindCount = (): ReturnType<Client['count']> => {
|
|||
};
|
||||
|
||||
export const getFindListItemOptionsMock = (): FindListItemOptions => {
|
||||
const callCluster = getCallClusterMockMultiTimes([
|
||||
getSearchListMock(),
|
||||
getFindCount(),
|
||||
getSearchListItemMock(),
|
||||
]);
|
||||
return {
|
||||
callCluster,
|
||||
currentIndexPosition: 0,
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
filter: '',
|
||||
listId: LIST_ID,
|
||||
listIndex: LIST_INDEX,
|
||||
|
|
|
@ -5,9 +5,12 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getEmptySearchListMock } from '../../../common/schemas/elastic_response/search_es_list_schema.mock';
|
||||
import { getCallClusterMockMultiTimes } from '../../../common/get_call_cluster.mock';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { getShardMock } from '../../../common/get_shard.mock';
|
||||
import { getFoundListItemSchemaMock } from '../../../common/schemas/response/found_list_item_schema.mock';
|
||||
import { getEmptySearchListMock } from '../../../common/schemas/elastic_response/search_es_list_schema.mock';
|
||||
|
||||
import { getFindListItemOptionsMock } from './find_list_item.mock';
|
||||
import { findListItem } from './find_list_item';
|
||||
|
@ -15,15 +18,53 @@ import { findListItem } from './find_list_item';
|
|||
describe('find_list_item', () => {
|
||||
test('should find a simple single list item', async () => {
|
||||
const options = getFindListItemOptionsMock();
|
||||
const item = await findListItem(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.count.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({ count: 1 })
|
||||
);
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({
|
||||
_scroll_id: '123',
|
||||
_shards: getShardMock(),
|
||||
hits: {
|
||||
hits: [
|
||||
{
|
||||
_id: 'some-list-item-id',
|
||||
_source: {
|
||||
_version: 'undefined',
|
||||
created_at: '2020-04-20T15:25:31.830Z',
|
||||
created_by: 'some user',
|
||||
date_range: '127.0.0.1',
|
||||
deserializer: undefined,
|
||||
list_id: 'some-list-id',
|
||||
meta: {},
|
||||
serializer: undefined,
|
||||
tie_breaker_id: '6a76b69d-80df-4ab2-8c3e-85f466b06a0e',
|
||||
type: 'ip',
|
||||
updated_at: '2020-04-20T15:25:31.830Z',
|
||||
updated_by: 'some user',
|
||||
},
|
||||
},
|
||||
],
|
||||
max_score: 0,
|
||||
total: 1,
|
||||
},
|
||||
timed_out: false,
|
||||
took: 10,
|
||||
})
|
||||
);
|
||||
const item = await findListItem({ ...options, esClient });
|
||||
const expected = getFoundListItemSchemaMock();
|
||||
expect(item).toEqual(expected);
|
||||
});
|
||||
|
||||
test('should return null if the list is null', async () => {
|
||||
const options = getFindListItemOptionsMock();
|
||||
options.callCluster = getCallClusterMockMultiTimes([getEmptySearchListMock()]);
|
||||
const item = await findListItem(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(getEmptySearchListMock())
|
||||
);
|
||||
const item = await findListItem({ ...options, esClient });
|
||||
expect(item).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { SearchResponse } from 'elasticsearch';
|
||||
|
||||
import {
|
||||
|
@ -37,13 +37,13 @@ export interface FindListItemOptions {
|
|||
page: Page;
|
||||
sortField: SortFieldOrUndefined;
|
||||
sortOrder: SortOrderOrUndefined;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listIndex: string;
|
||||
listItemIndex: string;
|
||||
}
|
||||
|
||||
export const findListItem = async ({
|
||||
callCluster,
|
||||
esClient,
|
||||
currentIndexPosition,
|
||||
filter,
|
||||
listId,
|
||||
|
@ -55,7 +55,7 @@ export const findListItem = async ({
|
|||
listItemIndex,
|
||||
sortOrder,
|
||||
}: FindListItemOptions): Promise<FoundListItemSchema | null> => {
|
||||
const list = await getList({ callCluster, id: listId, listIndex });
|
||||
const list = await getList({ esClient, id: listId, listIndex });
|
||||
if (list == null) {
|
||||
return null;
|
||||
} else {
|
||||
|
@ -63,8 +63,8 @@ export const findListItem = async ({
|
|||
const sortField =
|
||||
sortFieldWithPossibleValue === 'value' ? list.type : sortFieldWithPossibleValue;
|
||||
const scroll = await scrollToStartPage({
|
||||
callCluster,
|
||||
currentIndexPosition,
|
||||
esClient,
|
||||
filter,
|
||||
hopSize: 100,
|
||||
index: listItemIndex,
|
||||
|
@ -75,25 +75,25 @@ export const findListItem = async ({
|
|||
sortOrder,
|
||||
});
|
||||
|
||||
const { count } = await callCluster('count', {
|
||||
const { body: respose } = await esClient.count<{ count: number }>({
|
||||
body: {
|
||||
query,
|
||||
},
|
||||
ignoreUnavailable: true,
|
||||
ignore_unavailable: true,
|
||||
index: listItemIndex,
|
||||
});
|
||||
|
||||
if (scroll.validSearchAfterFound) {
|
||||
// Note: This typing of response = await callCluster<SearchResponse<SearchEsListSchema>>
|
||||
// Note: This typing of response = await esClient<SearchResponse<SearchEsListSchema>>
|
||||
// is because when you pass in seq_no_primary_term: true it does a "fall through" type and you have
|
||||
// to explicitly define the type <T>.
|
||||
const response = await callCluster<SearchResponse<SearchEsListItemSchema>>('search', {
|
||||
const { body: response } = await esClient.search<SearchResponse<SearchEsListItemSchema>>({
|
||||
body: {
|
||||
query,
|
||||
search_after: scroll.searchAfter,
|
||||
sort: getSortWithTieBreaker({ sortField, sortOrder }),
|
||||
},
|
||||
ignoreUnavailable: true,
|
||||
ignore_unavailable: true,
|
||||
index: listItemIndex,
|
||||
seq_no_primary_term: true,
|
||||
size: perPage,
|
||||
|
@ -107,7 +107,7 @@ export const findListItem = async ({
|
|||
data: transformElasticToListItem({ response, type: list.type }),
|
||||
page,
|
||||
per_page: perPage,
|
||||
total: count,
|
||||
total: respose.count,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
|
@ -115,7 +115,7 @@ export const findListItem = async ({
|
|||
data: [],
|
||||
page,
|
||||
per_page: perPage,
|
||||
total: count,
|
||||
total: respose.count,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { getSearchListItemMock } from '../../../common/schemas/elastic_response/search_es_list_item_schema.mock';
|
||||
import { getListItemResponseMock } from '../../../common/schemas/response/list_item_schema.mock';
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
import {
|
||||
DATE_NOW,
|
||||
LIST_ID,
|
||||
|
@ -30,8 +32,11 @@ describe('get_list_item', () => {
|
|||
|
||||
test('it returns a list item as expected if the list item is found', async () => {
|
||||
const data = getSearchListItemMock();
|
||||
const callCluster = getCallClusterMock(data);
|
||||
const list = await getListItem({ callCluster, id: LIST_ID, listItemIndex: LIST_INDEX });
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(data)
|
||||
);
|
||||
const list = await getListItem({ esClient, id: LIST_ID, listItemIndex: LIST_INDEX });
|
||||
const expected = getListItemResponseMock();
|
||||
expect(list).toEqual(expected);
|
||||
});
|
||||
|
@ -39,8 +44,11 @@ describe('get_list_item', () => {
|
|||
test('it returns null if the search is empty', async () => {
|
||||
const data = getSearchListItemMock();
|
||||
data.hits.hits = [];
|
||||
const callCluster = getCallClusterMock(data);
|
||||
const list = await getListItem({ callCluster, id: LIST_ID, listItemIndex: LIST_INDEX });
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(data)
|
||||
);
|
||||
const list = await getListItem({ esClient, id: LIST_ID, listItemIndex: LIST_INDEX });
|
||||
expect(list).toEqual(null);
|
||||
});
|
||||
|
||||
|
@ -80,8 +88,11 @@ describe('get_list_item', () => {
|
|||
updated_at: DATE_NOW,
|
||||
updated_by: USER,
|
||||
};
|
||||
const callCluster = getCallClusterMock(data);
|
||||
const list = await getListItem({ callCluster, id: LIST_ID, listItemIndex: LIST_INDEX });
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(data)
|
||||
);
|
||||
const list = await getListItem({ esClient, id: LIST_ID, listItemIndex: LIST_INDEX });
|
||||
expect(list).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { SearchResponse } from 'elasticsearch';
|
||||
|
||||
import { Id, ListItemSchema, SearchEsListItemSchema } from '../../../common/schemas';
|
||||
|
@ -14,19 +14,19 @@ import { findSourceType } from '../utils/find_source_type';
|
|||
|
||||
interface GetListItemOptions {
|
||||
id: Id;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listItemIndex: string;
|
||||
}
|
||||
|
||||
export const getListItem = async ({
|
||||
id,
|
||||
callCluster,
|
||||
esClient,
|
||||
listItemIndex,
|
||||
}: GetListItemOptions): Promise<ListItemSchema | null> => {
|
||||
// Note: This typing of response = await callCluster<SearchResponse<SearchEsListSchema>>
|
||||
// Note: This typing of response = await esClient<SearchResponse<SearchEsListSchema>>
|
||||
// is because when you pass in seq_no_primary_term: true it does a "fall through" type and you have
|
||||
// to explicitly define the type <T>.
|
||||
const listItemES = await callCluster<SearchResponse<SearchEsListItemSchema>>('search', {
|
||||
const { body: listItemES } = await esClient.search<SearchResponse<SearchEsListItemSchema>>({
|
||||
body: {
|
||||
query: {
|
||||
term: {
|
||||
|
@ -34,7 +34,7 @@ export const getListItem = async ({
|
|||
},
|
||||
},
|
||||
},
|
||||
ignoreUnavailable: true,
|
||||
ignore_unavailable: true,
|
||||
index: listItemIndex,
|
||||
seq_no_primary_term: true,
|
||||
});
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { GetListItemByValueOptions } from '../items';
|
||||
import { LIST_ID, LIST_ITEM_INDEX, TYPE, VALUE } from '../../../common/constants.mock';
|
||||
|
||||
export const getListItemByValueOptionsMocks = (): GetListItemByValueOptions => ({
|
||||
callCluster: getCallClusterMock(),
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
type: TYPE,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import { ListItemArraySchema, Type } from '../../../common/schemas';
|
||||
|
||||
|
@ -13,7 +13,7 @@ import { getListItemByValues } from '.';
|
|||
|
||||
export interface GetListItemByValueOptions {
|
||||
listId: string;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listItemIndex: string;
|
||||
type: Type;
|
||||
value: string;
|
||||
|
@ -21,13 +21,13 @@ export interface GetListItemByValueOptions {
|
|||
|
||||
export const getListItemByValue = async ({
|
||||
listId,
|
||||
callCluster,
|
||||
esClient,
|
||||
listItemIndex,
|
||||
type,
|
||||
value,
|
||||
}: GetListItemByValueOptions): Promise<ListItemArraySchema> =>
|
||||
getListItemByValues({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId,
|
||||
listItemIndex,
|
||||
type,
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { GetListItemByValuesOptions } from '../items';
|
||||
import { LIST_ID, LIST_ITEM_INDEX, TYPE, VALUE, VALUE_2 } from '../../../common/constants.mock';
|
||||
|
||||
export const getListItemByValuesOptionsMocks = (): GetListItemByValuesOptions => ({
|
||||
callCluster: getCallClusterMock(),
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
type: TYPE,
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { getSearchListItemMock } from '../../../common/schemas/elastic_response/search_es_list_item_schema.mock';
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
import {
|
||||
DATE_NOW,
|
||||
LIST_ID,
|
||||
|
@ -34,9 +36,12 @@ describe('get_list_item_by_values', () => {
|
|||
test('Returns a an empty array if the ES query is also empty', async () => {
|
||||
const data = getSearchListItemMock();
|
||||
data.hits.hits = [];
|
||||
const callCluster = getCallClusterMock(data);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(data)
|
||||
);
|
||||
const listItem = await getListItemByValues({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
type: TYPE,
|
||||
|
@ -48,9 +53,12 @@ describe('get_list_item_by_values', () => {
|
|||
|
||||
test('Returns transformed list item if the data exists within ES', async () => {
|
||||
const data = getSearchListItemMock();
|
||||
const callCluster = getCallClusterMock(data);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(data)
|
||||
);
|
||||
const listItem = await getListItemByValues({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
type: TYPE,
|
||||
|
|
|
@ -5,14 +5,18 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import { ListItemArraySchema, SearchEsListItemSchema, Type } from '../../../common/schemas';
|
||||
import { getQueryFilterFromTypeValue, transformElasticToListItem } from '../utils';
|
||||
import {
|
||||
TransformElasticToListItemOptions,
|
||||
getQueryFilterFromTypeValue,
|
||||
transformElasticToListItem,
|
||||
} from '../utils';
|
||||
|
||||
export interface GetListItemByValuesOptions {
|
||||
listId: string;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listItemIndex: string;
|
||||
type: Type;
|
||||
value: string[];
|
||||
|
@ -20,12 +24,12 @@ export interface GetListItemByValuesOptions {
|
|||
|
||||
export const getListItemByValues = async ({
|
||||
listId,
|
||||
callCluster,
|
||||
esClient,
|
||||
listItemIndex,
|
||||
type,
|
||||
value,
|
||||
}: GetListItemByValuesOptions): Promise<ListItemArraySchema> => {
|
||||
const response = await callCluster<SearchEsListItemSchema>('search', {
|
||||
const { body: response } = await esClient.search<SearchEsListItemSchema>({
|
||||
body: {
|
||||
query: {
|
||||
bool: {
|
||||
|
@ -33,9 +37,12 @@ export const getListItemByValues = async ({
|
|||
},
|
||||
},
|
||||
},
|
||||
ignoreUnavailable: true,
|
||||
ignore_unavailable: true,
|
||||
index: listItemIndex,
|
||||
size: 10000, // TODO: This has a limit on the number which is 10,000 the default of Elastic but we might want to provide a way to increase that number
|
||||
});
|
||||
return transformElasticToListItem({ response, type });
|
||||
return transformElasticToListItem(({
|
||||
response,
|
||||
type,
|
||||
} as unknown) as TransformElasticToListItemOptions);
|
||||
};
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { SearchListItemByValuesOptions } from '../items';
|
||||
import { LIST_ID, LIST_ITEM_INDEX, TYPE, VALUE, VALUE_2 } from '../../../common/constants.mock';
|
||||
|
||||
export const searchListItemByValuesOptionsMocks = (): SearchListItemByValuesOptions => ({
|
||||
callCluster: getCallClusterMock(),
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
type: TYPE,
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { SearchListItemArraySchema } from '../../../common/schemas';
|
||||
import { getSearchListItemMock } from '../../../common/schemas/elastic_response/search_es_list_item_schema.mock';
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
import { LIST_ID, LIST_ITEM_INDEX, TYPE, VALUE, VALUE_2 } from '../../../common/constants.mock';
|
||||
|
||||
import { searchListItemByValues } from './search_list_item_by_values';
|
||||
|
@ -24,9 +26,12 @@ describe('search_list_item_by_values', () => {
|
|||
test('Returns a an empty array of items if the value is empty', async () => {
|
||||
const data = getSearchListItemMock();
|
||||
data.hits.hits = [];
|
||||
const callCluster = getCallClusterMock(data);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(data)
|
||||
);
|
||||
const listItem = await searchListItemByValues({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
type: TYPE,
|
||||
|
@ -39,9 +44,12 @@ describe('search_list_item_by_values', () => {
|
|||
test('Returns a an empty array of items if the ES query is also empty', async () => {
|
||||
const data = getSearchListItemMock();
|
||||
data.hits.hits = [];
|
||||
const callCluster = getCallClusterMock(data);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(data)
|
||||
);
|
||||
const listItem = await searchListItemByValues({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
type: TYPE,
|
||||
|
@ -57,9 +65,12 @@ describe('search_list_item_by_values', () => {
|
|||
|
||||
test('Returns transformed list item if the data exists within ES', async () => {
|
||||
const data = getSearchListItemMock();
|
||||
const callCluster = getCallClusterMock(data);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(data)
|
||||
);
|
||||
const listItem = await searchListItemByValues({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
type: TYPE,
|
||||
|
|
|
@ -5,14 +5,18 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import { SearchEsListItemSchema, SearchListItemArraySchema, Type } from '../../../common/schemas';
|
||||
import { getQueryFilterFromTypeValue, transformElasticNamedSearchToListItem } from '../utils';
|
||||
import {
|
||||
TransformElasticMSearchToListItemOptions,
|
||||
getQueryFilterFromTypeValue,
|
||||
transformElasticNamedSearchToListItem,
|
||||
} from '../utils';
|
||||
|
||||
export interface SearchListItemByValuesOptions {
|
||||
listId: string;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listItemIndex: string;
|
||||
type: Type;
|
||||
value: unknown[];
|
||||
|
@ -20,12 +24,12 @@ export interface SearchListItemByValuesOptions {
|
|||
|
||||
export const searchListItemByValues = async ({
|
||||
listId,
|
||||
callCluster,
|
||||
esClient,
|
||||
listItemIndex,
|
||||
type,
|
||||
value,
|
||||
}: SearchListItemByValuesOptions): Promise<SearchListItemArraySchema> => {
|
||||
const response = await callCluster<SearchEsListItemSchema>('search', {
|
||||
const { body: response } = await esClient.search<SearchEsListItemSchema>({
|
||||
body: {
|
||||
query: {
|
||||
bool: {
|
||||
|
@ -33,9 +37,13 @@ export const searchListItemByValues = async ({
|
|||
},
|
||||
},
|
||||
},
|
||||
ignoreUnavailable: true,
|
||||
ignore_unavailable: true,
|
||||
index: listItemIndex,
|
||||
size: 10000, // TODO: This has a limit on the number which is 10,000 the default of Elastic but we might want to provide a way to increase that number
|
||||
});
|
||||
return transformElasticNamedSearchToListItem({ response, type, value });
|
||||
return transformElasticNamedSearchToListItem(({
|
||||
response,
|
||||
type,
|
||||
value,
|
||||
} as unknown) as TransformElasticMSearchToListItemOptions);
|
||||
};
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { UpdateListItemOptions } from '../items';
|
||||
import {
|
||||
DATE_NOW,
|
||||
|
@ -18,8 +20,8 @@ import {
|
|||
|
||||
export const getUpdateListItemOptionsMock = (): UpdateListItemOptions => ({
|
||||
_version: undefined,
|
||||
callCluster: getCallClusterMock(),
|
||||
dateNow: DATE_NOW,
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
id: LIST_ITEM_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
meta: META,
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { ListItemSchema } from '../../../common/schemas';
|
||||
import { getListItemResponseMock } from '../../../common/schemas/response/list_item_schema.mock';
|
||||
|
||||
|
@ -29,7 +32,11 @@ describe('update_list_item', () => {
|
|||
const listItem = getListItemResponseMock();
|
||||
((getListItem as unknown) as jest.Mock).mockResolvedValueOnce(listItem);
|
||||
const options = getUpdateListItemOptionsMock();
|
||||
const updatedList = await updateListItem(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.update.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' })
|
||||
);
|
||||
const updatedList = await updateListItem({ ...options, esClient });
|
||||
const expected: ListItemSchema = { ...getListItemResponseMock(), id: 'elastic-id-123' };
|
||||
expect(updatedList).toEqual(expected);
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { CreateDocumentResponse } from 'elasticsearch';
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import {
|
||||
Id,
|
||||
|
@ -25,7 +25,7 @@ export interface UpdateListItemOptions {
|
|||
_version: _VersionOrUndefined;
|
||||
id: Id;
|
||||
value: string | null | undefined;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listItemIndex: string;
|
||||
user: string;
|
||||
meta: MetaOrUndefined;
|
||||
|
@ -36,14 +36,14 @@ export const updateListItem = async ({
|
|||
_version,
|
||||
id,
|
||||
value,
|
||||
callCluster,
|
||||
esClient,
|
||||
listItemIndex,
|
||||
user,
|
||||
meta,
|
||||
dateNow,
|
||||
}: UpdateListItemOptions): Promise<ListItemSchema | null> => {
|
||||
const updatedAt = dateNow ?? new Date().toISOString();
|
||||
const listItem = await getListItem({ callCluster, id, listItemIndex });
|
||||
const listItem = await getListItem({ esClient, id, listItemIndex });
|
||||
if (listItem == null) {
|
||||
return null;
|
||||
} else {
|
||||
|
@ -62,7 +62,7 @@ export const updateListItem = async ({
|
|||
...elasticQuery,
|
||||
};
|
||||
|
||||
const response = await callCluster<CreateDocumentResponse>('update', {
|
||||
const { body: response } = await esClient.update<CreateDocumentResponse>({
|
||||
...decodeVersion(_version),
|
||||
body: {
|
||||
doc,
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { ImportListItemsToStreamOptions, WriteBufferToItemsOptions } from '../items';
|
||||
import {
|
||||
LIST_ID,
|
||||
|
@ -21,9 +23,9 @@ import { getConfigMockDecoded } from '../../config.mock';
|
|||
import { TestReadable } from './test_readable.mock';
|
||||
|
||||
export const getImportListItemsToStreamOptionsMock = (): ImportListItemsToStreamOptions => ({
|
||||
callCluster: getCallClusterMock(),
|
||||
config: getConfigMockDecoded(),
|
||||
deserializer: undefined,
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
listId: LIST_ID,
|
||||
listIndex: LIST_INDEX,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
|
@ -37,8 +39,8 @@ export const getImportListItemsToStreamOptionsMock = (): ImportListItemsToStream
|
|||
|
||||
export const getWriteBufferToItemsOptionsMock = (): WriteBufferToItemsOptions => ({
|
||||
buffer: [],
|
||||
callCluster: getCallClusterMock(),
|
||||
deserializer: undefined,
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
meta: META,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { Readable } from 'stream';
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import { createListIfItDoesNotExist } from '../lists/create_list_if_it_does_not_exist';
|
||||
import {
|
||||
|
@ -31,7 +31,7 @@ export interface ImportListItemsToStreamOptions {
|
|||
deserializer: DeserializerOrUndefined;
|
||||
serializer: SerializerOrUndefined;
|
||||
stream: Readable;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listItemIndex: string;
|
||||
type: Type;
|
||||
user: string;
|
||||
|
@ -45,7 +45,7 @@ export const importListItemsToStream = ({
|
|||
serializer,
|
||||
listId,
|
||||
stream,
|
||||
callCluster,
|
||||
esClient,
|
||||
listItemIndex,
|
||||
listIndex,
|
||||
type,
|
||||
|
@ -62,9 +62,9 @@ export const importListItemsToStream = ({
|
|||
fileName = fileNameEmitted;
|
||||
if (listId == null) {
|
||||
list = await createListIfItDoesNotExist({
|
||||
callCluster,
|
||||
description: `File uploaded from file system of ${fileNameEmitted}`,
|
||||
deserializer,
|
||||
esClient,
|
||||
id: fileNameEmitted,
|
||||
immutable: false,
|
||||
listIndex,
|
||||
|
@ -83,8 +83,8 @@ export const importListItemsToStream = ({
|
|||
if (listId != null) {
|
||||
await writeBufferToItems({
|
||||
buffer: lines,
|
||||
callCluster,
|
||||
deserializer,
|
||||
esClient,
|
||||
listId,
|
||||
listItemIndex,
|
||||
meta,
|
||||
|
@ -95,8 +95,8 @@ export const importListItemsToStream = ({
|
|||
} else if (fileName != null) {
|
||||
await writeBufferToItems({
|
||||
buffer: lines,
|
||||
callCluster,
|
||||
deserializer,
|
||||
esClient,
|
||||
listId: fileName,
|
||||
listItemIndex,
|
||||
meta,
|
||||
|
@ -117,7 +117,7 @@ export interface WriteBufferToItemsOptions {
|
|||
listId: string;
|
||||
deserializer: DeserializerOrUndefined;
|
||||
serializer: SerializerOrUndefined;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listItemIndex: string;
|
||||
buffer: string[];
|
||||
type: Type;
|
||||
|
@ -131,7 +131,7 @@ export interface LinesResult {
|
|||
|
||||
export const writeBufferToItems = async ({
|
||||
listId,
|
||||
callCluster,
|
||||
esClient,
|
||||
deserializer,
|
||||
serializer,
|
||||
listItemIndex,
|
||||
|
@ -141,8 +141,8 @@ export const writeBufferToItems = async ({
|
|||
meta,
|
||||
}: WriteBufferToItemsOptions): Promise<LinesResult> => {
|
||||
await createListItemsBulk({
|
||||
callCluster,
|
||||
deserializer,
|
||||
esClient,
|
||||
listId,
|
||||
listItemIndex,
|
||||
meta,
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { getSearchListItemMock } from '../../../common/schemas/elastic_response/search_es_list_item_schema.mock';
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
import { LIST_ID, LIST_ITEM_INDEX } from '../../../common/constants.mock';
|
||||
|
||||
import {
|
||||
|
@ -38,8 +40,11 @@ describe('write_list_items_to_stream', () => {
|
|||
const options = getExportListItemsToStreamOptionsMock();
|
||||
const firstResponse = getSearchListItemMock();
|
||||
firstResponse.hits.hits = [];
|
||||
options.callCluster = getCallClusterMock(firstResponse);
|
||||
exportListItemsToStream(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(firstResponse)
|
||||
);
|
||||
exportListItemsToStream({ ...options, esClient });
|
||||
|
||||
let chunks: string[] = [];
|
||||
options.stream.on('data', (chunk: Buffer) => {
|
||||
|
@ -54,7 +59,12 @@ describe('write_list_items_to_stream', () => {
|
|||
|
||||
test('It exports single list item to the stream', (done) => {
|
||||
const options = getExportListItemsToStreamOptionsMock();
|
||||
exportListItemsToStream(options);
|
||||
const response = getSearchListItemMock();
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(response)
|
||||
);
|
||||
exportListItemsToStream({ ...options, esClient });
|
||||
|
||||
let chunks: string[] = [];
|
||||
options.stream.on('data', (chunk: Buffer) => {
|
||||
|
@ -72,8 +82,11 @@ describe('write_list_items_to_stream', () => {
|
|||
const firstResponse = getSearchListItemMock();
|
||||
const secondResponse = getSearchListItemMock();
|
||||
firstResponse.hits.hits = [...firstResponse.hits.hits, ...secondResponse.hits.hits];
|
||||
options.callCluster = getCallClusterMock(firstResponse);
|
||||
exportListItemsToStream(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(firstResponse)
|
||||
);
|
||||
exportListItemsToStream({ ...options, esClient });
|
||||
|
||||
let chunks: string[] = [];
|
||||
options.stream.on('data', (chunk: Buffer) => {
|
||||
|
@ -95,12 +108,14 @@ describe('write_list_items_to_stream', () => {
|
|||
const secondResponse = getSearchListItemMock();
|
||||
secondResponse.hits.hits[0]._source.ip = '255.255.255.255';
|
||||
|
||||
options.callCluster = jest
|
||||
.fn()
|
||||
.mockResolvedValueOnce(firstResponse)
|
||||
.mockResolvedValueOnce(secondResponse);
|
||||
|
||||
exportListItemsToStream(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockResolvedValueOnce(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(firstResponse)
|
||||
);
|
||||
esClient.search.mockResolvedValueOnce(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(secondResponse)
|
||||
);
|
||||
exportListItemsToStream({ ...options, esClient });
|
||||
|
||||
let chunks: string[] = [];
|
||||
options.stream.on('data', (chunk: Buffer) => {
|
||||
|
@ -117,7 +132,12 @@ describe('write_list_items_to_stream', () => {
|
|||
describe('writeNextResponse', () => {
|
||||
test('It returns an empty searchAfter response when there is no sort defined', async () => {
|
||||
const options = getWriteNextResponseOptions();
|
||||
const searchAfter = await writeNextResponse(options);
|
||||
const listItem = getSearchListItemMock();
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(listItem)
|
||||
);
|
||||
const searchAfter = await writeNextResponse({ ...options, esClient });
|
||||
expect(searchAfter).toEqual(undefined);
|
||||
});
|
||||
|
||||
|
@ -125,8 +145,11 @@ describe('write_list_items_to_stream', () => {
|
|||
const listItem = getSearchListItemMock();
|
||||
listItem.hits.hits[0].sort = ['sort-value-1'];
|
||||
const options = getWriteNextResponseOptions();
|
||||
options.callCluster = getCallClusterMock(listItem);
|
||||
const searchAfter = await writeNextResponse(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(listItem)
|
||||
);
|
||||
const searchAfter = await writeNextResponse({ ...options, esClient });
|
||||
expect(searchAfter).toEqual(['sort-value-1']);
|
||||
});
|
||||
|
||||
|
@ -134,8 +157,11 @@ describe('write_list_items_to_stream', () => {
|
|||
const listItem = getSearchListItemMock();
|
||||
listItem.hits.hits = [];
|
||||
const options = getWriteNextResponseOptions();
|
||||
options.callCluster = getCallClusterMock(listItem);
|
||||
const searchAfter = await writeNextResponse(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(listItem)
|
||||
);
|
||||
const searchAfter = await writeNextResponse({ ...options, esClient });
|
||||
expect(searchAfter).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
|
@ -183,11 +209,11 @@ describe('write_list_items_to_stream', () => {
|
|||
search_after: ['string 1', 'string 2'],
|
||||
sort: [{ tie_breaker_id: 'asc' }],
|
||||
},
|
||||
ignoreUnavailable: true,
|
||||
ignore_unavailable: true,
|
||||
index: LIST_ITEM_INDEX,
|
||||
size: 100,
|
||||
};
|
||||
expect(options.callCluster).toBeCalledWith('search', expected);
|
||||
expect(options.esClient.search).toBeCalledWith(expected);
|
||||
});
|
||||
|
||||
test('It returns a simple response with expected values and size changed', async () => {
|
||||
|
@ -201,11 +227,11 @@ describe('write_list_items_to_stream', () => {
|
|||
search_after: ['string 1', 'string 2'],
|
||||
sort: [{ tie_breaker_id: 'asc' }],
|
||||
},
|
||||
ignoreUnavailable: true,
|
||||
ignore_unavailable: true,
|
||||
index: LIST_ITEM_INDEX,
|
||||
size: 33,
|
||||
};
|
||||
expect(options.callCluster).toBeCalledWith('search', expected);
|
||||
expect(options.esClient.search).toBeCalledWith(expected);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { PassThrough } from 'stream';
|
||||
|
||||
import { SearchResponse } from 'elasticsearch';
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import { SearchEsListItemSchema } from '../../../common/schemas';
|
||||
import { ErrorWithStatusCode } from '../../error_with_status_code';
|
||||
|
@ -22,7 +22,7 @@ export const SIZE = 100;
|
|||
|
||||
export interface ExportListItemsToStreamOptions {
|
||||
listId: string;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listItemIndex: string;
|
||||
stream: PassThrough;
|
||||
stringToAppend: string | null | undefined;
|
||||
|
@ -30,7 +30,7 @@ export interface ExportListItemsToStreamOptions {
|
|||
|
||||
export const exportListItemsToStream = ({
|
||||
listId,
|
||||
callCluster,
|
||||
esClient,
|
||||
stream,
|
||||
listItemIndex,
|
||||
stringToAppend,
|
||||
|
@ -39,7 +39,7 @@ export const exportListItemsToStream = ({
|
|||
// and prevent the async await from bubbling up to the caller
|
||||
setTimeout(async () => {
|
||||
let searchAfter = await writeNextResponse({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId,
|
||||
listItemIndex,
|
||||
searchAfter: undefined,
|
||||
|
@ -48,7 +48,7 @@ export const exportListItemsToStream = ({
|
|||
});
|
||||
while (searchAfter != null) {
|
||||
searchAfter = await writeNextResponse({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId,
|
||||
listItemIndex,
|
||||
searchAfter,
|
||||
|
@ -62,7 +62,7 @@ export const exportListItemsToStream = ({
|
|||
|
||||
export interface WriteNextResponseOptions {
|
||||
listId: string;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listItemIndex: string;
|
||||
stream: PassThrough;
|
||||
searchAfter: string[] | undefined;
|
||||
|
@ -71,14 +71,14 @@ export interface WriteNextResponseOptions {
|
|||
|
||||
export const writeNextResponse = async ({
|
||||
listId,
|
||||
callCluster,
|
||||
esClient,
|
||||
stream,
|
||||
listItemIndex,
|
||||
searchAfter,
|
||||
stringToAppend,
|
||||
}: WriteNextResponseOptions): Promise<string[] | undefined> => {
|
||||
const response = await getResponse({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId,
|
||||
listItemIndex,
|
||||
searchAfter,
|
||||
|
@ -102,7 +102,7 @@ export const getSearchAfterFromResponse = <T>({
|
|||
: undefined;
|
||||
|
||||
export interface GetResponseOptions {
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listId: string;
|
||||
searchAfter: undefined | string[];
|
||||
listItemIndex: string;
|
||||
|
@ -110,26 +110,28 @@ export interface GetResponseOptions {
|
|||
}
|
||||
|
||||
export const getResponse = async ({
|
||||
callCluster,
|
||||
esClient,
|
||||
searchAfter,
|
||||
listId,
|
||||
listItemIndex,
|
||||
size = SIZE,
|
||||
}: GetResponseOptions): Promise<SearchResponse<SearchEsListItemSchema>> => {
|
||||
return callCluster<SearchEsListItemSchema>('search', {
|
||||
body: {
|
||||
query: {
|
||||
term: {
|
||||
list_id: listId,
|
||||
return ((
|
||||
await esClient.search<SearchEsListItemSchema>({
|
||||
body: {
|
||||
query: {
|
||||
term: {
|
||||
list_id: listId,
|
||||
},
|
||||
},
|
||||
search_after: searchAfter,
|
||||
sort: [{ tie_breaker_id: 'asc' }],
|
||||
},
|
||||
search_after: searchAfter,
|
||||
sort: [{ tie_breaker_id: 'asc' }],
|
||||
},
|
||||
ignoreUnavailable: true,
|
||||
index: listItemIndex,
|
||||
size,
|
||||
});
|
||||
ignore_unavailable: true,
|
||||
index: listItemIndex,
|
||||
size,
|
||||
})
|
||||
).body as unknown) as SearchResponse<SearchEsListItemSchema>;
|
||||
};
|
||||
|
||||
export interface WriteResponseHitsToStreamOptions {
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
|
||||
import { Stream } from 'stream';
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { getSearchListItemMock } from '../../../common/schemas/elastic_response/search_es_list_item_schema.mock';
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
import {
|
||||
ExportListItemsToStreamOptions,
|
||||
GetResponseOptions,
|
||||
|
@ -18,7 +20,7 @@ import {
|
|||
import { LIST_ID, LIST_ITEM_INDEX } from '../../../common/constants.mock';
|
||||
|
||||
export const getExportListItemsToStreamOptionsMock = (): ExportListItemsToStreamOptions => ({
|
||||
callCluster: getCallClusterMock(getSearchListItemMock()),
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
stream: new Stream.PassThrough(),
|
||||
|
@ -26,7 +28,7 @@ export const getExportListItemsToStreamOptionsMock = (): ExportListItemsToStream
|
|||
});
|
||||
|
||||
export const getWriteNextResponseOptions = (): WriteNextResponseOptions => ({
|
||||
callCluster: getCallClusterMock(getSearchListItemMock()),
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
searchAfter: [],
|
||||
|
@ -35,7 +37,7 @@ export const getWriteNextResponseOptions = (): WriteNextResponseOptions => ({
|
|||
});
|
||||
|
||||
export const getResponseOptionsMock = (): GetResponseOptions => ({
|
||||
callCluster: getCallClusterMock(),
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
listId: LIST_ID,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
searchAfter: [],
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { CreateListOptions } from '../lists';
|
||||
import {
|
||||
DATE_NOW,
|
||||
|
@ -22,10 +24,10 @@ import {
|
|||
} from '../../../common/constants.mock';
|
||||
|
||||
export const getCreateListOptionsMock = (): CreateListOptions => ({
|
||||
callCluster: getCallClusterMock(),
|
||||
dateNow: DATE_NOW,
|
||||
description: DESCRIPTION,
|
||||
deserializer: undefined,
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
id: LIST_ID,
|
||||
immutable: IMMUTABLE,
|
||||
listIndex: LIST_INDEX,
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { ListSchema } from '../../../common/schemas';
|
||||
import { getListResponseMock } from '../../../common/schemas/response/list_schema.mock';
|
||||
import { getIndexESListMock } from '../../../common/schemas/elastic_query/index_es_list_schema.mock';
|
||||
|
@ -24,7 +27,11 @@ describe('crete_list', () => {
|
|||
|
||||
test('it returns a list as expected with the id changed out for the elastic id', async () => {
|
||||
const options = getCreateListOptionsMock();
|
||||
const list = await createList(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.index.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' })
|
||||
);
|
||||
const list = await createList({ ...options, esClient });
|
||||
const expected: ListSchema = { ...getListResponseMock(), id: 'elastic-id-123' };
|
||||
expect(list).toEqual(expected);
|
||||
});
|
||||
|
@ -35,7 +42,11 @@ describe('crete_list', () => {
|
|||
deserializer: '{{value}}',
|
||||
serializer: '(?<value>)',
|
||||
};
|
||||
const list = await createList(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.index.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' })
|
||||
);
|
||||
const list = await createList({ ...options, esClient });
|
||||
const expected: ListSchema = {
|
||||
...getListResponseMock(),
|
||||
deserializer: '{{value}}',
|
||||
|
@ -45,7 +56,7 @@ describe('crete_list', () => {
|
|||
expect(list).toEqual(expected);
|
||||
});
|
||||
|
||||
test('It calls "callCluster" with body, index, and listIndex', async () => {
|
||||
test('It calls "esClient" with body, index, and listIndex', async () => {
|
||||
const options = getCreateListOptionsMock();
|
||||
await createList(options);
|
||||
const body = getIndexESListMock();
|
||||
|
@ -55,13 +66,17 @@ describe('crete_list', () => {
|
|||
index: LIST_INDEX,
|
||||
refresh: 'wait_for',
|
||||
};
|
||||
expect(options.callCluster).toBeCalledWith('index', expected);
|
||||
expect(options.esClient.index).toBeCalledWith(expected);
|
||||
});
|
||||
|
||||
test('It returns an auto-generated id if id is sent in undefined', async () => {
|
||||
const options = getCreateListOptionsMock();
|
||||
options.id = undefined;
|
||||
const list = await createList(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.index.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' })
|
||||
);
|
||||
const list = await createList({ ...options, esClient });
|
||||
const expected: ListSchema = { ...getListResponseMock(), id: 'elastic-id-123' };
|
||||
expect(list).toEqual(expected);
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import uuid from 'uuid';
|
||||
import { CreateDocumentResponse } from 'elasticsearch';
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import { encodeHitVersion } from '../utils/encode_hit_version';
|
||||
import {
|
||||
|
@ -31,7 +31,7 @@ export interface CreateListOptions {
|
|||
type: Type;
|
||||
name: Name;
|
||||
description: Description;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listIndex: string;
|
||||
user: string;
|
||||
meta: MetaOrUndefined;
|
||||
|
@ -48,7 +48,7 @@ export const createList = async ({
|
|||
name,
|
||||
type,
|
||||
description,
|
||||
callCluster,
|
||||
esClient,
|
||||
listIndex,
|
||||
user,
|
||||
meta,
|
||||
|
@ -73,7 +73,7 @@ export const createList = async ({
|
|||
updated_by: user,
|
||||
version,
|
||||
};
|
||||
const response = await callCluster<CreateDocumentResponse>('index', {
|
||||
const { body: response } = await esClient.index<CreateDocumentResponse>({
|
||||
body,
|
||||
id,
|
||||
index: listIndex,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import {
|
||||
Description,
|
||||
|
@ -31,7 +31,7 @@ export interface CreateListIfItDoesNotExistOptions {
|
|||
serializer: SerializerOrUndefined;
|
||||
description: Description;
|
||||
immutable: Immutable;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listIndex: string;
|
||||
user: string;
|
||||
meta: MetaOrUndefined;
|
||||
|
@ -46,7 +46,7 @@ export const createListIfItDoesNotExist = async ({
|
|||
type,
|
||||
description,
|
||||
deserializer,
|
||||
callCluster,
|
||||
esClient,
|
||||
listIndex,
|
||||
user,
|
||||
meta,
|
||||
|
@ -56,13 +56,13 @@ export const createListIfItDoesNotExist = async ({
|
|||
version,
|
||||
immutable,
|
||||
}: CreateListIfItDoesNotExistOptions): Promise<ListSchema> => {
|
||||
const list = await getList({ callCluster, id, listIndex });
|
||||
const list = await getList({ esClient, id, listIndex });
|
||||
if (list == null) {
|
||||
return createList({
|
||||
callCluster,
|
||||
dateNow,
|
||||
description,
|
||||
deserializer,
|
||||
esClient,
|
||||
id,
|
||||
immutable,
|
||||
listIndex,
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { DeleteListOptions } from '../lists';
|
||||
import { LIST_ID, LIST_INDEX, LIST_ITEM_INDEX } from '../../../common/constants.mock';
|
||||
|
||||
export const getDeleteListOptionsMock = (): DeleteListOptions => ({
|
||||
callCluster: getCallClusterMock(),
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
id: LIST_ID,
|
||||
listIndex: LIST_INDEX,
|
||||
listItemIndex: LIST_ITEM_INDEX,
|
||||
|
|
|
@ -48,9 +48,9 @@ describe('delete_list', () => {
|
|||
const deleteByQuery = {
|
||||
body: { query: { term: { list_id: LIST_ID } } },
|
||||
index: LIST_ITEM_INDEX,
|
||||
refresh: 'wait_for',
|
||||
refresh: false,
|
||||
};
|
||||
expect(options.callCluster).toBeCalledWith('deleteByQuery', deleteByQuery);
|
||||
expect(options.esClient.deleteByQuery).toBeCalledWith(deleteByQuery);
|
||||
});
|
||||
|
||||
test('Delete calls "delete" second if a list is returned from getList', async () => {
|
||||
|
@ -61,15 +61,15 @@ describe('delete_list', () => {
|
|||
const deleteQuery = {
|
||||
id: LIST_ID,
|
||||
index: LIST_INDEX,
|
||||
refresh: 'wait_for',
|
||||
refresh: false,
|
||||
};
|
||||
expect(options.callCluster).toHaveBeenNthCalledWith(2, 'delete', deleteQuery);
|
||||
expect(options.esClient.delete).toHaveBeenNthCalledWith(1, deleteQuery);
|
||||
});
|
||||
|
||||
test('Delete does not call data client if the list returns null', async () => {
|
||||
((getList as unknown) as jest.Mock).mockResolvedValueOnce(null);
|
||||
const options = getDeleteListOptionsMock();
|
||||
await deleteList(options);
|
||||
expect(options.callCluster).not.toHaveBeenCalled();
|
||||
expect(options.esClient.delete).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import { Id, ListSchema } from '../../../common/schemas';
|
||||
|
||||
|
@ -13,22 +13,22 @@ import { getList } from './get_list';
|
|||
|
||||
export interface DeleteListOptions {
|
||||
id: Id;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listIndex: string;
|
||||
listItemIndex: string;
|
||||
}
|
||||
|
||||
export const deleteList = async ({
|
||||
id,
|
||||
callCluster,
|
||||
esClient,
|
||||
listIndex,
|
||||
listItemIndex,
|
||||
}: DeleteListOptions): Promise<ListSchema | null> => {
|
||||
const list = await getList({ callCluster, id, listIndex });
|
||||
const list = await getList({ esClient, id, listIndex });
|
||||
if (list == null) {
|
||||
return null;
|
||||
} else {
|
||||
await callCluster('deleteByQuery', {
|
||||
await esClient.deleteByQuery({
|
||||
body: {
|
||||
query: {
|
||||
term: {
|
||||
|
@ -37,13 +37,13 @@ export const deleteList = async ({
|
|||
},
|
||||
},
|
||||
index: listItemIndex,
|
||||
refresh: 'wait_for',
|
||||
refresh: false,
|
||||
});
|
||||
|
||||
await callCluster('delete', {
|
||||
await esClient.delete({
|
||||
id,
|
||||
index: listIndex,
|
||||
refresh: 'wait_for',
|
||||
refresh: false,
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { SearchResponse } from 'elasticsearch';
|
||||
|
||||
import {
|
||||
|
@ -34,12 +34,12 @@ interface FindListOptions {
|
|||
page: Page;
|
||||
sortField: SortFieldOrUndefined;
|
||||
sortOrder: SortOrderOrUndefined;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listIndex: string;
|
||||
}
|
||||
|
||||
export const findList = async ({
|
||||
callCluster,
|
||||
esClient,
|
||||
currentIndexPosition,
|
||||
filter,
|
||||
page,
|
||||
|
@ -52,8 +52,8 @@ export const findList = async ({
|
|||
const query = getQueryFilter({ filter });
|
||||
|
||||
const scroll = await scrollToStartPage({
|
||||
callCluster,
|
||||
currentIndexPosition,
|
||||
esClient,
|
||||
filter,
|
||||
hopSize: 100,
|
||||
index: listIndex,
|
||||
|
@ -64,25 +64,25 @@ export const findList = async ({
|
|||
sortOrder,
|
||||
});
|
||||
|
||||
const { count } = await callCluster('count', {
|
||||
const { body: totalCount } = await esClient.count({
|
||||
body: {
|
||||
query,
|
||||
},
|
||||
ignoreUnavailable: true,
|
||||
ignore_unavailable: true,
|
||||
index: listIndex,
|
||||
});
|
||||
|
||||
if (scroll.validSearchAfterFound) {
|
||||
// Note: This typing of response = await callCluster<SearchResponse<SearchEsListSchema>>
|
||||
// Note: This typing of response = await esClient<SearchResponse<SearchEsListSchema>>
|
||||
// is because when you pass in seq_no_primary_term: true it does a "fall through" type and you have
|
||||
// to explicitly define the type <T>.
|
||||
const response = await callCluster<SearchResponse<SearchEsListSchema>>('search', {
|
||||
const { body: response } = await esClient.search<SearchResponse<SearchEsListSchema>>({
|
||||
body: {
|
||||
query,
|
||||
search_after: scroll.searchAfter,
|
||||
sort: getSortWithTieBreaker({ sortField, sortOrder }),
|
||||
},
|
||||
ignoreUnavailable: true,
|
||||
ignore_unavailable: true,
|
||||
index: listIndex,
|
||||
seq_no_primary_term: true,
|
||||
size: perPage,
|
||||
|
@ -96,7 +96,7 @@ export const findList = async ({
|
|||
data: transformElasticToList({ response }),
|
||||
page,
|
||||
per_page: perPage,
|
||||
total: count,
|
||||
total: totalCount.count,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
|
@ -104,7 +104,7 @@ export const findList = async ({
|
|||
data: [],
|
||||
page,
|
||||
per_page: perPage,
|
||||
total: count,
|
||||
total: totalCount.count,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { getSearchListMock } from '../../../common/schemas/elastic_response/search_es_list_schema.mock';
|
||||
import { getListResponseMock } from '../../../common/schemas/response/list_schema.mock';
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
import { LIST_ID, LIST_INDEX } from '../../../common/constants.mock';
|
||||
|
||||
import { getList } from './get_list';
|
||||
|
@ -23,8 +25,11 @@ describe('get_list', () => {
|
|||
|
||||
test('it returns a list as expected if the list is found', async () => {
|
||||
const data = getSearchListMock();
|
||||
const callCluster = getCallClusterMock(data);
|
||||
const list = await getList({ callCluster, id: LIST_ID, listIndex: LIST_INDEX });
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(data)
|
||||
);
|
||||
const list = await getList({ esClient, id: LIST_ID, listIndex: LIST_INDEX });
|
||||
const expected = getListResponseMock();
|
||||
expect(list).toEqual(expected);
|
||||
});
|
||||
|
@ -32,8 +37,11 @@ describe('get_list', () => {
|
|||
test('it returns null if the search is empty', async () => {
|
||||
const data = getSearchListMock();
|
||||
data.hits.hits = [];
|
||||
const callCluster = getCallClusterMock(data);
|
||||
const list = await getList({ callCluster, id: LIST_ID, listIndex: LIST_INDEX });
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.search.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise(data)
|
||||
);
|
||||
const list = await getList({ esClient, id: LIST_ID, listIndex: LIST_INDEX });
|
||||
expect(list).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { SearchResponse } from 'elasticsearch';
|
||||
|
||||
import { Id, ListSchema, SearchEsListSchema } from '../../../common/schemas';
|
||||
|
@ -13,19 +13,19 @@ import { transformElasticToList } from '../utils/transform_elastic_to_list';
|
|||
|
||||
interface GetListOptions {
|
||||
id: Id;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listIndex: string;
|
||||
}
|
||||
|
||||
export const getList = async ({
|
||||
id,
|
||||
callCluster,
|
||||
esClient,
|
||||
listIndex,
|
||||
}: GetListOptions): Promise<ListSchema | null> => {
|
||||
// Note: This typing of response = await callCluster<SearchResponse<SearchEsListSchema>>
|
||||
// Note: This typing of response = await esClient<SearchResponse<SearchEsListSchema>>
|
||||
// is because when you pass in seq_no_primary_term: true it does a "fall through" type and you have
|
||||
// to explicitly define the type <T>.
|
||||
const response = await callCluster<SearchResponse<SearchEsListSchema>>('search', {
|
||||
const { body: response } = await esClient.search<SearchResponse<SearchEsListSchema>>({
|
||||
body: {
|
||||
query: {
|
||||
term: {
|
||||
|
@ -33,7 +33,7 @@ export const getList = async ({
|
|||
},
|
||||
},
|
||||
},
|
||||
ignoreUnavailable: true,
|
||||
ignore_unavailable: true,
|
||||
index: listIndex,
|
||||
seq_no_primary_term: true,
|
||||
});
|
||||
|
|
|
@ -5,11 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { getFoundListItemSchemaMock } from '../../../common/schemas/response/found_list_item_schema.mock';
|
||||
import { getFoundListSchemaMock } from '../../../common/schemas/response/found_list_schema.mock';
|
||||
import { getListItemResponseMock } from '../../../common/schemas/response/list_item_schema.mock';
|
||||
import { getListResponseMock } from '../../../common/schemas/response/list_schema.mock';
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
import {
|
||||
IMPORT_BUFFER_SIZE,
|
||||
IMPORT_TIMEOUT,
|
||||
|
@ -63,7 +65,6 @@ export class ListClientMock extends ListClient {
|
|||
|
||||
export const getListClientMock = (): ListClient => {
|
||||
const mock = new ListClientMock({
|
||||
callCluster: getCallClusterMock(),
|
||||
config: {
|
||||
enabled: true,
|
||||
importBufferSize: IMPORT_BUFFER_SIZE,
|
||||
|
@ -72,6 +73,7 @@ export const getListClientMock = (): ListClient => {
|
|||
listItemIndex: LIST_ITEM_INDEX,
|
||||
maxImportPayloadBytes: MAX_IMPORT_PAYLOAD_BYTES,
|
||||
},
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
spaceId: 'default',
|
||||
user: 'elastic',
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import {
|
||||
FoundListItemSchema,
|
||||
|
@ -80,13 +80,13 @@ export class ListClient {
|
|||
private readonly spaceId: string;
|
||||
private readonly user: string;
|
||||
private readonly config: ConfigType;
|
||||
private readonly callCluster: LegacyAPICaller;
|
||||
private readonly esClient: ElasticsearchClient;
|
||||
|
||||
constructor({ spaceId, user, config, callCluster }: ConstructorOptions) {
|
||||
constructor({ spaceId, user, config, esClient }: ConstructorOptions) {
|
||||
this.spaceId = spaceId;
|
||||
this.user = user;
|
||||
this.config = config;
|
||||
this.callCluster = callCluster;
|
||||
this.esClient = esClient;
|
||||
}
|
||||
|
||||
public getListIndex = (): string => {
|
||||
|
@ -106,9 +106,9 @@ export class ListClient {
|
|||
};
|
||||
|
||||
public getList = async ({ id }: GetListOptions): Promise<ListSchema | null> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
return getList({ callCluster, id, listIndex });
|
||||
return getList({ esClient, id, listIndex });
|
||||
};
|
||||
|
||||
public createList = async ({
|
||||
|
@ -122,12 +122,12 @@ export class ListClient {
|
|||
meta,
|
||||
version,
|
||||
}: CreateListOptions): Promise<ListSchema> => {
|
||||
const { callCluster, user } = this;
|
||||
const { esClient, user } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
return createList({
|
||||
callCluster,
|
||||
description,
|
||||
deserializer,
|
||||
esClient,
|
||||
id,
|
||||
immutable,
|
||||
listIndex,
|
||||
|
@ -151,12 +151,12 @@ export class ListClient {
|
|||
meta,
|
||||
version,
|
||||
}: CreateListIfItDoesNotExistOptions): Promise<ListSchema> => {
|
||||
const { callCluster, user } = this;
|
||||
const { esClient, user } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
return createListIfItDoesNotExist({
|
||||
callCluster,
|
||||
description,
|
||||
deserializer,
|
||||
esClient,
|
||||
id,
|
||||
immutable,
|
||||
listIndex,
|
||||
|
@ -170,51 +170,51 @@ export class ListClient {
|
|||
};
|
||||
|
||||
public getListIndexExists = async (): Promise<boolean> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
return getIndexExists(callCluster, listIndex);
|
||||
return getIndexExists(esClient, listIndex);
|
||||
};
|
||||
|
||||
public getListItemIndexExists = async (): Promise<boolean> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return getIndexExists(callCluster, listItemIndex);
|
||||
return getIndexExists(esClient, listItemIndex);
|
||||
};
|
||||
|
||||
public createListBootStrapIndex = async (): Promise<unknown> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
return createBootstrapIndex(callCluster, listIndex);
|
||||
return createBootstrapIndex(esClient, listIndex);
|
||||
};
|
||||
|
||||
public createListItemBootStrapIndex = async (): Promise<unknown> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return createBootstrapIndex(callCluster, listItemIndex);
|
||||
return createBootstrapIndex(esClient, listItemIndex);
|
||||
};
|
||||
|
||||
public getListPolicyExists = async (): Promise<boolean> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
return getPolicyExists(callCluster, listIndex);
|
||||
return getPolicyExists(esClient, listIndex);
|
||||
};
|
||||
|
||||
public getListItemPolicyExists = async (): Promise<boolean> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listsItemIndex = this.getListItemIndex();
|
||||
return getPolicyExists(callCluster, listsItemIndex);
|
||||
return getPolicyExists(esClient, listsItemIndex);
|
||||
};
|
||||
|
||||
public getListTemplateExists = async (): Promise<boolean> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
return getTemplateExists(callCluster, listIndex);
|
||||
return getTemplateExists(esClient, listIndex);
|
||||
};
|
||||
|
||||
public getListItemTemplateExists = async (): Promise<boolean> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return getTemplateExists(callCluster, listItemIndex);
|
||||
return getTemplateExists(esClient, listItemIndex);
|
||||
};
|
||||
|
||||
public getListTemplate = (): Record<string, unknown> => {
|
||||
|
@ -228,71 +228,71 @@ export class ListClient {
|
|||
};
|
||||
|
||||
public setListTemplate = async (): Promise<unknown> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const template = this.getListTemplate();
|
||||
const listIndex = this.getListIndex();
|
||||
return setTemplate(callCluster, listIndex, template);
|
||||
return setTemplate(esClient, listIndex, template);
|
||||
};
|
||||
|
||||
public setListItemTemplate = async (): Promise<unknown> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const template = this.getListItemTemplate();
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return setTemplate(callCluster, listItemIndex, template);
|
||||
return setTemplate(esClient, listItemIndex, template);
|
||||
};
|
||||
|
||||
public setListPolicy = async (): Promise<unknown> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
return setPolicy(callCluster, listIndex, listPolicy);
|
||||
return setPolicy(esClient, listIndex, listPolicy);
|
||||
};
|
||||
|
||||
public setListItemPolicy = async (): Promise<unknown> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return setPolicy(callCluster, listItemIndex, listsItemsPolicy);
|
||||
return setPolicy(esClient, listItemIndex, listsItemsPolicy);
|
||||
};
|
||||
|
||||
public deleteListIndex = async (): Promise<boolean> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
return deleteAllIndex(callCluster, `${listIndex}-*`);
|
||||
return deleteAllIndex(esClient, `${listIndex}-*`);
|
||||
};
|
||||
|
||||
public deleteListItemIndex = async (): Promise<boolean> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return deleteAllIndex(callCluster, `${listItemIndex}-*`);
|
||||
return deleteAllIndex(esClient, `${listItemIndex}-*`);
|
||||
};
|
||||
|
||||
public deleteListPolicy = async (): Promise<unknown> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
return deletePolicy(callCluster, listIndex);
|
||||
return deletePolicy(esClient, listIndex);
|
||||
};
|
||||
|
||||
public deleteListItemPolicy = async (): Promise<unknown> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return deletePolicy(callCluster, listItemIndex);
|
||||
return deletePolicy(esClient, listItemIndex);
|
||||
};
|
||||
|
||||
public deleteListTemplate = async (): Promise<unknown> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
return deleteTemplate(callCluster, listIndex);
|
||||
return deleteTemplate(esClient, listIndex);
|
||||
};
|
||||
|
||||
public deleteListItemTemplate = async (): Promise<unknown> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return deleteTemplate(callCluster, listItemIndex);
|
||||
return deleteTemplate(esClient, listItemIndex);
|
||||
};
|
||||
|
||||
public deleteListItem = async ({ id }: DeleteListItemOptions): Promise<ListItemSchema | null> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return deleteListItem({ callCluster, id, listItemIndex });
|
||||
return deleteListItem({ esClient, id, listItemIndex });
|
||||
};
|
||||
|
||||
public deleteListItemByValue = async ({
|
||||
|
@ -300,10 +300,10 @@ export class ListClient {
|
|||
value,
|
||||
type,
|
||||
}: DeleteListItemByValueOptions): Promise<ListItemArraySchema> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return deleteListItemByValue({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId,
|
||||
listItemIndex,
|
||||
type,
|
||||
|
@ -312,11 +312,11 @@ export class ListClient {
|
|||
};
|
||||
|
||||
public deleteList = async ({ id }: DeleteListOptions): Promise<ListSchema | null> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return deleteList({
|
||||
callCluster,
|
||||
esClient,
|
||||
id,
|
||||
listIndex,
|
||||
listItemIndex,
|
||||
|
@ -328,10 +328,10 @@ export class ListClient {
|
|||
listId,
|
||||
stream,
|
||||
}: ExportListItemsToStreamOptions): void => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
exportListItemsToStream({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId,
|
||||
listItemIndex,
|
||||
stream,
|
||||
|
@ -348,13 +348,13 @@ export class ListClient {
|
|||
meta,
|
||||
version,
|
||||
}: ImportListItemsToStreamOptions): Promise<ListSchema | null> => {
|
||||
const { callCluster, user, config } = this;
|
||||
const { esClient, user, config } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
const listIndex = this.getListIndex();
|
||||
return importListItemsToStream({
|
||||
callCluster,
|
||||
config,
|
||||
deserializer,
|
||||
esClient,
|
||||
listId,
|
||||
listIndex,
|
||||
listItemIndex,
|
||||
|
@ -372,10 +372,10 @@ export class ListClient {
|
|||
value,
|
||||
type,
|
||||
}: GetListItemByValueOptions): Promise<ListItemArraySchema> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return getListItemByValue({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId,
|
||||
listItemIndex,
|
||||
type,
|
||||
|
@ -392,11 +392,11 @@ export class ListClient {
|
|||
type,
|
||||
meta,
|
||||
}: CreateListItemOptions): Promise<ListItemSchema | null> => {
|
||||
const { callCluster, user } = this;
|
||||
const { esClient, user } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return createListItem({
|
||||
callCluster,
|
||||
deserializer,
|
||||
esClient,
|
||||
id,
|
||||
listId,
|
||||
listItemIndex,
|
||||
|
@ -414,11 +414,11 @@ export class ListClient {
|
|||
value,
|
||||
meta,
|
||||
}: UpdateListItemOptions): Promise<ListItemSchema | null> => {
|
||||
const { callCluster, user } = this;
|
||||
const { esClient, user } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return updateListItem({
|
||||
_version,
|
||||
callCluster,
|
||||
esClient,
|
||||
id,
|
||||
listItemIndex,
|
||||
meta,
|
||||
|
@ -435,12 +435,12 @@ export class ListClient {
|
|||
meta,
|
||||
version,
|
||||
}: UpdateListOptions): Promise<ListSchema | null> => {
|
||||
const { callCluster, user } = this;
|
||||
const { esClient, user } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
return updateList({
|
||||
_version,
|
||||
callCluster,
|
||||
description,
|
||||
esClient,
|
||||
id,
|
||||
listIndex,
|
||||
meta,
|
||||
|
@ -451,10 +451,10 @@ export class ListClient {
|
|||
};
|
||||
|
||||
public getListItem = async ({ id }: GetListItemOptions): Promise<ListItemSchema | null> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return getListItem({
|
||||
callCluster,
|
||||
esClient,
|
||||
id,
|
||||
listItemIndex,
|
||||
});
|
||||
|
@ -465,10 +465,10 @@ export class ListClient {
|
|||
listId,
|
||||
value,
|
||||
}: GetListItemsByValueOptions): Promise<ListItemArraySchema> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return getListItemByValues({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId,
|
||||
listItemIndex,
|
||||
type,
|
||||
|
@ -481,10 +481,10 @@ export class ListClient {
|
|||
listId,
|
||||
value,
|
||||
}: SearchListItemByValuesOptions): Promise<SearchListItemArraySchema> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return searchListItemByValues({
|
||||
callCluster,
|
||||
esClient,
|
||||
listId,
|
||||
listItemIndex,
|
||||
type,
|
||||
|
@ -501,11 +501,11 @@ export class ListClient {
|
|||
sortOrder,
|
||||
searchAfter,
|
||||
}: FindListOptions): Promise<FoundListSchema> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
return findList({
|
||||
callCluster,
|
||||
currentIndexPosition,
|
||||
esClient,
|
||||
filter,
|
||||
listIndex,
|
||||
page,
|
||||
|
@ -526,12 +526,12 @@ export class ListClient {
|
|||
sortOrder,
|
||||
searchAfter,
|
||||
}: FindListItemOptions): Promise<FoundListItemSchema | null> => {
|
||||
const { callCluster } = this;
|
||||
const { esClient } = this;
|
||||
const listIndex = this.getListIndex();
|
||||
const listItemIndex = this.getListItemIndex();
|
||||
return findListItem({
|
||||
callCluster,
|
||||
currentIndexPosition,
|
||||
esClient,
|
||||
filter,
|
||||
listId,
|
||||
listIndex,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { PassThrough, Readable } from 'stream';
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import {
|
||||
Description,
|
||||
|
@ -35,7 +35,7 @@ import {
|
|||
import { ConfigType } from '../../config';
|
||||
|
||||
export interface ConstructorOptions {
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
config: ConfigType;
|
||||
spaceId: string;
|
||||
user: string;
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getCallClusterMock } from '../../../common/get_call_cluster.mock';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { UpdateListOptions } from '../lists';
|
||||
import {
|
||||
DATE_NOW,
|
||||
|
@ -20,9 +22,9 @@ import {
|
|||
|
||||
export const getUpdateListOptionsMock = (): UpdateListOptions => ({
|
||||
_version: undefined,
|
||||
callCluster: getCallClusterMock(),
|
||||
dateNow: DATE_NOW,
|
||||
description: DESCRIPTION,
|
||||
esClient: elasticsearchClientMock.createScopedClusterClient().asCurrentUser,
|
||||
id: LIST_ID,
|
||||
listIndex: LIST_INDEX,
|
||||
meta: META,
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
|
||||
|
||||
import { ListSchema } from '../../../common/schemas';
|
||||
import { getListResponseMock } from '../../../common/schemas/response/list_schema.mock';
|
||||
|
||||
|
@ -29,7 +32,11 @@ describe('update_list', () => {
|
|||
const list = getListResponseMock();
|
||||
((getList as unknown) as jest.Mock).mockResolvedValueOnce(list);
|
||||
const options = getUpdateListOptionsMock();
|
||||
const updatedList = await updateList(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.update.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' })
|
||||
);
|
||||
const updatedList = await updateList({ ...options, esClient });
|
||||
const expected: ListSchema = { ...getListResponseMock(), id: 'elastic-id-123' };
|
||||
expect(updatedList).toEqual(expected);
|
||||
});
|
||||
|
@ -42,7 +49,11 @@ describe('update_list', () => {
|
|||
};
|
||||
((getList as unknown) as jest.Mock).mockResolvedValueOnce(list);
|
||||
const options = getUpdateListOptionsMock();
|
||||
const updatedList = await updateList(options);
|
||||
const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser;
|
||||
esClient.update.mockReturnValue(
|
||||
elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' })
|
||||
);
|
||||
const updatedList = await updateList({ ...options, esClient });
|
||||
const expected: ListSchema = {
|
||||
...getListResponseMock(),
|
||||
deserializer: '{{value}}',
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { CreateDocumentResponse } from 'elasticsearch';
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import { decodeVersion } from '../utils/decode_version';
|
||||
import { encodeHitVersion } from '../utils/encode_hit_version';
|
||||
|
@ -26,7 +26,7 @@ import { getList } from '.';
|
|||
export interface UpdateListOptions {
|
||||
_version: _VersionOrUndefined;
|
||||
id: Id;
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
listIndex: string;
|
||||
user: string;
|
||||
name: NameOrUndefined;
|
||||
|
@ -41,7 +41,7 @@ export const updateList = async ({
|
|||
id,
|
||||
name,
|
||||
description,
|
||||
callCluster,
|
||||
esClient,
|
||||
listIndex,
|
||||
user,
|
||||
meta,
|
||||
|
@ -49,7 +49,7 @@ export const updateList = async ({
|
|||
version,
|
||||
}: UpdateListOptions): Promise<ListSchema | null> => {
|
||||
const updatedAt = dateNow ?? new Date().toISOString();
|
||||
const list = await getList({ callCluster, id, listIndex });
|
||||
const list = await getList({ esClient, id, listIndex });
|
||||
if (list == null) {
|
||||
return null;
|
||||
} else {
|
||||
|
@ -61,7 +61,7 @@ export const updateList = async ({
|
|||
updated_at: updatedAt,
|
||||
updated_by: user,
|
||||
};
|
||||
const response = await callCluster<CreateDocumentResponse>('update', {
|
||||
const { body: response } = await esClient.update<CreateDocumentResponse>({
|
||||
...decodeVersion(_version),
|
||||
body: { doc },
|
||||
id,
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { SearchResponse } from 'elasticsearch';
|
||||
|
||||
import { Filter, SortFieldOrUndefined, SortOrderOrUndefined } from '../../../common/schemas';
|
||||
import { Scroll } from '../lists/types';
|
||||
|
@ -16,7 +17,7 @@ import { getSourceWithTieBreaker } from './get_source_with_tie_breaker';
|
|||
import { TieBreaker, getSearchAfterWithTieBreaker } from './get_search_after_with_tie_breaker';
|
||||
|
||||
interface GetSearchAfterOptions {
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
filter: Filter;
|
||||
hops: number;
|
||||
hopSize: number;
|
||||
|
@ -27,7 +28,7 @@ interface GetSearchAfterOptions {
|
|||
}
|
||||
|
||||
export const getSearchAfterScroll = async <T>({
|
||||
callCluster,
|
||||
esClient,
|
||||
filter,
|
||||
hopSize,
|
||||
hops,
|
||||
|
@ -39,14 +40,14 @@ export const getSearchAfterScroll = async <T>({
|
|||
const query = getQueryFilter({ filter });
|
||||
let newSearchAfter = searchAfter;
|
||||
for (let i = 0; i < hops; ++i) {
|
||||
const response = await callCluster<TieBreaker<T>>('search', {
|
||||
const { body: response } = await esClient.search<SearchResponse<TieBreaker<T>>>({
|
||||
body: {
|
||||
_source: getSourceWithTieBreaker({ sortField }),
|
||||
query,
|
||||
search_after: newSearchAfter,
|
||||
sort: getSortWithTieBreaker({ sortField, sortOrder }),
|
||||
},
|
||||
ignoreUnavailable: true,
|
||||
ignore_unavailable: true,
|
||||
index,
|
||||
size: hopSize,
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LegacyAPICaller } from 'kibana/server';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
|
||||
import { Filter, SortFieldOrUndefined, SortOrderOrUndefined } from '../../../common/schemas';
|
||||
import { Scroll } from '../lists/types';
|
||||
|
@ -14,7 +14,7 @@ import { calculateScrollMath } from './calculate_scroll_math';
|
|||
import { getSearchAfterScroll } from './get_search_after_scroll';
|
||||
|
||||
interface ScrollToStartPageOptions {
|
||||
callCluster: LegacyAPICaller;
|
||||
esClient: ElasticsearchClient;
|
||||
filter: Filter;
|
||||
sortField: SortFieldOrUndefined;
|
||||
sortOrder: SortOrderOrUndefined;
|
||||
|
@ -27,7 +27,7 @@ interface ScrollToStartPageOptions {
|
|||
}
|
||||
|
||||
export const scrollToStartPage = async ({
|
||||
callCluster,
|
||||
esClient,
|
||||
filter,
|
||||
hopSize,
|
||||
currentIndexPosition,
|
||||
|
@ -58,7 +58,7 @@ export const scrollToStartPage = async ({
|
|||
};
|
||||
} else if (hops > 0) {
|
||||
const scroll = await getSearchAfterScroll({
|
||||
callCluster,
|
||||
esClient,
|
||||
filter,
|
||||
hopSize,
|
||||
hops,
|
||||
|
@ -69,7 +69,7 @@ export const scrollToStartPage = async ({
|
|||
});
|
||||
if (scroll.validSearchAfterFound && leftOverAfterHops > 0) {
|
||||
return getSearchAfterScroll({
|
||||
callCluster,
|
||||
esClient,
|
||||
filter,
|
||||
hopSize: leftOverAfterHops,
|
||||
hops: 1,
|
||||
|
@ -83,7 +83,7 @@ export const scrollToStartPage = async ({
|
|||
}
|
||||
} else {
|
||||
return getSearchAfterScroll({
|
||||
callCluster,
|
||||
esClient,
|
||||
filter,
|
||||
hopSize: leftOverAfterHops,
|
||||
hops: 1,
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
ElasticsearchClient,
|
||||
IContextProvider,
|
||||
IRouter,
|
||||
LegacyAPICaller,
|
||||
RequestHandlerContext,
|
||||
SavedObjectsClientContract,
|
||||
} from 'kibana/server';
|
||||
|
@ -27,7 +27,7 @@ export interface PluginsStart {
|
|||
}
|
||||
|
||||
export type GetListClientType = (
|
||||
dataClient: LegacyAPICaller,
|
||||
esClient: ElasticsearchClient,
|
||||
spaceId: string,
|
||||
user: string
|
||||
) => ListClient;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Logger, LegacyCallAPIOptions } from 'kibana/server';
|
||||
import { Logger, ElasticsearchClient } from 'kibana/server';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
AlertType,
|
||||
|
@ -32,7 +32,6 @@ import { fetchClusters } from '../lib/alerts/fetch_clusters';
|
|||
import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern';
|
||||
import { INDEX_PATTERN_ELASTICSEARCH } from '../../common/constants';
|
||||
import { AlertSeverity } from '../../common/enums';
|
||||
import { mbSafeQuery } from '../lib/mb_safe_query';
|
||||
import { appendMetricbeatIndex } from '../lib/alerts/append_mb_index';
|
||||
import { parseDuration } from '../../../alerting/common/parse_duration';
|
||||
import { Globals } from '../static_globals';
|
||||
|
@ -56,12 +55,6 @@ interface AlertOptions {
|
|||
accessorKey?: string;
|
||||
}
|
||||
|
||||
type CallCluster = (
|
||||
endpoint: string,
|
||||
clientParams?: Record<string, unknown> | undefined,
|
||||
options?: LegacyCallAPIOptions | undefined
|
||||
) => Promise<any>;
|
||||
|
||||
const defaultAlertOptions = (): AlertOptions => {
|
||||
return {
|
||||
id: '',
|
||||
|
@ -233,29 +226,15 @@ export class BaseAlert {
|
|||
`Executing alert with params: ${JSON.stringify(params)} and state: ${JSON.stringify(state)}`
|
||||
);
|
||||
|
||||
const useCallCluster =
|
||||
Globals.app.monitoringCluster?.callAsInternalUser || services.callCluster;
|
||||
const callCluster = async (
|
||||
endpoint: string,
|
||||
clientParams?: Record<string, unknown>,
|
||||
options?: LegacyCallAPIOptions
|
||||
) => {
|
||||
return await mbSafeQuery(async () => useCallCluster(endpoint, clientParams, options));
|
||||
};
|
||||
const availableCcs = Globals.app.config.ui.ccs.enabled
|
||||
? await fetchAvailableCcs(callCluster)
|
||||
: [];
|
||||
const clusters = await this.fetchClusters(
|
||||
callCluster,
|
||||
params as CommonAlertParams,
|
||||
availableCcs
|
||||
);
|
||||
const data = await this.fetchData(params, callCluster, clusters, availableCcs);
|
||||
const esClient = services.scopedClusterClient.asCurrentUser;
|
||||
const availableCcs = Globals.app.config.ui.ccs.enabled ? await fetchAvailableCcs(esClient) : [];
|
||||
const clusters = await this.fetchClusters(esClient, params as CommonAlertParams, availableCcs);
|
||||
const data = await this.fetchData(params, esClient, clusters, availableCcs);
|
||||
return await this.processData(data, clusters, services, state);
|
||||
}
|
||||
|
||||
protected async fetchClusters(
|
||||
callCluster: CallCluster,
|
||||
esClient: ElasticsearchClient,
|
||||
params: CommonAlertParams,
|
||||
ccs?: string[]
|
||||
) {
|
||||
|
@ -264,7 +243,7 @@ export class BaseAlert {
|
|||
esIndexPattern = getCcsIndexPattern(esIndexPattern, ccs);
|
||||
}
|
||||
if (!params.limit) {
|
||||
return await fetchClusters(callCluster, esIndexPattern);
|
||||
return await fetchClusters(esClient, esIndexPattern);
|
||||
}
|
||||
const limit = parseDuration(params.limit);
|
||||
const rangeFilter = this.alertOptions.fetchClustersRange
|
||||
|
@ -275,12 +254,12 @@ export class BaseAlert {
|
|||
},
|
||||
}
|
||||
: undefined;
|
||||
return await fetchClusters(callCluster, esIndexPattern, rangeFilter);
|
||||
return await fetchClusters(esClient, esIndexPattern, rangeFilter);
|
||||
}
|
||||
|
||||
protected async fetchData(
|
||||
params: CommonAlertParams | unknown,
|
||||
callCluster: CallCluster,
|
||||
esClient: ElasticsearchClient,
|
||||
clusters: AlertCluster[],
|
||||
availableCcs: string[]
|
||||
): Promise<Array<AlertData & unknown>> {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { BaseAlert } from './base_alert';
|
||||
import {
|
||||
AlertData,
|
||||
|
@ -70,7 +71,7 @@ export class CCRReadExceptionsAlert extends BaseAlert {
|
|||
|
||||
protected async fetchData(
|
||||
params: CommonAlertParams,
|
||||
callCluster: any,
|
||||
esClient: ElasticsearchClient,
|
||||
clusters: AlertCluster[],
|
||||
availableCcs: string[]
|
||||
): Promise<AlertData[]> {
|
||||
|
@ -83,7 +84,7 @@ export class CCRReadExceptionsAlert extends BaseAlert {
|
|||
const endMs = +new Date();
|
||||
const startMs = endMs - duration;
|
||||
const stats = await fetchCCRReadExceptions(
|
||||
callCluster,
|
||||
esClient,
|
||||
esIndexPattern,
|
||||
startMs,
|
||||
endMs,
|
||||
|
|
|
@ -10,6 +10,7 @@ import { ALERT_CLUSTER_HEALTH } from '../../common/constants';
|
|||
import { AlertClusterHealthType, AlertSeverity } from '../../common/enums';
|
||||
import { fetchClusterHealth } from '../lib/alerts/fetch_cluster_health';
|
||||
import { fetchClusters } from '../lib/alerts/fetch_clusters';
|
||||
import { elasticsearchServiceMock } from 'src/core/server/mocks';
|
||||
|
||||
const RealDate = Date;
|
||||
|
||||
|
@ -80,7 +81,7 @@ describe('ClusterHealthAlert', () => {
|
|||
const getState = jest.fn();
|
||||
const executorOptions = {
|
||||
services: {
|
||||
callCluster: jest.fn(),
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
replaceState,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { BaseAlert } from './base_alert';
|
||||
import {
|
||||
AlertData,
|
||||
|
@ -64,7 +65,7 @@ export class ClusterHealthAlert extends BaseAlert {
|
|||
|
||||
protected async fetchData(
|
||||
params: CommonAlertParams,
|
||||
callCluster: any,
|
||||
esClient: ElasticsearchClient,
|
||||
clusters: AlertCluster[],
|
||||
availableCcs: string[]
|
||||
): Promise<AlertData[]> {
|
||||
|
@ -72,7 +73,7 @@ export class ClusterHealthAlert extends BaseAlert {
|
|||
if (availableCcs) {
|
||||
esIndexPattern = getCcsIndexPattern(esIndexPattern, availableCcs);
|
||||
}
|
||||
const healths = await fetchClusterHealth(callCluster, clusters, esIndexPattern);
|
||||
const healths = await fetchClusterHealth(esClient, clusters, esIndexPattern);
|
||||
return healths.map((clusterHealth) => {
|
||||
const shouldFire = clusterHealth.health !== AlertClusterHealthType.Green;
|
||||
const severity =
|
||||
|
|
|
@ -9,6 +9,7 @@ import { CpuUsageAlert } from './cpu_usage_alert';
|
|||
import { ALERT_CPU_USAGE } from '../../common/constants';
|
||||
import { fetchCpuUsageNodeStats } from '../lib/alerts/fetch_cpu_usage_node_stats';
|
||||
import { fetchClusters } from '../lib/alerts/fetch_clusters';
|
||||
import { elasticsearchServiceMock } from 'src/core/server/mocks';
|
||||
|
||||
const RealDate = Date;
|
||||
|
||||
|
@ -83,7 +84,7 @@ describe('CpuUsageAlert', () => {
|
|||
const getState = jest.fn();
|
||||
const executorOptions = {
|
||||
services: {
|
||||
callCluster: jest.fn(),
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
replaceState,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import numeral from '@elastic/numeral';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { BaseAlert } from './base_alert';
|
||||
import {
|
||||
AlertData,
|
||||
|
@ -68,7 +69,7 @@ export class CpuUsageAlert extends BaseAlert {
|
|||
|
||||
protected async fetchData(
|
||||
params: CommonAlertParams,
|
||||
callCluster: any,
|
||||
esClient: ElasticsearchClient,
|
||||
clusters: AlertCluster[],
|
||||
availableCcs: string[]
|
||||
): Promise<AlertData[]> {
|
||||
|
@ -80,7 +81,7 @@ export class CpuUsageAlert extends BaseAlert {
|
|||
const endMs = +new Date();
|
||||
const startMs = endMs - duration;
|
||||
const stats = await fetchCpuUsageNodeStats(
|
||||
callCluster,
|
||||
esClient,
|
||||
clusters,
|
||||
esIndexPattern,
|
||||
startMs,
|
||||
|
|
|
@ -9,6 +9,7 @@ import { DiskUsageAlert } from './disk_usage_alert';
|
|||
import { ALERT_DISK_USAGE } from '../../common/constants';
|
||||
import { fetchDiskUsageNodeStats } from '../lib/alerts/fetch_disk_usage_node_stats';
|
||||
import { fetchClusters } from '../lib/alerts/fetch_clusters';
|
||||
import { elasticsearchServiceMock } from 'src/core/server/mocks';
|
||||
|
||||
type IDiskUsageAlertMock = DiskUsageAlert & {
|
||||
defaultParams: {
|
||||
|
@ -95,7 +96,7 @@ describe('DiskUsageAlert', () => {
|
|||
const getState = jest.fn();
|
||||
const executorOptions = {
|
||||
services: {
|
||||
callCluster: jest.fn(),
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
replaceState,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import numeral from '@elastic/numeral';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { BaseAlert } from './base_alert';
|
||||
import {
|
||||
AlertData,
|
||||
|
@ -67,7 +68,7 @@ export class DiskUsageAlert extends BaseAlert {
|
|||
|
||||
protected async fetchData(
|
||||
params: CommonAlertParams,
|
||||
callCluster: any,
|
||||
esClient: ElasticsearchClient,
|
||||
clusters: AlertCluster[],
|
||||
availableCcs: string[]
|
||||
): Promise<AlertData[]> {
|
||||
|
@ -77,7 +78,7 @@ export class DiskUsageAlert extends BaseAlert {
|
|||
}
|
||||
const { duration, threshold } = params;
|
||||
const stats = await fetchDiskUsageNodeStats(
|
||||
callCluster,
|
||||
esClient,
|
||||
clusters,
|
||||
esIndexPattern,
|
||||
duration as string,
|
||||
|
|
|
@ -9,6 +9,7 @@ import { ElasticsearchVersionMismatchAlert } from './elasticsearch_version_misma
|
|||
import { ALERT_ELASTICSEARCH_VERSION_MISMATCH } from '../../common/constants';
|
||||
import { fetchElasticsearchVersions } from '../lib/alerts/fetch_elasticsearch_versions';
|
||||
import { fetchClusters } from '../lib/alerts/fetch_clusters';
|
||||
import { elasticsearchServiceMock } from 'src/core/server/mocks';
|
||||
|
||||
const RealDate = Date;
|
||||
|
||||
|
@ -84,7 +85,7 @@ describe('ElasticsearchVersionMismatchAlert', () => {
|
|||
const getState = jest.fn();
|
||||
const executorOptions = {
|
||||
services: {
|
||||
callCluster: jest.fn(),
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
replaceState,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { BaseAlert } from './base_alert';
|
||||
import {
|
||||
AlertData,
|
||||
|
@ -53,7 +54,7 @@ export class ElasticsearchVersionMismatchAlert extends BaseAlert {
|
|||
|
||||
protected async fetchData(
|
||||
params: CommonAlertParams,
|
||||
callCluster: any,
|
||||
esClient: ElasticsearchClient,
|
||||
clusters: AlertCluster[],
|
||||
availableCcs: string[]
|
||||
): Promise<AlertData[]> {
|
||||
|
@ -62,7 +63,7 @@ export class ElasticsearchVersionMismatchAlert extends BaseAlert {
|
|||
esIndexPattern = getCcsIndexPattern(esIndexPattern, availableCcs);
|
||||
}
|
||||
const elasticsearchVersions = await fetchElasticsearchVersions(
|
||||
callCluster,
|
||||
esClient,
|
||||
clusters,
|
||||
esIndexPattern,
|
||||
Globals.app.config.ui.max_bucket_size
|
||||
|
|
|
@ -9,6 +9,7 @@ import { KibanaVersionMismatchAlert } from './kibana_version_mismatch_alert';
|
|||
import { ALERT_KIBANA_VERSION_MISMATCH } from '../../common/constants';
|
||||
import { fetchKibanaVersions } from '../lib/alerts/fetch_kibana_versions';
|
||||
import { fetchClusters } from '../lib/alerts/fetch_clusters';
|
||||
import { elasticsearchServiceMock } from 'src/core/server/mocks';
|
||||
|
||||
const RealDate = Date;
|
||||
|
||||
|
@ -87,7 +88,7 @@ describe('KibanaVersionMismatchAlert', () => {
|
|||
const getState = jest.fn();
|
||||
const executorOptions = {
|
||||
services: {
|
||||
callCluster: jest.fn(),
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
replaceState,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { BaseAlert } from './base_alert';
|
||||
import {
|
||||
AlertData,
|
||||
|
@ -66,7 +67,7 @@ export class KibanaVersionMismatchAlert extends BaseAlert {
|
|||
|
||||
protected async fetchData(
|
||||
params: CommonAlertParams,
|
||||
callCluster: any,
|
||||
esClient: ElasticsearchClient,
|
||||
clusters: AlertCluster[],
|
||||
availableCcs: string[]
|
||||
): Promise<AlertData[]> {
|
||||
|
@ -75,7 +76,7 @@ export class KibanaVersionMismatchAlert extends BaseAlert {
|
|||
kibanaIndexPattern = getCcsIndexPattern(kibanaIndexPattern, availableCcs);
|
||||
}
|
||||
const kibanaVersions = await fetchKibanaVersions(
|
||||
callCluster,
|
||||
esClient,
|
||||
clusters,
|
||||
kibanaIndexPattern,
|
||||
Globals.app.config.ui.max_bucket_size
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { BaseAlert } from './base_alert';
|
||||
import {
|
||||
AlertData,
|
||||
|
@ -59,7 +60,7 @@ export class LargeShardSizeAlert extends BaseAlert {
|
|||
|
||||
protected async fetchData(
|
||||
params: CommonAlertParams & { indexPattern: string },
|
||||
callCluster: any,
|
||||
esClient: ElasticsearchClient,
|
||||
clusters: AlertCluster[],
|
||||
availableCcs: string[]
|
||||
): Promise<AlertData[]> {
|
||||
|
@ -70,7 +71,7 @@ export class LargeShardSizeAlert extends BaseAlert {
|
|||
const { threshold, indexPattern: shardIndexPatterns } = params;
|
||||
|
||||
const stats = await fetchIndexShardSize(
|
||||
callCluster,
|
||||
esClient,
|
||||
clusters,
|
||||
esIndexPattern,
|
||||
threshold!,
|
||||
|
|
|
@ -10,6 +10,7 @@ import { ALERT_LICENSE_EXPIRATION } from '../../common/constants';
|
|||
import { AlertSeverity } from '../../common/enums';
|
||||
import { fetchLicenses } from '../lib/alerts/fetch_licenses';
|
||||
import { fetchClusters } from '../lib/alerts/fetch_clusters';
|
||||
import { elasticsearchServiceMock } from 'src/core/server/mocks';
|
||||
|
||||
const RealDate = Date;
|
||||
|
||||
|
@ -85,7 +86,7 @@ describe('LicenseExpirationAlert', () => {
|
|||
const getState = jest.fn();
|
||||
const executorOptions = {
|
||||
services: {
|
||||
callCluster: jest.fn(),
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
replaceState,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
import moment from 'moment';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { BaseAlert } from './base_alert';
|
||||
import {
|
||||
AlertData,
|
||||
|
@ -78,7 +79,7 @@ export class LicenseExpirationAlert extends BaseAlert {
|
|||
|
||||
protected async fetchData(
|
||||
params: CommonAlertParams,
|
||||
callCluster: any,
|
||||
esClient: ElasticsearchClient,
|
||||
clusters: AlertCluster[],
|
||||
availableCcs: string[]
|
||||
): Promise<AlertData[]> {
|
||||
|
@ -86,7 +87,7 @@ export class LicenseExpirationAlert extends BaseAlert {
|
|||
if (availableCcs) {
|
||||
esIndexPattern = getCcsIndexPattern(esIndexPattern, availableCcs);
|
||||
}
|
||||
const licenses = await fetchLicenses(callCluster, clusters, esIndexPattern);
|
||||
const licenses = await fetchLicenses(esClient, clusters, esIndexPattern);
|
||||
|
||||
return licenses.map((license) => {
|
||||
const { clusterUuid, type, expiryDateMS, status, ccs } = license;
|
||||
|
|
|
@ -9,6 +9,7 @@ import { LogstashVersionMismatchAlert } from './logstash_version_mismatch_alert'
|
|||
import { ALERT_LOGSTASH_VERSION_MISMATCH } from '../../common/constants';
|
||||
import { fetchLogstashVersions } from '../lib/alerts/fetch_logstash_versions';
|
||||
import { fetchClusters } from '../lib/alerts/fetch_clusters';
|
||||
import { elasticsearchServiceMock } from 'src/core/server/mocks';
|
||||
|
||||
const RealDate = Date;
|
||||
|
||||
|
@ -85,7 +86,7 @@ describe('LogstashVersionMismatchAlert', () => {
|
|||
const getState = jest.fn();
|
||||
const executorOptions = {
|
||||
services: {
|
||||
callCluster: jest.fn(),
|
||||
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
|
||||
alertInstanceFactory: jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
replaceState,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { BaseAlert } from './base_alert';
|
||||
import {
|
||||
AlertData,
|
||||
|
@ -53,7 +54,7 @@ export class LogstashVersionMismatchAlert extends BaseAlert {
|
|||
|
||||
protected async fetchData(
|
||||
params: CommonAlertParams,
|
||||
callCluster: any,
|
||||
esClient: ElasticsearchClient,
|
||||
clusters: AlertCluster[],
|
||||
availableCcs: string[]
|
||||
): Promise<AlertData[]> {
|
||||
|
@ -62,7 +63,7 @@ export class LogstashVersionMismatchAlert extends BaseAlert {
|
|||
logstashIndexPattern = getCcsIndexPattern(logstashIndexPattern, availableCcs);
|
||||
}
|
||||
const logstashVersions = await fetchLogstashVersions(
|
||||
callCluster,
|
||||
esClient,
|
||||
clusters,
|
||||
logstashIndexPattern,
|
||||
Globals.app.config.ui.max_bucket_size
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import numeral from '@elastic/numeral';
|
||||
import { ElasticsearchClient } from 'kibana/server';
|
||||
import { BaseAlert } from './base_alert';
|
||||
import {
|
||||
AlertData,
|
||||
|
@ -68,7 +69,7 @@ export class MemoryUsageAlert extends BaseAlert {
|
|||
|
||||
protected async fetchData(
|
||||
params: CommonAlertParams,
|
||||
callCluster: any,
|
||||
esClient: ElasticsearchClient,
|
||||
clusters: AlertCluster[],
|
||||
availableCcs: string[]
|
||||
): Promise<AlertData[]> {
|
||||
|
@ -82,7 +83,7 @@ export class MemoryUsageAlert extends BaseAlert {
|
|||
const startMs = endMs - parsedDuration;
|
||||
|
||||
const stats = await fetchMemoryUsageNodeStats(
|
||||
callCluster,
|
||||
esClient,
|
||||
clusters,
|
||||
esIndexPattern,
|
||||
startMs,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue