Skip to content

Commit

Permalink
displays Alert Instance state on Alert Details page (#56842) (#57387)
Browse files Browse the repository at this point in the history
Adds a list of Alert Instances to the Alert Details page based off of the current state of the Alert.

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
gmmorris and elasticmachine authored Feb 12, 2020
1 parent 7339d02 commit 9017c99
Show file tree
Hide file tree
Showing 27 changed files with 1,398 additions and 180 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
*/

import { SavedObjectAttributes } from 'kibana/server';
import { AlertActionParams } from '../server/types';

export interface IntervalSchedule extends SavedObjectAttributes {
interval: string;
}

export type AlertActionParams = SavedObjectAttributes;

export interface AlertAction {
group: string;
id: string;
Expand Down
24 changes: 24 additions & 0 deletions x-pack/legacy/plugins/alerting/common/alert_instance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import * as t from 'io-ts';
import { DateFromString } from './date_from_string';

const metaSchema = t.partial({
lastScheduledActions: t.type({
group: t.string,
date: DateFromString,
}),
});
export type AlertInstanceMeta = t.TypeOf<typeof metaSchema>;

const stateSchema = t.record(t.string, t.unknown);
export type AlertInstanceState = t.TypeOf<typeof stateSchema>;

export const rawAlertInstance = t.partial({
state: stateSchema,
meta: metaSchema,
});
export type RawAlertInstance = t.TypeOf<typeof rawAlertInstance>;
26 changes: 26 additions & 0 deletions x-pack/legacy/plugins/alerting/common/alert_task_instance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import * as t from 'io-ts';
import { rawAlertInstance } from './alert_instance';
import { DateFromString } from './date_from_string';

export const alertStateSchema = t.partial({
alertTypeState: t.record(t.string, t.unknown),
alertInstances: t.record(t.string, rawAlertInstance),
previousStartedAt: t.union([t.null, DateFromString]),
});

export type AlertTaskState = t.TypeOf<typeof alertStateSchema>;

export const alertParamsSchema = t.intersection([
t.type({
alertId: t.string,
}),
t.partial({
spaceId: t.string,
}),
]);
export type AlertTaskParams = t.TypeOf<typeof alertParamsSchema>;
28 changes: 28 additions & 0 deletions x-pack/legacy/plugins/alerting/common/date_from_string.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { DateFromString } from './date_from_string';
import { right, isLeft } from 'fp-ts/lib/Either';

describe('DateFromString', () => {
test('validated and parses a string into a Date', () => {
const date = new Date(1973, 10, 30);
expect(DateFromString.decode(date.toISOString())).toEqual(right(date));
});

test('validated and returns a failure for an actual Date', () => {
const date = new Date(1973, 10, 30);
expect(isLeft(DateFromString.decode(date))).toEqual(true);
});

test('validated and returns a failure for an invalid Date string', () => {
expect(isLeft(DateFromString.decode('1234-23-45'))).toEqual(true);
});

test('validated and returns a failure for a null value', () => {
expect(isLeft(DateFromString.decode(null))).toEqual(true);
});
});
26 changes: 26 additions & 0 deletions x-pack/legacy/plugins/alerting/common/date_from_string.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import * as t from 'io-ts';
import { either } from 'fp-ts/lib/Either';

// represents a Date from an ISO string
export const DateFromString = new t.Type<Date, string, unknown>(
'DateFromString',
// detect the type
(value): value is Date => value instanceof Date,
(valueToDecode, context) =>
either.chain(
// validate this is a string
t.string.validate(valueToDecode, context),
// decode
value => {
const decoded = new Date(value);
return isNaN(decoded.getTime()) ? t.failure(valueToDecode, context) : t.success(decoded);
}
),
valueToEncode => valueToEncode.toISOString()
);
4 changes: 3 additions & 1 deletion x-pack/legacy/plugins/alerting/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/

export * from './types';
export * from './alert';
export * from './alert_instance';
export * from './alert_task_instance';
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,22 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import * as t from 'io-ts';
import {
AlertInstanceMeta,
AlertInstanceState,
RawAlertInstance,
rawAlertInstance,
} from '../../common';

import { State, Context } from '../types';
import { DateFromString } from '../lib/types';
import { parseDuration } from '../lib';

interface ScheduledExecutionOptions {
actionGroup: string;
context: Context;
state: State;
}

const metaSchema = t.partial({
lastScheduledActions: t.type({
group: t.string,
date: DateFromString,
}),
});
type AlertInstanceMeta = t.TypeOf<typeof metaSchema>;

const stateSchema = t.record(t.string, t.unknown);
type AlertInstanceState = t.TypeOf<typeof stateSchema>;

export const rawAlertInstance = t.partial({
state: stateSchema,
meta: metaSchema,
});
export type RawAlertInstance = t.TypeOf<typeof rawAlertInstance>;

export type AlertInstances = Record<string, AlertInstance>;
export class AlertInstance {
private scheduledExecutionOptions?: ScheduledExecutionOptions;
private meta: AlertInstanceMeta;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
* you may not use this file except in compliance with the Elastic License.
*/

export { AlertInstance, RawAlertInstance, rawAlertInstance } from './alert_instance';
export { AlertInstance } from './alert_instance';
export { createAlertInstanceFactory } from './create_alert_instance_factory';
3 changes: 2 additions & 1 deletion x-pack/legacy/plugins/alerting/server/alerts_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
AlertType,
IntervalSchedule,
SanitizedAlert,
AlertTaskState,
} from './types';
import { validateAlertTypeParams } from './lib';
import {
Expand All @@ -31,7 +32,7 @@ import {
} from '../../../../plugins/security/server';
import { EncryptedSavedObjectsPluginStart } from '../../../../plugins/encrypted_saved_objects/server';
import { TaskManagerStartContract } from '../../../../plugins/task_manager/server';
import { AlertTaskState, taskInstanceToAlertTaskInstance } from './task_runner/alert_task_instance';
import { taskInstanceToAlertTaskInstance } from './task_runner/alert_task_instance';

type NormalizedAlertAction = Omit<AlertAction, 'actionTypeId'>;
export type CreateAPIKeyResult =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,12 @@ import * as t from 'io-ts';
import { pipe } from 'fp-ts/lib/pipeable';
import { fold } from 'fp-ts/lib/Either';
import { ConcreteTaskInstance } from '../../../../../plugins/task_manager/server';
import { SanitizedAlert } from '../types';
import { DateFromString } from '../lib/types';
import { AlertInstance, rawAlertInstance } from '../alert_instance';
import { SanitizedAlert, AlertTaskState, alertParamsSchema, alertStateSchema } from '../../common';

export interface AlertTaskInstance extends ConcreteTaskInstance {
state: AlertTaskState;
}

export const alertStateSchema = t.partial({
alertTypeState: t.record(t.string, t.unknown),
alertInstances: t.record(t.string, rawAlertInstance),
previousStartedAt: t.union([t.null, DateFromString]),
});
export type AlertInstances = Record<string, AlertInstance>;
export type AlertTaskState = t.TypeOf<typeof alertStateSchema>;

const alertParamsSchema = t.intersection([
t.type({
alertId: t.string,
}),
t.partial({
spaceId: t.string,
}),
]);
export type AlertTaskParams = t.TypeOf<typeof alertParamsSchema>;

const enumerateErrorFields = (e: t.Errors) =>
`${e.map(({ context }) => context.map(({ key }) => key).join('.'))}`;

Expand Down
17 changes: 11 additions & 6 deletions x-pack/legacy/plugins/alerting/server/task_runner/task_runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,21 @@ import { SavedObject } from '../../../../../../src/core/server';
import { TaskRunnerContext } from './task_runner_factory';
import { ConcreteTaskInstance } from '../../../../../plugins/task_manager/server';
import { createExecutionHandler } from './create_execution_handler';
import { AlertInstance, createAlertInstanceFactory, RawAlertInstance } from '../alert_instance';
import { AlertInstance, createAlertInstanceFactory } from '../alert_instance';
import { getNextRunAt } from './get_next_run_at';
import { validateAlertTypeParams } from '../lib';
import { AlertType, RawAlert, IntervalSchedule, Services, AlertInfoParams } from '../types';
import { promiseResult, map, Resultable, asOk, asErr, resolveErr } from '../lib/result_type';
import {
AlertType,
RawAlert,
IntervalSchedule,
Services,
AlertInfoParams,
RawAlertInstance,
AlertTaskState,
AlertInstances,
taskInstanceToAlertTaskInstance,
} from './alert_task_instance';
} from '../types';
import { promiseResult, map, Resultable, asOk, asErr, resolveErr } from '../lib/result_type';
import { taskInstanceToAlertTaskInstance } from './alert_task_instance';
import { AlertInstances } from '../alert_instance/alert_instance';

const FALLBACK_RETRY_INTERVAL: IntervalSchedule = { interval: '5m' };

Expand Down
5 changes: 1 addition & 4 deletions x-pack/legacy/plugins/alerting/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import { AlertInstance } from './alert_instance';
import { AlertTypeRegistry as OrigAlertTypeRegistry } from './alert_type_registry';
import { PluginSetupContract, PluginStartContract } from './plugin';
import { SavedObjectAttributes, SavedObjectsClientContract } from '../../../../../src/core/server';
import { Alert } from '../common';

import { Alert, AlertActionParams } from '../common';
export * from '../common';

export type State = Record<string, any>;
Expand Down Expand Up @@ -53,8 +52,6 @@ export interface AlertType {
executor: ({ services, params, state }: AlertExecutorOptions) => Promise<State | void>;
}

export type AlertActionParams = SavedObjectAttributes;

export interface RawAlertAction extends SavedObjectAttributes {
group: string;
actionRef: string;
Expand Down
Loading

0 comments on commit 9017c99

Please sign in to comment.