Name
sn_cimaf.CIMetricStagingUtilSNC
Description
No description available
Script
var CIMetricStagingUtilSNC = Class.create();
CIMetricStagingUtilSNC.prototype = {
initialize: function() {},
TABLES: {
METRIC_STAGING: 'sn_cimaf_metric_staging',
ADAPTER_CONFIGURATION: 'sn_cimaf_adapter_config',
SYS_HUB_FLOW: 'sys_hub_flow'
},
FIELDS: {
BATCH_ID: 'batch_id',
PAYLOAD: 'payload',
REQUEST_ID: 'request_id',
STATE: 'state',
METRIC: 'metric',
METRIC_DEFINITION: 'metric_definition',
CONFIGURATION_ITEM: 'configuration_item',
ADAPTER_CONFIG: 'adapter_config',
TRANSFORM_FLOW: 'transform_flow',
TRANSFORM_SCRIPT: 'transform_script',
SYS_ID: 'sys_id',
INTERNAL_NAME: 'internal_name',
SYS_SCOPE: 'sys_scope',
SCOPE: 'scope',
PROVIDER: 'provider',
TRANSFORM_ACTION: 'transform_action',
TIMESTAMP: 'timestamp',
SYS_CREATED_ON: 'sys_created_on'
},
STAGING_STATES: {
IN_PROGRESS: "in_progress",
COMPLETED: "completed",
FAILED: "failed"
},
TRANSFORM_ACTIONS: {
FLOW: 'flow',
SCRIPT: 'script'
},
// returns batch id if a similar metric request is already in progress in the defined time limit
checkDuplicateRequestInProgress: function(ciSysId, metricDefSysId) {
var metricStagingGr = new GlideRecord(this.TABLES.METRIC_STAGING);
metricStagingGr.addQuery(this.FIELDS.STATE, this.STAGING_STATES.IN_PROGRESS);
metricStagingGr.addQuery(this.FIELDS.CONFIGURATION_ITEM, ciSysId);
metricStagingGr.addQuery(this.FIELDS.ADAPTER_CONFIG + '.' + this.FIELDS.METRIC_DEFINITION, metricDefSysId);
metricStagingGr.setLimit(1);
var timeLimit = gs.getProperty("sn_cimaf.metric_collection.duplicate_request_time_limit", 5);
metricStagingGr.addQuery(this.FIELDS.SYS_CREATED_ON + "RELATIVEGT@minute@ago@" + timeLimit);
metricStagingGr.query();
if (metricStagingGr.next()) {
return metricStagingGr.getValue(this.FIELDS.BATCH_ID);
}
},
addStagingRecord: function(cmdbSysId, adapterConfigSysId, batchId, requestId) {
var metricStagingGr = new GlideRecord(this.TABLES.METRIC_STAGING);
metricStagingGr[this.FIELDS.BATCH_ID] = batchId;
metricStagingGr[this.FIELDS.REQUEST_ID] = requestId;
metricStagingGr[this.FIELDS.ADAPTER_CONFIG] = adapterConfigSysId;
metricStagingGr[this.FIELDS.CONFIGURATION_ITEM] = cmdbSysId;
metricStagingGr[this.FIELDS.STATE] = this.STAGING_STATES.IN_PROGRESS;
return metricStagingGr.insert();
},
updateStagingRecordWithRequestId: function(stagingSysId, requestId) {
var metricStagingGr = new GlideRecord(this.TABLES.METRIC_STAGING);
if (metricStagingGr.get(stagingSysId)) {
metricStagingGr.setValue(this.FIELDS.REQUEST_ID, requestId);
metricStagingGr.update();
}
},
updateStagingRecordByRequestId: function(requestId, payload /* JSON Object */ , timestamp /* GlideDateTime */ , provider /* optional */ ) {
var metricStagingGr = new GlideRecord(this.TABLES.METRIC_STAGING);
metricStagingGr.addQuery(this.FIELDS.REQUEST_ID, requestId);
if (provider) {
metricStagingGr.addQuery(this.FIELDS.ADAPTER_CONFIG + '.' + this.FIELDS.PROVIDER, provider);
}
metricStagingGr.query();
if (metricStagingGr.next()) {
this.updateStagingRecord(metricStagingGr, payload, timestamp);
}
},
updateStagingRecordById: function(stagingSysId, payload /* JSON Object */ , timestamp) {
var metricStagingGr = new GlideRecord(this.TABLES.METRIC_STAGING);
if (metricStagingGr.get(stagingSysId)) {
this.updateStagingRecord(metricStagingGr, payload, timestamp);
}
},
// Sets state 'completed'
updateStagingRecord: function(metricStagingGr, payload /* JSON Object */ , timestamp) {
if (!metricStagingGr || !metricStagingGr.isValidRecord())
return;
try {
payload = JSON.stringify(payload);
} catch (e) {
gs.error("updateStagingRecord: invalid payload object");
return;
}
if (!timestamp) { // some providers might not provide timestamp, in such case set current date time.
timestamp = new GlideDateTime();
}
metricStagingGr.setValue(this.FIELDS.STATE, this.STAGING_STATES.COMPLETED);
metricStagingGr.setValue(this.FIELDS.PAYLOAD, payload);
metricStagingGr.setValue(this.FIELDS.TIMESTAMP, timestamp.getValue());
metricStagingGr.update();
},
handleStagingErrorByRequestId: function(requestId, payload /* JSON Object */ , provider /* optional */ ) {
var metricStagingGr = new GlideRecord(this.TABLES.METRIC_STAGING);
metricStagingGr.addQuery(this.FIELDS.REQUEST_ID, requestId);
if (provider) {
metricStagingGr.addQuery(this.FIELDS.ADAPTER_CONFIG + '.' + this.FIELDS.PROVIDER, provider);
}
metricStagingGr.query();
if (metricStagingGr.next()) {
this.handleStagingError(metricStagingGr, payload);
}
},
handleStagingErrorById: function(stagingSysId, payload /* JSON Object */ ) {
var metricStagingGr = new GlideRecord(this.TABLES.METRIC_STAGING);
if (metricStagingGr.get(stagingSysId)) {
this.handleStagingError(metricStagingGr, payload);
}
},
// Sets state 'failed'
handleStagingError: function(metricStagingGr, payload /* JSON Object */ ) {
if (!metricStagingGr || !metricStagingGr.isValidRecord())
return;
try {
payload = JSON.stringify(payload);
} catch (e) {
gs.error("handleStagingError: invalid payload object");
return;
}
metricStagingGr.setValue(this.FIELDS.STATE, this.STAGING_STATES.FAILED);
metricStagingGr.setValue(this.FIELDS.PAYLOAD, payload);
metricStagingGr.update();
},
/*
* Check if all stagging records are either completed or failed (not in progress).
*/
canInitiateTransform: function(batchId) {
var metricStagingGr = new GlideRecord(this.TABLES.METRIC_STAGING);
metricStagingGr.addQuery(this.FIELDS.BATCH_ID, batchId);
metricStagingGr.addQuery(this.FIELDS.STATE, this.STAGING_STATES.IN_PROGRESS);
metricStagingGr.query();
return !metricStagingGr.hasNext();
},
getFlowName: function(flowSysId) {
if (!flowSysId)
return '';
var flowGr = new GlideRecord(this.TABLES.SYS_HUB_FLOW);
if (flowGr.get(flowSysId)) {
var sysScopeGr = flowGr[this.FIELDS.SYS_SCOPE].getRefRecord();
if (sysScopeGr && sysScopeGr.isValidRecord()) {
return sysScopeGr.getValue(this.FIELDS.SCOPE) + '.' + flowGr.getValue(this.FIELDS.INTERNAL_NAME);
}
}
return '';
},
initiateTransform: function(batchId, adapterConfigSysId) {
if (!batchId) {
gs.error("[initiateTransform] The batchId are null or invalid");
return;
}
var adapterConfigGr = new GlideRecord(this.TABLES.ADAPTER_CONFIGURATION);
if (!adapterConfigGr.get(adapterConfigSysId))
return;
var metricStagingGr = new GlideRecord(this.TABLES.METRIC_STAGING);
metricStagingGr.addQuery(this.FIELDS.BATCH_ID, batchId);
metricStagingGr.addQuery(this.FIELDS.STATE, this.STAGING_STATES.COMPLETED);
metricStagingGr.query();
if (!metricStagingGr.hasNext()) {
gs.info("[initiateTransform] All metric staging records are failed. batchId :: " + batchId);
return;
}
var transformAction = adapterConfigGr.getValue(this.FIELDS.TRANSFORM_ACTION);
var inputs = {
staging_records: metricStagingGr
};
var metricResult = {};
if (transformAction == this.TRANSFORM_ACTIONS.FLOW && global.JSUtil.notNil(adapterConfigGr.transform_flow)) {
var transformFlowName = this.getFlowName(adapterConfigGr.getValue(this.FIELDS.TRANSFORM_FLOW));
if (transformFlowName) {
var flowResult = sn_fd.FlowAPI.getRunner().subflow(transformFlowName).inForeground().withInputs(inputs).run();
metricResult = flowResult.getOutputs();
}
} else if (transformAction == this.TRANSFORM_ACTIONS.SCRIPT && global.JSUtil.notNil(adapterConfigGr.transform_script)) {
var transformScript = adapterConfigGr.getValue(this.FIELDS.TRANSFORM_SCRIPT);
if (transformScript) {
var evaluator = new GlideScopedEvaluator();
try {
metricResult = evaluator.evaluateScript(adapterConfigGr, this.FIELDS.TRANSFORM_SCRIPT, inputs);
} catch (e) {
gs.error("Error while executing the transform script defined at adapter: " + e);
}
}
} else if (global.JSUtil.notNil(adapterConfigGr.provider) && global.JSUtil.notNil(adapterConfigGr.provider.default_transform_flow)) {
var transformFlowName = this.getFlowName(adapterConfigGr.provider.default_transform_flow + '');
if (transformFlowName) {
var flowResult = sn_fd.FlowAPI.getRunner().subflow(transformFlowName).inForeground().withInputs(inputs).run();
metricResult = flowResult.getOutputs();
}
}
/*
* Create metric record using payload returned by flow or script.
*/
if (metricResult) {
var lastestStagingGr = new GlideRecord(this.TABLES.METRIC_STAGING);
lastestStagingGr.addQuery(this.FIELDS.BATCH_ID, batchId);
lastestStagingGr.addQuery(this.FIELDS.STATE, this.STAGING_STATES.COMPLETED);
lastestStagingGr.orderBy('timestamp');
lastestStagingGr.setLimit(1);
lastestStagingGr.query();
if (lastestStagingGr.next()) {
if (metricResult.payload) {
var metricSysId = new CIMetricEngine().createMetric(lastestStagingGr.configuration_item + "",
lastestStagingGr.adapter_config.metric_definition + "",
metricResult.payload,
lastestStagingGr.timestamp + "");
if (metricSysId) {
var failedStagingGr = new GlideRecord(this.TABLES.METRIC_STAGING);
failedStagingGr.addQuery(this.FIELDS.BATCH_ID, batchId);
failedStagingGr.addQuery(this.FIELDS.STATE, this.STAGING_STATES.FAILED);
failedStagingGr.query();
failedStagingGr.setValue('metric', metricSysId + '');
failedStagingGr.updateMultiple();
}
} else {
gr.error("initiateTransform:: transform flow/script result is expected to contain payload");
}
} else {
gs.info("[initiateTransform] All the stagging records in the batch [" + batchId + "] are errored out.");
}
/*
* All completed stagging records in the batch are deleted.
*/
metricStagingGr.deleteMultiple();
}
},
type: 'CIMetricStagingUtilSNC'
};
Sys ID
bf4dd692c34301104442a81c8640dd9a