Skip to content

Commit

Permalink
Incorporating action subgroups into logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ymao1 committed Dec 10, 2020
1 parent 38bd887 commit b2f6610
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 21 deletions.
77 changes: 67 additions & 10 deletions x-pack/plugins/alerts/server/alert_instance/alert_instance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ describe('isThrottled', () => {
});
});

describe('actionGroupHasChanged()', () => {
describe('scheduledActionGroupOrSubgroupHasChanged()', () => {
test('should be false if no last scheduled and nothing scheduled', () => {
const alertInstance = new AlertInstance();
expect(alertInstance.actionGroupHasChanged()).toEqual(false);
expect(alertInstance.scheduledActionGroupOrSubgroupHasChanged()).toEqual(false);
});

test('should be false if group does not change', () => {
Expand All @@ -88,16 +88,24 @@ describe('actionGroupHasChanged()', () => {
},
});
alertInstance.scheduleActions('default');
expect(alertInstance.actionGroupHasChanged()).toEqual(false);
expect(alertInstance.scheduledActionGroupOrSubgroupHasChanged()).toEqual(false);
});

test('should be true if no last scheduled and group is scheduled', () => {
const alertInstance = new AlertInstance();
alertInstance.scheduleActions('default');
expect(alertInstance.actionGroupHasChanged()).toEqual(true);
test('should be false if group and subgroup does not change', () => {
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
group: 'default',
subgroup: 'subgroup',
},
},
});
alertInstance.scheduleActionsWithSubGroup('default', 'subgroup');
expect(alertInstance.scheduledActionGroupOrSubgroupHasChanged()).toEqual(false);
});

test('should be true if last scheduled group and next action is undefined', () => {
test('should be false if group does not change and subgroup goes from undefined to defined', () => {
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
Expand All @@ -106,7 +114,28 @@ describe('actionGroupHasChanged()', () => {
},
},
});
expect(alertInstance.actionGroupHasChanged()).toEqual(true);
alertInstance.scheduleActionsWithSubGroup('default', 'subgroup');
expect(alertInstance.scheduledActionGroupOrSubgroupHasChanged()).toEqual(false);
});

test('should be false if group does not change and subgroup goes from defined to undefined', () => {
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
group: 'default',
subgroup: 'subgroup',
},
},
});
alertInstance.scheduleActions('default');
expect(alertInstance.scheduledActionGroupOrSubgroupHasChanged()).toEqual(false);
});

test('should be true if no last scheduled and has scheduled action', () => {
const alertInstance = new AlertInstance();
alertInstance.scheduleActions('default');
expect(alertInstance.scheduledActionGroupOrSubgroupHasChanged()).toEqual(true);
});

test('should be true if group does change', () => {
Expand All @@ -119,7 +148,35 @@ describe('actionGroupHasChanged()', () => {
},
});
alertInstance.scheduleActions('penguin');
expect(alertInstance.actionGroupHasChanged()).toEqual(true);
expect(alertInstance.scheduledActionGroupOrSubgroupHasChanged()).toEqual(true);
});

test('should be true if group does change and subgroup does change', () => {
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
group: 'default',
subgroup: 'subgroup',
},
},
});
alertInstance.scheduleActionsWithSubGroup('penguin', 'fish');
expect(alertInstance.scheduledActionGroupOrSubgroupHasChanged()).toEqual(true);
});

test('should be true if group does not change and subgroup does change', () => {
const alertInstance = new AlertInstance({
meta: {
lastScheduledActions: {
date: new Date(),
group: 'default',
subgroup: 'subgroup',
},
},
});
alertInstance.scheduleActionsWithSubGroup('default', 'fish');
expect(alertInstance.scheduledActionGroupOrSubgroupHasChanged()).toEqual(true);
});
});

Expand Down
28 changes: 19 additions & 9 deletions x-pack/plugins/alerts/server/alert_instance/alert_instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,28 @@ export class AlertInstance<
}

scheduledActionGroupOrSubgroupHasChanged(): boolean {
return (
!!this.meta.lastScheduledActions &&
!!this.scheduledExecutionOptions &&
(!this.scheduledActionGroupIsUnchanged(
this.meta.lastScheduledActions,
this.scheduledExecutionOptions
) ||
if (!this.meta.lastScheduledActions && this.scheduledExecutionOptions) {
// it is considered a change when there are no previous scheduled actions
// and new scheduled actions
return true;
}

if (this.meta.lastScheduledActions && this.scheduledExecutionOptions) {
// compare previous and new scheduled actions if both exist
return (
!this.scheduledActionGroupIsUnchanged(
this.meta.lastScheduledActions,
this.scheduledExecutionOptions
) ||
!this.scheduledActionSubgroupIsUnchanged(
this.meta.lastScheduledActions,
this.scheduledExecutionOptions
))
);
)
);
}

// no previous and no new scheduled actions
return false;
}

private scheduledActionGroupIsUnchanged(
Expand Down
61 changes: 60 additions & 1 deletion x-pack/plugins/alerts/server/task_runner/task_runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,66 @@ describe('Task Runner', () => {
);
const taskRunner = new TaskRunner(
alertType,
mockedTaskInstance,
{
...mockedTaskInstance,
state: {
...mockedTaskInstance.state,
alertInstances: {
'1': {
meta: { lastScheduledActions: { group: 'newGroup', date: new Date().toISOString() } },
state: { bar: false },
},
},
},
},
taskRunnerFactoryInitializerParams
);
alertsClient.get.mockResolvedValue({
...mockedAlertTypeSavedObject,
notifyWhen: 'onActionGroupChange',
});
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue({
id: '1',
type: 'alert',
attributes: {
apiKey: Buffer.from('123:abc').toString('base64'),
},
references: [],
});
await taskRunner.run();
expect(actionsClient.enqueueExecution).toHaveBeenCalledTimes(1);
});

test('actionsPlugin.execute is called when notifyWhen=onActionGroupChange and alert instance state subgroup has changed', async () => {
taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true);
taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true);
alertType.executor.mockImplementation(
({ services: executorServices }: AlertExecutorOptions) => {
executorServices
.alertInstanceFactory('1')
.scheduleActionsWithSubGroup('default', 'subgroup1');
}
);
const taskRunner = new TaskRunner(
alertType,
{
...mockedTaskInstance,
state: {
...mockedTaskInstance.state,
alertInstances: {
'1': {
meta: {
lastScheduledActions: {
group: 'default',
subgroup: 'newSubgroup',
date: new Date().toISOString(),
},
},
state: { bar: false },
},
},
},
},
taskRunnerFactoryInitializerParams
);
alertsClient.get.mockResolvedValue({
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/alerts/server/task_runner/task_runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ export class TaskRunner {
notifyWhen === 'onActionGroupChange'
? Object.entries(instancesWithScheduledActions).filter(
([alertInstanceName, alertInstance]: [string, AlertInstance]) => {
const shouldExecuteAction = alertInstance.actionGroupHasChanged();
const shouldExecuteAction = alertInstance.scheduledActionGroupOrSubgroupHasChanged();
if (!shouldExecuteAction) {
this.logger.debug(
`skipping scheduling of actions for '${alertInstanceName}' in alert ${alertLabel}: instance is active but action group has not changed`
Expand Down

0 comments on commit b2f6610

Please sign in to comment.