Name
sn_em_arm.EvtMgmtAlertMgmtAlertReopenHandler
Description
No description available
Script
gs.include('EvtMgmtIncidentHandler');
gs.include('EvtMgmtAlertMgmtCommons');
gs.include('EvtMgmtAlertMgmtProcess');
var EvtMgmtAlertMgmtAlertReopenHandler = Class.create();
EvtMgmtAlertMgmtAlertReopenHandler.prototype = {
type: 'EvtMgmtAlertMgmtAlertReopenHandler',
initialize: function() {
this.evtMgmtCommons = new global.EvtMgmtCommons();
this.evtMgmtAlertMgmtMediator = new global.EvtMgmtAlertMgmtMediator();
this.evtMgmtAlertMgmtCommons = new EvtMgmtAlertMgmtCommons();
this.evtMgmtAlertMgmtProcess = new EvtMgmtAlertMgmtProcess();
},
onAlertReopen: function(current) {
// This rule runs when a closed alert is reopened or goes into flapping for a new event
// It checks if the associated task is in the resolved or closed state
// If it is, then it can reopen that task or create a new one (checks the property alert_reopens_incident)
// If not, it just adds a comment on the task
var alertNumber = current.number;
var task = new GlideRecord("task");
task.get(current.incident);
var type;
var gr = new GlideRecord("em_task_type_choices");
gr.addQuery("type", task.sys_class_name);
gr.query();
if (!gr.next())
type = "task";
else
type = task.sys_class_name;
if (type != "task") {
task = new GlideRecord(type);
task.get(current.incident);
}
gr.initialize();
gr.addQuery("type", type);
var qc = gr.addQuery("state", "2");
qc.addOrCondition("state", "3");
gr.query();
var resolved, closed;
if (gr.next())
resolved = gr.getValue('value');
if (gr.next())
closed = gr.getValue('value');
var taskNumber = task.number;
var taskState = task.state;
// Task is Resolved or Closed
if (resolved == taskState || closed == taskState) {
var property = gs.getProperty('evt_mgmt.alert_reopens_incident');
var manualIncident = this.incidentCreatedManually(task);
if (property == 'reopen')
this.handleReopen(current, alertNumber, manualIncident, taskNumber, task);
else if (property == 'new')
this.handleNew(current, alertNumber, manualIncident, type, task, taskNumber);
else if (property == 'nothing') {
// do nothing
}
} else {
// Incident is still open, just add a comment to it
this.updateWorkNoteField(task, gs.getMessage("The related alert {0} state is now {1}", [alertNumber, current.state]));
task.update();
}
},
incidentCreatedManually: function(task) {
// backdoor to disable the feature for backward support
if ('true' == gs.getProperty('evt_mgmt.always_reopen_incident', 'false'))
return true;
var toReopen = false;
var incidentCreatedByUser = "" + task.sys_created_by;
var jobUser = this.evtMgmtAlertMgmtMediator.getIncidentCreatingJobUser();
// manually created incidents should be opened without additional checks
return (incidentCreatedByUser != jobUser);
},
createNewTaskByAlertRules: function(current) {
// create task with admin user - to be same as the one created by job
var jobUser = this.evtMgmtAlertMgmtMediator.getIncidentCreatingJobUser();
var originalUser = this.evtMgmtAlertMgmtMediator.setSessionUser(jobUser);
var createdTask = global.EvtMgmtIncidentHandler.createIncidentNoUpdate(current, true);
this.evtMgmtAlertMgmtMediator.setSessionUser(originalUser);
return createdTask;
},
updateWorkNoteField: function(gr, comments) {
//TODO- if this is the task and not the alert, should it ne regular update???
this.evtMgmtAlertMgmtMediator.updateWorkNotesOnAlert(gr, comments);
},
addWorkNoteAndClearTaskIfNeed: function(current, taskNumber) {
var propertyIncidentClosesAert = gs.getProperty('evt_mgmt.incident_closes_alert');
if (propertyIncidentClosesAert == 'true') {
// cleanup the incident - no matching alert rule and it is not manual created incident
// we should clear it to avoid inconsistent situation
// when opened alert has closed incident
this.updateWorkNoteField(
current,
gs.getMessage("Connected incident {0} is in Resolved state while the alert is Reopend. There is no matching alert rule to reopen the incident. Disconnecting the incident from the alert.", [taskNumber]));
current.incident = "";
} else {
this.updateWorkNoteField(
current,
gs.getMessage("Connected incident {0} is in Resolved state while the alert is Reopend. There is no matching alert rule to reopen the incident.", [taskNumber]));
}
this.evtMgmtAlertMgmtMediator.currentUpdateWithoutRecursiveCalls(current);
},
reopen: function(current, taskNumber, task) {
// Reopen incident
task.state = '1'; // New state
this.updateWorkNoteField(task, gs.getMessage("The related alert {0} state is now {1}", [current.number, current.state]));
task.state = '1';
task.update();
},
getAlertManagementExecutionByAlert: function(alertGR) {
//Using Alert rules management
if (gs.getProperty('evt_mgmt.alert.management.activated', false) === 'true') {
//Worng input, can't find esecution
if ((!alertGR) || (!alertGR.getUniqueValue()) || (!alertGR.incident))
return null;
var executionGR = new GlideRecord("em_alert_management_execution");
executionGR.addQuery('alert', alertGR.getUniqueValue());
executionGR.addQuery('related_task', alertGR.incident);
executionGR.orderByDesc('sys_created_on');
executionGR.setLimit(1);
executionGR.query();
if (executionGR.next()) {
return executionGR;
}
}
return null;
},
isManualExecution: function(manualIncidentByUserID, amExecutionGR) {
// backdoor to disable the feature for backward support
if ('true' == gs.getProperty('evt_mgmt.always_reopen_incident', 'false'))
return true;
if (amExecutionGR == null) {
//No execution- treat like legacy
return manualIncidentByUserID;
} else {
//there is an am execution, make sure it's marked as manual
return amExecutionGR.automatic_run == "0";
}
},
alertMatchеsAlertManagementRules: function(alertGR, executionGR) {
//Using Alert rules management
if (gs.getProperty('evt_mgmt.alert.management.activated', false) === 'true') {
if (executionGR != null) { //no execution, should treat like legacy alert
var rule = this.evtMgmtAlertMgmtCommons.getRuleFromCacheByID(executionGR.management_rule);
if (this.alertMatchesRuleFilterNoInt(alertGR, rule)) {
return true;
} else {
return false;
}
}
}
return this.alertMatchеsLegacyRules(alertGR);
},
/**
Checks rather alert matches the rule's filter- remove the int before doing that...
*/
alertMatchesRuleFilterNoInt: function(alertGR, rule) {
var oldTask = alertGR.incident + "";
alertGR.incident = "";
var filterRes = this.evtMgmtAlertMgmtProcess.checkFilter(alertGR, rule);
alertGR.incident = oldTask;
return filterRes;
},
alertMatchеsLegacyRules: function(alert) {
if (gs.getProperty('evt_mgmt.alert.management.enable_legacy_alert_action_rules', 'true') == 'true') { // if property is turned on, used to disable legacy alert rules where not needed
// automatically created incidents should be opened only if the alert match alert rules
var rule = global.EvtMgmtIncidentHandler.locateRule(alert, true);
return (rule != null);
}
return false;
},
handleReopen: function(current, alertNumber, manualIncidentByUserID, taskNumber, task) {
// if alert rules are matched or the incedent was created manually,
// Reopen incident
var amExecutionGR = this.getAlertManagementExecutionByAlert(current);
if (this.isManualExecution(manualIncidentByUserID, amExecutionGR)) {
this.reopen(current, taskNumber, task);
} else {
var ruleMatched = this.alertMatchеsAlertManagementRules(current, amExecutionGR);
if (ruleMatched) {
this.reopen(current, taskNumber, task);
} else {
// no matched rule, and incident was created by Job,
// the incident should not be reopened
this.addWorkNoteAndClearTaskIfNeed(current, taskNumber);
}
}
},
createNew: function(current, alertNumber, newTask, taskNumber, type, task) {
// Create a new one and copy fields from the old one here
newTask.initialize();
// Copy all fields into newIncident
var fields = task.getElements();
var fieldsToIgnore = gs.getProperty('evt_mgmt.open_new_incident_ignore_fields', 'number,state,opened_at');
fieldsToIgnore = fieldsToIgnore.replace(/ /g, ''); //remove all spaces
var fieldsToIgnoreArr = JSON.stringify(fieldsToIgnore.split(","));
for (var i = 0; i < fields.length; ++i) {
var ele = fields[i];
if ((typeof ele.getName() == "undefined") ||ele.getName() == "active"|| (((ele.getName() +"").startsWith("sys_")) && (!((ele.getName() +"").startsWith("sys_domain")))) || fieldsToIgnoreArr.includes(ele.getName())){
continue;
}
newTask.setValue(ele.getName(), ele);
}
// Add comments on new incident
this.updateWorkNoteField(newTask, gs.getMessage("The related alert {0} is now unlinked from the previous {1} {2}", [alertNumber, type, taskNumber]));
newTaskId = newTask.insert();
current.incident = newTaskId;
},
handleNew: function(current, alertNumber, manualIncidentByUserID, type, task, taskNumber) {
// Create a new task and update comments on the task
// about the alert's previous task being unlinked
var newTaskId;
var newTask = new GlideRecord(type);
var createdTask;
var amExecutionGR = this.getAlertManagementExecutionByAlert(current);
if (this.isManualExecution(manualIncidentByUserID, amExecutionGR)) {
// Create a new one and copy fields from the old one here
this.createNew(current, alertNumber, newTask, taskNumber, type, task);
createdTask = true;
} else {
if (amExecutionGR != null) { //int was created by an AM rule, we just remove the int field and let the job do the logic
createdTask = false;
this.updateWorkNoteField(task, gs.getMessage("The related alert {0} is now unlinked from the {1} {2}", [alertNumber, type, taskNumber]));
task.update();
this.updateWorkNoteField(current, gs.getMessage("Connected incident {0} is in Resolved state while the alert is Reopend. Disconnecting the incident from the alert.", [taskNumber]));
current.incident = "";
this.evtMgmtAlertMgmtMediator.currentUpdateWithoutRecursiveCalls(current);
} else {
createdTask = this.createNewTaskByAlertRules(current);
if (createdTask) {
// found matching alert rule and task was created
newTaskId = current.incident;
newTask.get(newTaskId);
// Add comments on new incident
this.updateWorkNoteField(newTask, gs.getMessage("The related alert {0} is now unlinked from the previous {1} {2}",
[alertNumber, type, taskNumber]));
newTask.update();
} else {
// no matched rule, and incident was created by Job, so the incident should not be reopened
this.addWorkNoteAndClearTaskIfNeed(current, taskNumber);
}
}
}
if (createdTask) {
var newTaskNumber = newTask.number;
// Add comments on old incident
this.updateWorkNoteField(task, gs.getMessage("The related alert {0} is now linked to a new {1} {2}", [alertNumber, type, newTaskNumber]));
task.update();
// Add comments on alert
this.updateWorkNoteField(current, gs.getMessage("The {0} number changed from {1} to {2}", [type, taskNumber, newTaskNumber]));
this.evtMgmtAlertMgmtMediator.currentUpdateWithoutRecursiveCalls(current);
}
},
};
Sys ID
8ff399e6b7d920107c038229ce11a9cc