[ResponseOps] Lazy load dataViews and wrappedSearchSourceClient services when running alerting rules (#189929)

Resolves https://github.com/elastic/kibana/issues/184322

## Summary

This PR updates `getExecutorServices` to allow alerting rules to only
load the dataViews and wrappedSearchSourceClient services when needed. I
updated the rule types dependent on dataViews and/or
wrappedSearchSourceClient.


### Checklist

- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

### To verify

- Verify that the dataviews and searchsource are only loaded when
needed. I think the best way to verify this is create an Index threshold
rule and make sure that the `dataViews` and `searchSourceClient`
services are not created.
- Verify that the updated rules work correctly. I updated the following
rule types:
Custom threshold
SLO burn rate
ES query
Indicator match
This commit is contained in:
Alexi Doak 2024-08-19 12:04:10 -07:00 committed by GitHub
parent 1d5a0e1a44
commit cbaa3a8aa0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 148 additions and 123 deletions

View file

@ -174,10 +174,10 @@ const createRuleExecutorServicesMock = <
shouldWriteAlerts: () => true,
shouldStopExecution: () => true,
search: createAbortableSearchServiceMock(),
searchSourceClient: searchSourceCommonMock,
getSearchSourceClient: jest.fn().mockResolvedValue(searchSourceCommonMock),
ruleMonitoringService: createRuleMonitoringServiceMock(),
share: createShareStartMock(),
dataViews: dataViewPluginMocks.createStartContract(),
getDataViews: jest.fn().mockResolvedValue(dataViewPluginMocks.createStartContract()),
};
};
export type RuleExecutorServicesMock = ReturnType<typeof createRuleExecutorServicesMock>;

View file

