Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EventLog] Added event log API to get events for multiple saved objects. #87596

Merged
merged 12 commits into from
Jan 13, 2021
8 changes: 7 additions & 1 deletion x-pack/plugins/actions/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
ElasticsearchServiceStart,
ILegacyClusterClient,
SavedObjectsClientContract,
SavedObjectsBulkGetObject,
} from '../../../../src/core/server';

import {
Expand Down Expand Up @@ -333,7 +334,12 @@ export class ActionsPlugin implements Plugin<Promise<PluginSetupContract>, Plugi

this.eventLogService!.registerSavedObjectProvider('action', (request) => {
const client = secureGetActionsClientWithRequest(request);
return async (type: string, id: string) => (await client).get({ id });
return (objects?: SavedObjectsBulkGetObject[]) =>
objects
? Promise.all(
objects.map(async (objectItem) => await (await client).get({ id: objectItem.id }))
)
: Promise.resolve([]);
});

const getScopedSavedObjectsClientWithoutAccessToActions = (request: KibanaRequest) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ export class AlertsClient {
this.logger.debug(`getAlertInstanceSummary(): search the event log for alert ${id}`);
let events: IEvent[];
try {
const queryResults = await eventLogClient.findEventsBySavedObject('alert', id, {
const queryResults = await eventLogClient.findEventsBySavedObjectIds('alert', [id], {
page: 1,
per_page: 10000,
start: parsedDateStart.toISOString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ describe('getAlertInstanceSummary()', () => {
total: events.length,
data: events,
};
eventLogClient.findEventsBySavedObject.mockResolvedValueOnce(eventsResult);
eventLogClient.findEventsBySavedObjectIds.mockResolvedValueOnce(eventsResult);

const dateStart = new Date(Date.now() - 60 * 1000).toISOString();

Expand Down Expand Up @@ -188,18 +188,20 @@ describe('getAlertInstanceSummary()', () => {

test('calls saved objects and event log client with default params', async () => {
unsecuredSavedObjectsClient.get.mockResolvedValueOnce(getAlertInstanceSummarySavedObject());
eventLogClient.findEventsBySavedObject.mockResolvedValueOnce(
eventLogClient.findEventsBySavedObjectIds.mockResolvedValueOnce(
AlertInstanceSummaryFindEventsResult
);

await alertsClient.getAlertInstanceSummary({ id: '1' });

expect(unsecuredSavedObjectsClient.get).toHaveBeenCalledTimes(1);
expect(eventLogClient.findEventsBySavedObject).toHaveBeenCalledTimes(1);
expect(eventLogClient.findEventsBySavedObject.mock.calls[0]).toMatchInlineSnapshot(`
expect(eventLogClient.findEventsBySavedObjectIds).toHaveBeenCalledTimes(1);
expect(eventLogClient.findEventsBySavedObjectIds.mock.calls[0]).toMatchInlineSnapshot(`
Array [
"alert",
"1",
Array [
"1",
],
Object {
"end": "2019-02-12T21:01:22.479Z",
"page": 1,
Expand All @@ -210,7 +212,7 @@ describe('getAlertInstanceSummary()', () => {
]
`);
// calculate the expected start/end date for one test
const { start, end } = eventLogClient.findEventsBySavedObject.mock.calls[0][2]!;
const { start, end } = eventLogClient.findEventsBySavedObjectIds.mock.calls[0][2]!;
expect(end).toBe(mockedDateString);

const startMillis = Date.parse(start!);
Expand All @@ -222,7 +224,7 @@ describe('getAlertInstanceSummary()', () => {

test('calls event log client with start date', async () => {
unsecuredSavedObjectsClient.get.mockResolvedValueOnce(getAlertInstanceSummarySavedObject());
eventLogClient.findEventsBySavedObject.mockResolvedValueOnce(
eventLogClient.findEventsBySavedObjectIds.mockResolvedValueOnce(
AlertInstanceSummaryFindEventsResult
);

Expand All @@ -232,8 +234,8 @@ describe('getAlertInstanceSummary()', () => {
await alertsClient.getAlertInstanceSummary({ id: '1', dateStart });

expect(unsecuredSavedObjectsClient.get).toHaveBeenCalledTimes(1);
expect(eventLogClient.findEventsBySavedObject).toHaveBeenCalledTimes(1);
const { start, end } = eventLogClient.findEventsBySavedObject.mock.calls[0][2]!;
expect(eventLogClient.findEventsBySavedObjectIds).toHaveBeenCalledTimes(1);
const { start, end } = eventLogClient.findEventsBySavedObjectIds.mock.calls[0][2]!;

expect({ start, end }).toMatchInlineSnapshot(`
Object {
Expand All @@ -245,16 +247,16 @@ describe('getAlertInstanceSummary()', () => {

test('calls event log client with relative start date', async () => {
unsecuredSavedObjectsClient.get.mockResolvedValueOnce(getAlertInstanceSummarySavedObject());
eventLogClient.findEventsBySavedObject.mockResolvedValueOnce(
eventLogClient.findEventsBySavedObjectIds.mockResolvedValueOnce(
AlertInstanceSummaryFindEventsResult
);

const dateStart = '2m';
await alertsClient.getAlertInstanceSummary({ id: '1', dateStart });

expect(unsecuredSavedObjectsClient.get).toHaveBeenCalledTimes(1);
expect(eventLogClient.findEventsBySavedObject).toHaveBeenCalledTimes(1);
const { start, end } = eventLogClient.findEventsBySavedObject.mock.calls[0][2]!;
expect(eventLogClient.findEventsBySavedObjectIds).toHaveBeenCalledTimes(1);
const { start, end } = eventLogClient.findEventsBySavedObjectIds.mock.calls[0][2]!;

expect({ start, end }).toMatchInlineSnapshot(`
Object {
Expand All @@ -266,7 +268,7 @@ describe('getAlertInstanceSummary()', () => {

test('invalid start date throws an error', async () => {
unsecuredSavedObjectsClient.get.mockResolvedValueOnce(getAlertInstanceSummarySavedObject());
eventLogClient.findEventsBySavedObject.mockResolvedValueOnce(
eventLogClient.findEventsBySavedObjectIds.mockResolvedValueOnce(
AlertInstanceSummaryFindEventsResult
);

Expand All @@ -280,7 +282,7 @@ describe('getAlertInstanceSummary()', () => {

test('saved object get throws an error', async () => {
unsecuredSavedObjectsClient.get.mockRejectedValueOnce(new Error('OMG!'));
eventLogClient.findEventsBySavedObject.mockResolvedValueOnce(
eventLogClient.findEventsBySavedObjectIds.mockResolvedValueOnce(
AlertInstanceSummaryFindEventsResult
);

Expand All @@ -291,7 +293,7 @@ describe('getAlertInstanceSummary()', () => {

test('findEvents throws an error', async () => {
unsecuredSavedObjectsClient.get.mockResolvedValueOnce(getAlertInstanceSummarySavedObject());
eventLogClient.findEventsBySavedObject.mockRejectedValueOnce(new Error('OMG 2!'));
eventLogClient.findEventsBySavedObjectIds.mockRejectedValueOnce(new Error('OMG 2!'));

// error eaten but logged
await alertsClient.getAlertInstanceSummary({ id: '1' });
Expand Down
6 changes: 5 additions & 1 deletion x-pack/plugins/alerts/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
ILegacyClusterClient,
StatusServiceSetup,
ServiceStatus,
SavedObjectsBulkGetObject,
} from '../../../../src/core/server';

import {
Expand Down Expand Up @@ -370,7 +371,10 @@ export class AlertingPlugin {

this.eventLogService!.registerSavedObjectProvider('alert', (request) => {
const client = getAlertsClientWithRequest(request);
return (type: string, id: string) => client.get({ id });
return (objects?: SavedObjectsBulkGetObject[]) =>
objects
? Promise.all(objects.map(async (objectItem) => await client.get({ id: objectItem.id })))
: Promise.resolve([]);
});

scheduleAlertingTelemetry(this.telemetryLogger, plugins.taskManager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const createClusterClientMock = () => {
createIndexTemplate: jest.fn(),
doesAliasExist: jest.fn(),
createIndex: jest.fn(),
queryEventsBySavedObject: jest.fn(),
queryEventsBySavedObjects: jest.fn(),
shutdown: jest.fn(),
};
return mock;
Expand Down
52 changes: 26 additions & 26 deletions x-pack/plugins/event_log/server/es/cluster_client_adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,11 +327,11 @@ describe('queryEventsBySavedObject', () => {
total: { value: 0 },
},
});
await clusterClientAdapter.queryEventsBySavedObject(
await clusterClientAdapter.queryEventsBySavedObjects(
'index-name',
'namespace',
'saved-object-type',
'saved-object-id',
['saved-object-id'],
DEFAULT_OPTIONS
);

Expand Down Expand Up @@ -365,10 +365,10 @@ describe('queryEventsBySavedObject', () => {
},
},
Object {
"term": Object {
"kibana.saved_objects.id": Object {
"value": "saved-object-id",
},
"terms": Object {
"kibana.saved_objects.id": Array [
"saved-object-id",
],
},
},
Object {
Expand Down Expand Up @@ -406,11 +406,11 @@ describe('queryEventsBySavedObject', () => {
total: { value: 0 },
},
});
await clusterClientAdapter.queryEventsBySavedObject(
await clusterClientAdapter.queryEventsBySavedObjects(
'index-name',
undefined,
'saved-object-type',
'saved-object-id',
['saved-object-id'],
DEFAULT_OPTIONS
);

Expand Down Expand Up @@ -444,10 +444,10 @@ describe('queryEventsBySavedObject', () => {
},
},
Object {
"term": Object {
"kibana.saved_objects.id": Object {
"value": "saved-object-id",
},
"terms": Object {
"kibana.saved_objects.id": Array [
"saved-object-id",
],
},
},
Object {
Expand Down Expand Up @@ -487,11 +487,11 @@ describe('queryEventsBySavedObject', () => {
total: { value: 0 },
},
});
await clusterClientAdapter.queryEventsBySavedObject(
await clusterClientAdapter.queryEventsBySavedObjects(
'index-name',
'namespace',
'saved-object-type',
'saved-object-id',
['saved-object-id'],
{ ...DEFAULT_OPTIONS, sort_field: 'event.end', sort_order: 'desc' }
);

Expand All @@ -515,11 +515,11 @@ describe('queryEventsBySavedObject', () => {

const start = '2020-07-08T00:52:28.350Z';

await clusterClientAdapter.queryEventsBySavedObject(
await clusterClientAdapter.queryEventsBySavedObjects(
'index-name',
'namespace',
'saved-object-type',
'saved-object-id',
['saved-object-id'],
{ ...DEFAULT_OPTIONS, start }
);

Expand Down Expand Up @@ -553,10 +553,10 @@ describe('queryEventsBySavedObject', () => {
},
},
Object {
"term": Object {
"kibana.saved_objects.id": Object {
"value": "saved-object-id",
},
"terms": Object {
"kibana.saved_objects.id": Array [
"saved-object-id",
],
},
},
Object {
Expand Down Expand Up @@ -605,11 +605,11 @@ describe('queryEventsBySavedObject', () => {
const start = '2020-07-08T00:52:28.350Z';
const end = '2020-07-08T00:00:00.000Z';

await clusterClientAdapter.queryEventsBySavedObject(
await clusterClientAdapter.queryEventsBySavedObjects(
'index-name',
'namespace',
'saved-object-type',
'saved-object-id',
['saved-object-id'],
{ ...DEFAULT_OPTIONS, start, end }
);

Expand Down Expand Up @@ -643,10 +643,10 @@ describe('queryEventsBySavedObject', () => {
},
},
Object {
"term": Object {
"kibana.saved_objects.id": Object {
"value": "saved-object-id",
},
"terms": Object {
"kibana.saved_objects.id": Array [
"saved-object-id",
],
},
},
Object {
Expand Down
13 changes: 6 additions & 7 deletions x-pack/plugins/event_log/server/es/cluster_client_adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,11 @@ export class ClusterClientAdapter {
}
}

public async queryEventsBySavedObject(
public async queryEventsBySavedObjects(
index: string,
namespace: string | undefined,
type: string,
id: string,
ids: string[],
// eslint-disable-next-line @typescript-eslint/naming-convention
{ page, per_page: perPage, start, end, sort_field, sort_order }: FindOptionsType
): Promise<QueryEventsBySavedObjectResult> {
Expand Down Expand Up @@ -249,10 +249,9 @@ export class ClusterClientAdapter {
},
},
{
term: {
'kibana.saved_objects.id': {
value: id,
},
terms: {
// default maximum of 65,536 terms, configurable by index.max_terms_count
'kibana.saved_objects.id': ids,
},
},
namespaceQuery,
Expand Down Expand Up @@ -298,7 +297,7 @@ export class ClusterClientAdapter {
};
} catch (err) {
throw new Error(
`querying for Event Log by for type "${type}" and id "${id}" failed with: ${err.message}`
`querying for Event Log by for type "${type}" and ids "${ids}" failed with: ${err.message}`
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/event_log/server/event_log_client.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { IEventLogClient } from './types';

const createEventLogClientMock = () => {
const mock: jest.Mocked<IEventLogClient> = {
findEventsBySavedObject: jest.fn(),
findEventsBySavedObjectIds: jest.fn(),
};
return mock;
};
Expand Down
Loading