Skip to content

Commit

Permalink
[FEATURE] Add composite monitor type opensearch-project#573
Browse files Browse the repository at this point in the history
Signed-off-by: Jovan Cvetkovic <[email protected]>
  • Loading branch information
jovancvetkovic3006 committed Jun 19, 2023
1 parent f6b39fe commit 2201c0e
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const MonitorsList = ({ monitors = [], options = [], values }) => {

updateMonitorOptions(newSelected);

onBlur(monitorIdx, form);
updateFormik(monitorIdx, form);
};

const updateMonitorOptions = (selected) => {
Expand All @@ -72,7 +72,7 @@ const MonitorsList = ({ monitors = [], options = [], values }) => {
setMonitorOptions([...newMonitorOptions]);
};

const onBlur = (monitorIdx, form) => {
const updateFormik = (monitorIdx, form) => {
form.setFieldTouched('associatedMonitors', true);
form.setFieldTouched(`associatedMonitor_${monitorIdx}`, true);
form.setFieldValue('associatedMonitors', Object.values(selectedOptions));
Expand Down Expand Up @@ -109,10 +109,11 @@ const MonitorsList = ({ monitors = [], options = [], values }) => {

updateMonitorOptions(newSelected);

onBlur(monitorIdx, form);
updateFormik(monitorIdx, form);
};

const isValid = () => Object.keys(selectedOptions).length > 1;

const validate = () => {
if (!isValid()) return 'Required.';
};
Expand Down Expand Up @@ -149,7 +150,7 @@ const MonitorsList = ({ monitors = [], options = [], values }) => {
!selectedOptions[monitorIdx],
placeholder: 'Select a monitor',
onChange: (options, field, form) => onChange(options, monitorIdx, form),
onBlur: (e, field, form) => onBlur(monitorIdx, form),
onBlur: (e, field, form) => updateFormik(monitorIdx, form),
options: monitorOptions,
singleSelection: { asPlainText: true },
selectedOptions: selectedOptions[monitorIdx]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ const ExpressionQuery = ({
const [usedExpressions, setUsedExpressions] = useState([]);

useEffect(() => {
debugger;
let expressions = [];
if (value?.length) {
let values = [...value];
Expand Down Expand Up @@ -164,10 +163,13 @@ const ExpressionQuery = ({
/>
);

const isValid = () => usedExpressions.length > 1;
const isValid = () => selections.length > 1 && usedExpressions.length > 1;

const validate = () => {
if (!isValid()) return 'At least two monitors should be selected.';
if (selections.length < 2)
return 'Trigger condition requires at least two associated monitors.';
if (usedExpressions.length < 2)
return 'Trigger condition requires at least two monitors selected.';
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,6 @@ export function compositeTriggerToFormik(trigger, monitor) {
severity,
condition: { script },
actions,
minTimeBetweenExecutions,
rollingWindowSize,
} = trigger[TRIGGER_TYPE.COMPOSITE_LEVEL];
const triggerUiMetadata = _.get(monitor, `ui_metadata.triggers[${name}]`);
return {
Expand All @@ -236,8 +234,6 @@ export function compositeTriggerToFormik(trigger, monitor) {
severity,
script,
actions: getExecutionPolicyActions(actions),
minTimeBetweenExecutions,
rollingWindowSize,
triggerConditions: triggerUiMetadata,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import React, { useEffect, useState } from 'react';
import {
EuiButton,
EuiSpacer,
Expand All @@ -22,6 +22,7 @@ import _ from 'lodash';
import { formikToTrigger } from '../CreateTrigger/utils/formikToTrigger';
import { backendErrorNotification } from '../../../../utils/helpers';
import { checkForError } from '../ConfigureActions/ConfigureActions';
import { TRIGGER_TYPE } from '../CreateTrigger/utils/constants';

const NotificationConfigDialog = ({
channel,
Expand All @@ -41,39 +42,53 @@ const NotificationConfigDialog = ({
...initialActionValues,
});

const fieldPath = 'triggerDefinitions[0]';
const [initialValues, setInitialValues] = useState({});

useEffect(() => {
setInitialValues({
subject_source: _.get(
triggerValues,
`${fieldPath}actions.${actionIndex}.subject_template.source`,
''
),
message_source: _.get(
triggerValues,
`${fieldPath}actions.${actionIndex}.message_template.source`,
''
),
throttle_enabled: _.get(
triggerValues,
`${fieldPath}actions.${actionIndex}.throttle_enabled`,
''
),
throttle_value: _.get(triggerValues, `${fieldPath}actions.${actionIndex}.throttle.value`, ''),
});
}, []);

const sendTestMessage = async (index) => {
const mon = _.cloneDeep(monitor);
const tv = _.cloneDeep(triggerValues);
let testTrigger = _.cloneDeep(formikToTrigger(tv, mon.ui_metadata)[triggerIndex]);
const monitorData = _.cloneDeep(monitor);
let testTrigger = _.cloneDeep(
formikToTrigger(triggerValues, monitorData.ui_metadata)[triggerIndex]
);

testTrigger = {
...testTrigger,
name: _.get(tv, 'triggerDefinitions[0].name', ''),
severity: _.get(tv, 'triggerDefinitions[0].severity', ''),
name: _.get(triggerValues, 'triggerDefinitions[0].name', ''),
severity: _.get(triggerValues, 'triggerDefinitions[0].severity', ''),
};
const action = _.get(testTrigger, `chained_alert_trigger.actions[${index}]`);
const action = _.get(testTrigger, `${TRIGGER_TYPE.COMPOSITE_LEVEL}.actions[${index}]`);
const condition = {
..._.get(testTrigger, 'chained_alert_trigger.condition'),
..._.get(testTrigger, `${TRIGGER_TYPE.COMPOSITE_LEVEL}.condition`),
script: { lang: 'painless', source: 'return true' },
};

let triggers = _.cloneDeep(testTrigger);

delete triggers.chained_alert_trigger;
delete triggers.min_time_between_executions;
delete triggers.rolling_window_size;
delete testTrigger[TRIGGER_TYPE.COMPOSITE_LEVEL];

_.set(triggers, 'actions', [action]);
_.set(triggers, 'condition', condition);
_.set(testTrigger, 'actions', [action]);
_.set(testTrigger, 'condition', condition);

const testMonitor = { ...monitor, triggers: [{ ...triggers }] };

// clean up actions and triggers
delete testMonitor.enabled_time;
delete testMonitor.last_update_time;
delete testMonitor.schema_version;
delete testMonitor.ui_metadata.composite_input;
delete testMonitor.ui_metadata.monitor_type;
const testMonitor = { ...monitor, triggers: [{ ...testTrigger }] };

try {
const response = await httpClient.post('../api/alerting/monitors/_execute', {
Expand All @@ -96,8 +111,17 @@ const NotificationConfigDialog = ({
}
};

const clearConfig = () => {
_.set(
triggerValues,
`${fieldPath}actions.${actionIndex}.subject_template.source`,
initialValues.subject_source
);
closeModal();
};

return (
<EuiModal onClose={() => closeModal()}>
<EuiModal onClose={() => clearConfig()}>
<EuiModalHeader>
<EuiModalHeaderTitle>
<h1>Configure notification</h1>
Expand All @@ -120,7 +144,7 @@ const NotificationConfigDialog = ({
/>
</EuiModalBody>
<EuiModalFooter>
<EuiButton onClick={() => closeModal()}>Close</EuiButton>
<EuiButton onClick={() => clearConfig()}>Close</EuiButton>
<EuiButton onClick={() => closeModal()} fill>
Update
</EuiButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const TriggerNotifications = ({
const onRemoveNotification = (idx) => {
const newActions = [...actions];
newActions.splice(idx, 1);
_.set(triggerValues, 'triggerDefinitions[0].actions', newActions);
setActions(newActions);
};

Expand Down
5 changes: 2 additions & 3 deletions public/pages/Monitors/containers/Monitors/utils/tableUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const columns = [
sortable: true,
textOnly: true,
render: (name, item) => (
<EuiLink data-test-subj={name} href={`${PLUGIN_NAME}#/monitors/${item.id}`}>
<EuiLink data-test-subj={name} href={`${PLUGIN_NAME}#/monitors/${item.id}?type=${item.type}`}>
{name}
</EuiLink>
),
Expand All @@ -39,8 +39,7 @@ export const columns = [
2. Monitors are created when security plugin is disabled, these will have empty User object.
(`monitor.user.name`, `monitor.user.roles` are empty )
3. Monitors are created when security plugin is enabled, these will have an User object. */
render: (_, item) =>
item.monitor.user && item.monitor.user.name ? item.monitor.user.name : '-',
render: (_, item) => (item.user && item.user.name ? item.user.name : '-'),
},
{
field: 'latestAlert',
Expand Down
2 changes: 0 additions & 2 deletions server/services/MonitorService.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ export default class MonitorService {
};
}

const filter = [{ term: { 'monitor.type': 'monitor' } }];
if (state !== 'all') {
const enabled = state === 'enabled';
filter.push({ term: { 'monitor.enabled': enabled } });
Expand All @@ -252,7 +251,6 @@ export default class MonitorService {
...monitorSortPageData,
query: {
bool: {
filter,
must,
},
},
Expand Down

0 comments on commit 2201c0e

Please sign in to comment.