@ -212,7 +212,7 @@ export class AdHocTaskRunner implements CancellableTask {
taskInstance: this.taskInstance,
});
const executorServices = await getExecutorServices({
const executorServices = getExecutorServices({
context: this.context,
fakeRequest,
abortController: this.searchAbortController,

View file

@ -40,16 +40,16 @@ interface GetExecutorServicesOpts {
}
export interface ExecutorServices {
dataViews: DataViewsContract;
ruleMonitoringService: PublicRuleMonitoringService;
ruleResultService: PublicRuleResultService;
savedObjectsClient: SavedObjectsClientContract;
uiSettingsClient: IUiSettingsClient;
wrappedScopedClusterClient: WrappedScopedClusterClient;
wrappedSearchSourceClient: WrappedSearchSourceClient;
getDataViews: () => Promise<DataViewsContract>;
getWrappedSearchSourceClient: () => Promise<WrappedSearchSourceClient>;
}
export const getExecutorServices = async (opts: GetExecutorServicesOpts) => {
export const getExecutorServices = (opts: GetExecutorServicesOpts) => {
const { context, abortController, fakeRequest, logger, ruleData, ruleTaskTimeout } = opts;
const wrappedClientOptions = {
@ -66,34 +66,35 @@ export const getExecutorServices = async (opts: GetExecutorServicesOpts) => {
scopedClusterClient,
});
const searchSourceClient = await withAlertingSpan('alerting:get-search-source-client', () =>
context.data.search.searchSource.asScoped(fakeRequest)
);
const wrappedSearchSourceClient = wrapSearchSourceClient({
...wrappedClientOptions,
searchSourceClient,
});
const savedObjectsClient = context.savedObjects.getScopedClient(fakeRequest, {
includedHiddenTypes: [RULE_SAVED_OBJECT_TYPE, 'action'],
});
const dataViews = await await withAlertingSpan('alerting:get-data-views-factory', () =>
context.dataViews.dataViewsServiceFactory(
savedObjectsClient,
scopedClusterClient.asInternalUser
)
);
const uiSettingsClient = context.uiSettings.asScopedToClient(savedObjectsClient);
return {
dataViews,
ruleMonitoringService: opts.ruleMonitoringService.getLastRunMetricsSetters(),
ruleResultService: opts.ruleResultService.getLastRunSetters(),
savedObjectsClient,
uiSettingsClient,
wrappedScopedClusterClient,
wrappedSearchSourceClient,
getDataViews: async () => {
const dataViews = await withAlertingSpan('alerting:get-data-views-factory', () =>
context.dataViews.dataViewsServiceFactory(
savedObjectsClient,
scopedClusterClient.asInternalUser
)
);
return dataViews;
},
getWrappedSearchSourceClient: async () => {
const searchSourceClient = await withAlertingSpan('alerting:get-search-source-client', () =>
context.data.search.searchSource.asScoped(fakeRequest)
);
return wrapSearchSourceClient({
...wrappedClientOptions,
searchSourceClient,
});
},
};
};

View file

@ -21,7 +21,6 @@ import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks';
import { publicRuleMonitoringServiceMock } from '../monitoring/rule_monitoring_service.mock';
import { publicRuleResultServiceMock } from '../monitoring/rule_result_service.mock';
import { wrappedScopedClusterClientMock } from '../lib/wrap_scoped_cluster_client.mock';
import { wrappedSearchSourceClientMock } from '../lib/wrap_search_source_client.mock';
import { NormalizedRuleType } from '../rule_type_registry';
import {
ConcreteTaskInstance,
@ -41,7 +40,8 @@ const ruleRunMetricsStore = ruleRunMetricsStoreMock.create();
const savedObjectsClient = savedObjectsClientMock.create();
const uiSettingsClient = uiSettingsServiceMock.createClient();
const wrappedScopedClusterClient = wrappedScopedClusterClientMock.create();
const wrappedSearchSourceClient = wrappedSearchSourceClientMock.create();
const getDataViews = jest.fn().mockResolvedValue(dataViews);
const getWrappedSearchSourceClient = jest.fn();
const timer = new TaskRunnerTimer({ logger });
const ruleType: jest.Mocked<
@ -172,13 +172,13 @@ describe('RuleTypeRunner', () => {
alertsClient,
executionId: 'abc',
executorServices: {
dataViews,
getDataViews,
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
uiSettingsClient,
wrappedScopedClusterClient,
wrappedSearchSourceClient,
getWrappedSearchSourceClient,
},
rule: mockedRule,
ruleType,
@ -192,12 +192,12 @@ describe('RuleTypeRunner', () => {
services: {
alertFactory: alertsClient.factory(),
alertsClient: alertsClient.client(),
dataViews,
getDataViews: expect.any(Function),
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
scopedClusterClient: wrappedScopedClusterClient.client(),
searchSourceClient: wrappedSearchSourceClient.searchSourceClient,
getSearchSourceClient: expect.any(Function),
share: {},
shouldStopExecution: expect.any(Function),
shouldWriteAlerts: expect.any(Function),
@ -277,13 +277,13 @@ describe('RuleTypeRunner', () => {
alertsClient,
executionId: 'abc',
executorServices: {
dataViews,
getDataViews,
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
uiSettingsClient,
wrappedScopedClusterClient,
wrappedSearchSourceClient,
getWrappedSearchSourceClient,
},
rule: mockedRule,
ruleType,
@ -297,12 +297,12 @@ describe('RuleTypeRunner', () => {
services: {
alertFactory: alertsClient.factory(),
alertsClient: alertsClient.client(),
dataViews,
getDataViews: expect.any(Function),
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
scopedClusterClient: wrappedScopedClusterClient.client(),
searchSourceClient: wrappedSearchSourceClient.searchSourceClient,
getSearchSourceClient: expect.any(Function),
share: {},
shouldStopExecution: expect.any(Function),
shouldWriteAlerts: expect.any(Function),
@ -385,13 +385,13 @@ describe('RuleTypeRunner', () => {
alertsClient,
executionId: 'abc',
executorServices: {
dataViews,
getDataViews,
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
uiSettingsClient,
wrappedScopedClusterClient,
wrappedSearchSourceClient,
getWrappedSearchSourceClient,
},
rule: mockedRule,
ruleType,
@ -446,13 +446,13 @@ describe('RuleTypeRunner', () => {
alertsClient,
executionId: 'abc',
executorServices: {
dataViews,
getDataViews,
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
uiSettingsClient,
wrappedScopedClusterClient,
wrappedSearchSourceClient,
getWrappedSearchSourceClient,
},
rule: mockedRule,
ruleType,
@ -466,12 +466,12 @@ describe('RuleTypeRunner', () => {
services: {
alertFactory: alertsClient.factory(),
alertsClient: alertsClient.client(),
dataViews,
getDataViews: expect.any(Function),
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
scopedClusterClient: wrappedScopedClusterClient.client(),
searchSourceClient: wrappedSearchSourceClient.searchSourceClient,
getSearchSourceClient: expect.any(Function),
share: {},
shouldStopExecution: expect.any(Function),
shouldWriteAlerts: expect.any(Function),
@ -545,13 +545,13 @@ describe('RuleTypeRunner', () => {
alertsClient,
executionId: 'abc',
executorServices: {
dataViews,
getDataViews,
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
uiSettingsClient,
wrappedScopedClusterClient,
wrappedSearchSourceClient,
getWrappedSearchSourceClient,
},
rule: mockedRule,
ruleType,
@ -565,12 +565,12 @@ describe('RuleTypeRunner', () => {
services: {
alertFactory: alertsClient.factory(),
alertsClient: alertsClient.client(),
dataViews,
getDataViews: expect.any(Function),
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
scopedClusterClient: wrappedScopedClusterClient.client(),
searchSourceClient: wrappedSearchSourceClient.searchSourceClient,
getSearchSourceClient: expect.any(Function),
share: {},
shouldStopExecution: expect.any(Function),
shouldWriteAlerts: expect.any(Function),
@ -644,13 +644,13 @@ describe('RuleTypeRunner', () => {
alertsClient,
executionId: 'abc',
executorServices: {
dataViews,
getDataViews,
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
uiSettingsClient,
wrappedScopedClusterClient,
wrappedSearchSourceClient,
getWrappedSearchSourceClient,
},
rule: mockedRule,
ruleType,
@ -679,13 +679,13 @@ describe('RuleTypeRunner', () => {
alertsClient,
executionId: 'abc',
executorServices: {
dataViews,
getDataViews,
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
uiSettingsClient,
wrappedScopedClusterClient,
wrappedSearchSourceClient,
getWrappedSearchSourceClient,
},
rule: mockedRule,
ruleType,
@ -699,12 +699,12 @@ describe('RuleTypeRunner', () => {
services: {
alertFactory: alertsClient.factory(),
alertsClient: alertsClient.client(),
dataViews,
getDataViews: expect.any(Function),
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
scopedClusterClient: wrappedScopedClusterClient.client(),
searchSourceClient: wrappedSearchSourceClient.searchSourceClient,
getSearchSourceClient: expect.any(Function),
share: {},
shouldStopExecution: expect.any(Function),
shouldWriteAlerts: expect.any(Function),
@ -791,13 +791,13 @@ describe('RuleTypeRunner', () => {
alertsClient,
executionId: 'abc',
executorServices: {
dataViews,
getDataViews,
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
uiSettingsClient,
wrappedScopedClusterClient,
wrappedSearchSourceClient,
getWrappedSearchSourceClient,
},
rule: mockedRule,
ruleType,
@ -811,12 +811,12 @@ describe('RuleTypeRunner', () => {
services: {
alertFactory: alertsClient.factory(),
alertsClient: alertsClient.client(),
dataViews,
getDataViews: expect.any(Function),
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
scopedClusterClient: wrappedScopedClusterClient.client(),
searchSourceClient: wrappedSearchSourceClient.searchSourceClient,
getSearchSourceClient: expect.any(Function),
share: {},
shouldStopExecution: expect.any(Function),
shouldWriteAlerts: expect.any(Function),
@ -903,13 +903,13 @@ describe('RuleTypeRunner', () => {
alertsClient,
executionId: 'abc',
executorServices: {
dataViews,
getDataViews,
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
uiSettingsClient,
wrappedScopedClusterClient,
wrappedSearchSourceClient,
getWrappedSearchSourceClient,
},
rule: mockedRule,
ruleType,
@ -924,12 +924,12 @@ describe('RuleTypeRunner', () => {
services: {
alertFactory: alertsClient.factory(),
alertsClient: alertsClient.client(),
dataViews,
getDataViews: expect.any(Function),
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
scopedClusterClient: wrappedScopedClusterClient.client(),
searchSourceClient: wrappedSearchSourceClient.searchSourceClient,
getSearchSourceClient: expect.any(Function),
share: {},
shouldStopExecution: expect.any(Function),
shouldWriteAlerts: expect.any(Function),
@ -1005,13 +1005,13 @@ describe('RuleTypeRunner', () => {
alertsClient,
executionId: 'abc',
executorServices: {
dataViews,
getDataViews,
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
uiSettingsClient,
wrappedScopedClusterClient,
wrappedSearchSourceClient,
getWrappedSearchSourceClient,
},
rule: mockedRule,
ruleType,
@ -1026,12 +1026,12 @@ describe('RuleTypeRunner', () => {
services: {
alertFactory: alertsClient.factory(),
alertsClient: alertsClient.client(),
dataViews,
getDataViews: expect.any(Function),
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
scopedClusterClient: wrappedScopedClusterClient.client(),
searchSourceClient: wrappedSearchSourceClient.searchSourceClient,
getSearchSourceClient: expect.any(Function),
share: {},
shouldStopExecution: expect.any(Function),
shouldWriteAlerts: expect.any(Function),
@ -1107,13 +1107,13 @@ describe('RuleTypeRunner', () => {
alertsClient,
executionId: 'abc',
executorServices: {
dataViews,
getDataViews,
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
uiSettingsClient,
wrappedScopedClusterClient,
wrappedSearchSourceClient,
getWrappedSearchSourceClient,
},
rule: mockedRule,
ruleType,
@ -1128,12 +1128,12 @@ describe('RuleTypeRunner', () => {
services: {
alertFactory: alertsClient.factory(),
alertsClient: alertsClient.client(),
dataViews,
getDataViews: expect.any(Function),
ruleMonitoringService: publicRuleMonitoringService,
ruleResultService: publicRuleResultService,
savedObjectsClient,
scopedClusterClient: wrappedScopedClusterClient.client(),
searchSourceClient: wrappedSearchSourceClient.searchSourceClient,
getSearchSourceClient: expect.any(Function),
share: {},
shouldStopExecution: expect.any(Function),
shouldWriteAlerts: expect.any(Function),

View file

@ -31,6 +31,7 @@ import { ExecutorServices } from './get_executor_services';
import { TaskRunnerTimer, TaskRunnerTimerSpan } from './task_runner_timer';
import { RuleRunnerErrorStackTraceLog, RuleTypeRunnerContext, TaskRunnerContext } from './types';
import { withAlertingSpan } from './lib';
import { WrappedSearchSourceClient } from '../lib/wrap_search_source_client';
interface ConstructorOpts<
Params extends RuleTypeParams,
@ -203,6 +204,7 @@ export class RuleTypeRunner<
};
let executorResult: { state: RuleState } | undefined;
let wrappedSearchSourceClient: WrappedSearchSourceClient | undefined;
try {
const ctx = {
type: 'alert',
@ -219,17 +221,23 @@ export class RuleTypeRunner<
services: {
alertFactory: alertsClient.factory(),
alertsClient: alertsClient.client(),
dataViews: executorServices.dataViews,
ruleMonitoringService: executorServices.ruleMonitoringService,
ruleResultService: executorServices.ruleResultService,
savedObjectsClient: executorServices.savedObjectsClient,
scopedClusterClient: executorServices.wrappedScopedClusterClient.client(),
searchSourceClient: executorServices.wrappedSearchSourceClient.searchSourceClient,
share: this.options.context.share,
shouldStopExecution: () => this.cancelled,
shouldWriteAlerts: () =>
this.shouldLogAndScheduleActionsForAlerts(ruleType.cancelAlertsOnRuleTimeout),
uiSettingsClient: executorServices.uiSettingsClient,
getDataViews: executorServices.getDataViews,
getSearchSourceClient: async () => {
if (!wrappedSearchSourceClient) {
wrappedSearchSourceClient =
await executorServices.getWrappedSearchSourceClient();
}
return wrappedSearchSourceClient.searchSourceClient;
},
},
params: validatedParams,
state: ruleTypeState as RuleState,
@ -306,10 +314,12 @@ export class RuleTypeRunner<
context.alertingEventLogger.setExecutionSucceeded(
`rule executed: ${context.ruleLogPrefix}`
);
context.ruleRunMetricsStore.setSearchMetrics([
executorServices.wrappedScopedClusterClient.getMetrics(),
executorServices.wrappedSearchSourceClient.getMetrics(),
]);
const metrics = [executorServices.wrappedScopedClusterClient.getMetrics()];
if (wrappedSearchSourceClient) {
metrics.push(wrappedSearchSourceClient.getMetrics());
}
context.ruleRunMetricsStore.setSearchMetrics(metrics);
return {
updatedRuleTypeState: executorResult?.state || undefined,

View file

@ -1969,9 +1969,9 @@ describe('Task Runner', () => {
});
test('should set unexpected errors as framework-error', async () => {
(getExecutorServicesModule.getExecutorServices as jest.Mock).mockRejectedValue(
new Error('test')
);
(getExecutorServicesModule.getExecutorServices as jest.Mock).mockImplementation(() => {
throw new Error('test');
});
const taskRunner = new TaskRunner({
ruleType,

View file

@ -339,23 +339,21 @@ export class TaskRunner<
taskInstance: this.taskInstance,
})
);
const executorServices = await withAlertingSpan('alerting:get-executor-services', () =>
getExecutorServices({
context: this.context,
fakeRequest,
abortController: this.searchAbortController,
logger: this.logger,
ruleMonitoringService: this.ruleMonitoring,
ruleResultService: this.ruleResult,
ruleData: {
name: rule.name,
alertTypeId: rule.alertTypeId,
id: rule.id,
spaceId,
},
ruleTaskTimeout: this.ruleType.ruleTaskTimeout,
})
);
const executorServices = getExecutorServices({
context: this.context,
fakeRequest,
abortController: this.searchAbortController,
logger: this.logger,
ruleMonitoringService: this.ruleMonitoring,
ruleResultService: this.ruleResult,
ruleData: {
name: rule.name,
alertTypeId: rule.alertTypeId,
id: rule.id,
spaceId,
},
ruleTaskTimeout: this.ruleType.ruleTaskTimeout,
});
const {
state: updatedRuleTypeState,

View file

@ -102,7 +102,6 @@ export interface RuleExecutorServices<
ActionGroupIds extends string = never,
AlertData extends RuleAlertData = RuleAlertData
> {
searchSourceClient: ISearchStartSearchSource;
savedObjectsClient: SavedObjectsClientContract;
uiSettingsClient: IUiSettingsClient;
scopedClusterClient: IScopedClusterClient;
@ -121,8 +120,9 @@ export interface RuleExecutorServices<
shouldStopExecution: () => boolean;
ruleMonitoringService?: PublicRuleMonitoringService;
share: SharePluginStart;
dataViews: DataViewsContract;
ruleResultService?: PublicRuleResultService;
getDataViews: () => Promise<DataViewsContract>;
getSearchSourceClient: () => Promise<ISearchStartSearchSource>;
}
export interface RuleExecutorOptions<

View file

@ -178,10 +178,10 @@ const setup = () => {
services = {
...alertsServices,
searchSourceClient: {
getSearchSourceClient: jest.fn().mockResolvedValue({
...searchSourceCommonMock,
create: jest.fn(() => Promise.resolve(mockedSearchSource)),
},
}),
};
services.alertsClient.report.mockImplementation((params: any) => {

View file

@ -95,7 +95,8 @@ export const createCustomThresholdExecutor = ({
executionId,
});
const { searchSourceClient, alertsClient, uiSettingsClient } = services;
const { alertsClient, uiSettingsClient } = services;
const searchSourceClient = await services.getSearchSourceClient();
if (!alertsClient) {
throw new AlertsClientError();

View file

@ -184,12 +184,12 @@ describe('BurnRateRuleExecutor', () => {
done: jest.fn(),
alertLimit: { getValue: jest.fn(), setLimitReached: jest.fn() },
},
searchSourceClient: searchSourceClientMock,
getSearchSourceClient: jest.fn().mockResolvedValue(searchSourceClientMock),
uiSettingsClient: uiSettingsClientMock,
shouldWriteAlerts: jest.fn(),
shouldStopExecution: jest.fn(),
share: {} as SharePluginStart,
dataViews: dataViewPluginMocks.createStartContract(),
getDataViews: jest.fn().mockResolvedValue(dataViewPluginMocks.createStartContract()),
};
});

View file

@ -137,12 +137,12 @@ function createRule(shouldWriteAlerts: boolean = true) {
savedObjectsClient: {} as any,
scopedClusterClient: {} as any,
search: {} as any,
searchSourceClient: {} as ISearchStartSearchSource,
getSearchSourceClient: async () => ({} as ISearchStartSearchSource),
shouldStopExecution: () => false,
shouldWriteAlerts: () => shouldWriteAlerts,
uiSettingsClient: {} as any,
share: {} as SharePluginStart,
dataViews: dataViewPluginMocks.createStartContract(),
getDataViews: async () => dataViewPluginMocks.createStartContract(),
},
spaceId: 'spaceId',
startedAt,

View file

@ -86,9 +86,9 @@ export const createDefaultAlertExecutorOptions = <
scopedClusterClient: elasticsearchServiceMock.createScopedClusterClient(),
shouldWriteAlerts: () => shouldWriteAlerts,
shouldStopExecution: () => false,
searchSourceClient: searchSourceCommonMock,
getSearchSourceClient: async () => searchSourceCommonMock,
share: {} as SharePluginStart,
dataViews: dataViewPluginMocks.createStartContract(),
getDataViews: async () => dataViewPluginMocks.createStartContract(),
},
state,
previousStartedAt: null,

View file

@ -283,12 +283,13 @@ export const previewRulesRoute = (
abortController,
scopedClusterClient: coreContext.elasticsearch.client,
}),
searchSourceClient: wrapSearchSourceClient({
abortController,
searchSourceClient,
}),
getSearchSourceClient: async () =>
wrapSearchSourceClient({
abortController,
searchSourceClient,
}),
uiSettingsClient: coreContext.uiSettings.client,
dataViews: dataViewsService,
getDataViews: async () => dataViewsService,
share,
},
spaceId,

View file

@ -105,14 +105,14 @@ export const createRuleTypeMocks = (
alertWithPersistence: jest.fn(),
logger: loggerMock,
shouldWriteAlerts: () => true,
dataViews: {
getDataViews: jest.fn().mockResolvedValue({
createDataViewLazy: jest.fn().mockResolvedValue({
getFields: jest.fn().mockResolvedValue({
getFieldMapSorted: jest.fn().mockReturnValue({}),
}),
getSourceFiltering: jest.fn().mockReturnValue({ excludes: [] }),
}),
},
}),
};
return {

View file

@ -343,9 +343,10 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper =
!isQueryParams(params) &&
!isEqlParams(params)
) {
const dataViews = await services.getDataViews();
inputIndexFields = await getFieldsForWildcard({
index: inputIndex,
dataViews: services.dataViews,
dataViews,
language: params.language,
ruleExecutionLogger,
});

View file

@ -140,10 +140,11 @@ export const createThreatSignals = async ({
if (newPitId) threatPitId = newPitId;
};
const dataViews = await services.getDataViews();
const threatIndexFields = await getFieldsForWildcard({
index: threatIndex,
language: threatLanguage ?? 'kuery',
dataViews: services.dataViews,
dataViews,
ruleExecutionLogger,
});

View file

@ -74,8 +74,9 @@ export const getFilter = async ({
fields = [],
loadFields = false,
}: GetFilterArgs): Promise<ESBoolQuery> => {
const dataViews = await services.getDataViews();
const getQueryFilter = loadFields
? getQueryFilterLoadFields(services.dataViews)
? getQueryFilterLoadFields(dataViews)
: getQueryFilterNoLoadFields;
const dataTiersFilters = ruleTypesSupportingTierFilters.has(type)

View file

@ -101,11 +101,12 @@ describe('es_query executor', () => {
savedObjectsClient: {
get: () => ({ attributes: { consumer: 'alerts' } }),
},
searchSourceClient: searchSourceClientMock,
getSearchSourceClient: jest.fn().mockResolvedValue(searchSourceClientMock),
alertsClient: mockAlertClient,
alertWithLifecycle: jest.fn(),
logger,
shouldWriteAlerts: () => true,
getDataViews: jest.fn(),
};
const coreMock = {
http: { basePath: { publicBaseUrl: 'https://localhost:5601' } },

View file

@ -51,7 +51,10 @@ export async function executor(core: CoreSetup, options: ExecutorOptions<EsQuery
logger,
getTimeRange,
} = options;
const { alertsClient, scopedClusterClient, searchSourceClient, share, dataViews } = services;
const { alertsClient, scopedClusterClient, share } = services;
const searchSourceClient = await services.getSearchSourceClient();
const dataViews = await services.getDataViews();
if (!alertsClient) {
throw new AlertsClientError();
}

View file

@ -10,6 +10,7 @@ import type { Writable } from '@kbn/utility-types';
import { RuleExecutorServices } from '@kbn/alerting-plugin/server';
import { RuleExecutorServicesMock, alertsMock } from '@kbn/alerting-plugin/server/mocks';
import { loggingSystemMock } from '@kbn/core/server/mocks';
import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks';
import { getRuleType } from './rule_type';
import { EsQueryRuleParams, EsQueryRuleState } from './rule_type_params';
import { ActionContext } from './action_context';
@ -676,10 +677,13 @@ describe('ruleType', () => {
const searchResult: ESSearchResponse<unknown, {}> = generateResults([]);
const ruleServices: RuleExecutorServicesMock = alertsMock.createRuleExecutorServices();
(ruleServices.dataViews.create as jest.Mock).mockResolvedValueOnce({
...dataViewMock.toSpec(),
toSpec: () => dataViewMock.toSpec(),
toMinimalSpec: () => dataViewMock.toSpec(),
ruleServices.getDataViews = jest.fn().mockResolvedValueOnce({
...dataViewPluginMocks.createStartContract(),
create: jest.fn().mockResolvedValueOnce({
...dataViewMock.toSpec(),
toSpec: () => dataViewMock.toSpec(),
toMinimalSpec: () => dataViewMock.toSpec(),
}),
});
(searchSourceInstanceMock.getField as jest.Mock).mockImplementation((name: string) => {
if (name === 'index') {
@ -715,11 +719,14 @@ describe('ruleType', () => {
const params = { ...defaultParams, thresholdComparator: Comparator.GT_OR_EQ, threshold: [3] };
const ruleServices: RuleExecutorServicesMock = alertsMock.createRuleExecutorServices();
(ruleServices.dataViews.create as jest.Mock).mockResolvedValueOnce({
...dataViewMock.toSpec(),
toSpec: () => dataViewMock.toSpec(),
getTimeField: () => dataViewMock.fields[1],
toMinimalSpec: () => dataViewMock.toSpec(),
ruleServices.getDataViews = jest.fn().mockResolvedValueOnce({
...dataViewPluginMocks.createStartContract(),
create: jest.fn().mockResolvedValueOnce({
...dataViewMock.toSpec(),
toSpec: () => dataViewMock.toSpec(),
getTimeField: () => dataViewMock.fields[1],
toMinimalSpec: () => dataViewMock.toSpec(),
}),
});
(searchSourceInstanceMock.getField as jest.Mock).mockImplementation((name: string) => {
if (name === 'index') {