Name
sn_em_ai.EvtMgmtGetServicesRelationsForCsdm
Description
No description available
Script
var EvtMgmtGetServicesRelationsForCsdm = Class.create();
EvtMgmtGetServicesRelationsForCsdm.prototype = {
initialize: function() {
this.slowStepManager = new global.SlowStepJSManager();
this.evtMgmtCommons = new global.EvtMgmtCommons();
this.debugLog = this.type + " script include: \n";
this.TABLES = {
PORTFOLIO: "spm_service_portfolio",
TAXONOMY_NODE: "spm_taxonomy_node",
TECHNICAL: "cmdb_ci_service_technical",
BUSINESS: "cmdb_ci_service_business",
OFFERING: "service_offering",
APP_SERVICE: "cmdb_ci_service_auto",
CI_RELATIONSHIPS: "cmdb_rel_ci"
};
this.FIELDS = {
PARENT: "parent",
SYS_ID: "sys_id",
NAME: "name",
SERVICE_CLASSIFICATION: "service_classification",
CHILD: "child",
TYPE: "type",
TAXONOMY: "spm_taxonomy_node",
PORTFOLIO: "spm_service_portfolio",
SERVICE_CLASS: "service_classification"
};
this.TYPES = {
ALL: "ROOT",
SERVICE_PORTFOLIO: "PO",
TAXONOMY_NODE: "TX",
BUSINESS_SERVICE: "BS",
TECHNICAL_SERVICE: "TS",
OFFERING: "OFFER",
APP_SERVICE: "APP"
};
this.RELATION_TYPES = {
DEPENDS_ON_USED_BY: "1a9cb166f1571100a92eb60da2bce5c5",
CONTAINS_CONTAINED_BY: "55c95bf6c0a8010e0118ec7056ebc54d"
};
this.taxonomyNodes = {};
this.portfolioNodes = {};
},
/*
returns the portfolios tree as object
*/
getPortfoliosTree: function() {
this.slowStepManager.setTopic("CSDM: Get Portfolios Tree");
this.getServices();
this.slowStepManager.startStep(this.type + ": getPortfoliosTree");
var output = this.createNode('0', gs.getMessage("All"), this.TYPES.ALL, []);
for (var key in this.portfolioNodes) {
if (this.portfolioNodes.hasOwnProperty(key)) {
output.children.push(this.portfolioNodes[key]);
}
}
this.slowStepManager.report();
return output;
},
getServices: function() {
this.slowStepManager.startStep(this.type + ": getServices");
var tables = [this.TABLES.TECHNICAL, this.TABLES.BUSINESS];
for (var table in tables) {
if (!tables.hasOwnProperty(table)) {
continue;
}
var serviceGr = new GlideRecord(tables[table]);
// if there isn't a taxonomy node then there is no service portfolio and the service shouldn't be displayed.
serviceGr.addNotNullQuery(this.FIELDS.TAXONOMY);
serviceGr.query();
while (serviceGr.next()) {
var serviceTaxonomyID = serviceGr.getValue(this.FIELDS.TAXONOMY);
var serviceId = serviceGr.getValue(this.FIELDS.SYS_ID);
var serviceName = serviceGr.getValue(this.FIELDS.NAME);
var serviceClass = serviceGr.getValue(this.FIELDS.SERVICE_CLASS);
var serviceType = (serviceClass == 'Business Service') ? this.TYPES.BUSINESS_SERVICE : this.TYPES.TECHNICAL_SERVICE;
var serviceNode = this.createNode(
serviceId,
serviceName,
serviceType,
this.getOfferings(serviceId, serviceType));
this.getTaxonomy(serviceTaxonomyID, serviceNode);
}
}
},
getOfferings: function(parent, parentType) {
this.slowStepManager.startStep(this.type + ": getOfferings");
var offerings = [];
var offeringGr = new GlideRecord(this.TABLES.OFFERING);
offeringGr.addQuery(this.FIELDS.PARENT, parent);
offeringGr.query();
while (offeringGr.next()) {
var offeringID = offeringGr.getValue(this.FIELDS.SYS_ID);
var offeringName = offeringGr.getValue(this.FIELDS.NAME);
offerings.push(this.createNode(
offeringID,
offeringName,
this.TYPES.OFFERING,
this.getApplicationServices(offeringID, parentType)));
}
return offerings;
},
getApplicationServices: function(parent, offeringClassification) {
this.slowStepManager.startStep(this.type + ": getApplicationServices");
var appServices = [];
var ciRelationsGr = new GlideRecord(this.TABLES.CI_RELATIONSHIPS);
ciRelationsGr.addQuery(this.FIELDS.PARENT, parent);
if (offeringClassification == this.TYPES.BUSINESS_SERVICE) {
ciRelationsGr.addQuery(this.FIELDS.TYPE, this.RELATION_TYPES.DEPENDS_ON_USED_BY);
} else { // must be technical service
ciRelationsGr.addQuery(this.FIELDS.TYPE, this.RELATION_TYPES.CONTAINS_CONTAINED_BY);
}
ciRelationsGr.query();
var childrenIds = [];
while (ciRelationsGr.next())
childrenIds.push(ciRelationsGr.getValue(this.FIELDS.CHILD));
var applicationGr = new GlideRecord(this.TABLES.APP_SERVICE);
applicationGr.addQuery(this.FIELDS.SYS_ID, "IN", childrenIds);
applicationGr.query();
while (applicationGr.next()) {
var applicationID = applicationGr.getValue(this.FIELDS.SYS_ID);
var applicationName = applicationGr.getValue(this.FIELDS.NAME);
appServices.push(this.createNode(
applicationID,
applicationName,
this.TYPES.APP_SERVICE,
[]));
}
return appServices;
},
// there is an assumption that the caller checked the correctness of taxonomyId and therefore the taxonomyGr will be nexted.
getTaxonomy: function(taxonomyId, childNode) {
this.slowStepManager.startStep(this.type + ": getTaxonomy");
var taxonomyGr = new GlideRecord(this.TABLES.TAXONOMY_NODE);
while (taxonomyId) {
var taxonomyNode = this.taxonomyNodes[taxonomyId];
if (!taxonomyNode) {
taxonomyGr.get(taxonomyId);
var taxonomyName = taxonomyGr.getValue(this.FIELDS.NAME);
childNode = this.createNode(taxonomyId, taxonomyName, this.TYPES.TAXONOMY_NODE, [childNode]);
this.taxonomyNodes[taxonomyId] = childNode;
taxonomyId = taxonomyGr.getValue(this.FIELDS.PARENT);
} else {
taxonomyNode.children.push(childNode);
return; // parent already inserted into the tree, no need to continue iterating over the tree
}
}
var portfolioId = taxonomyGr.getValue(this.FIELDS.PORTFOLIO);
this.getPortfolio(portfolioId, childNode);
return;
},
getPortfolio: function(portfolioId, childNode) {
this.slowStepManager.startStep(this.type + ": getPortfolio");
var portfolioNode = this.portfolioNodes[portfolioId];
if (!portfolioNode) {
var portfolioGr = new GlideRecord(this.TABLES.PORTFOLIO);
portfolioGr.get(portfolioId);
var portfolioName = portfolioGr.getValue(this.FIELDS.NAME);
this.portfolioNodes[portfolioId] = this.createNode(portfolioId, portfolioName, this.TYPES.SERVICE_PORTFOLIO, [childNode]);
return;
}
portfolioNode.children.push(childNode);
return;
},
createNode: function(sysId, name, type, children) {
return {
"data": {
"id": sysId,
"name": name,
"type": type,
},
"children": children
};
},
/*
returns object with services and/or offerings associated with the given alert
services: if false then don't return the impacted services
offerings: if false then don't return the impacted services
*/
getImpactedServicesAndOffering: function(alertId, services, offerings) {
var output = {
"alertId": alertId
};
var alertsInGroup = new global.EvtMgmtAlertsInGroupAPI();
var impactedServices = alertsInGroup.getImpactedServicesForAlert(alertId);
if (impactedServices) {
impactedServices = impactedServices.split(',');
if (offerings)
var impactedOfferings = this.getOfferingsForServices(impactedServices);
}
if (services)
output["services"] = impactedServices ? impactedServices : [];
if (offerings)
output["offerings"] = impactedOfferings ? impactedOfferings : [];
return output;
},
/*
returns the service offerings of the given serviceIds
servicesIds - array of sys_ids
*/
getOfferingsForServices: function(serviceIds) {
var startTime = new GlideDateTime().getNumericValue();
var servicesLimit = gs.getProperty('sn_em_ai.evt_mgmt.offerings_for_services.services_limit', 100);
var offerings = {};
if (!serviceIds)
return [];
if (serviceIds.length <= servicesLimit)
this.offeringsForServicesQuery(offerings, serviceIds);
else {
var iteration = 0;
do {
var services = serviceIds.slice(0, servicesLimit);
this.offeringsForServicesQuery(offerings, serviceIds);
serviceIds = serviceIds.slice(servicesLimit);
iteration = iteration + 1;
}
while (serviceIds.length > 0 && iteration < 100);
}
var output = [];
for (offering in offerings)
output.push(offering);
var endTime = new GlideDateTime().getNumericValue();
this.evtMgmtCommons.addDebugMessage(this.debugLog + "getOfferingsForServices time: " + String(endTime - startTime) + " ms");
return output;
},
offeringsForServicesQuery: function(curOfferings, services) {
var offeringsLimit = gs.getProperty('sn_em_ai.evt_mgmt.offerings_for_services.fetch_limit', 100000);
var relationGr = new GlideAggregate("cmdb_rel_ci");
relationGr.addQuery("child", "IN", services);
relationGr.addQuery("type", this.RELATION_TYPES.DEPENDS_ON_USED_BY)
.addOrCondition("type", this.RELATION_TYPES.CONTAINS_CONTAINED_BY);
relationGr.groupBy("parent"); // get unique offerings
relationGr.setLimit(offeringsLimit);
relationGr.query();
if (relationGr.getRowCount() >= offeringsLimit)
gs.info(this.type + 'The number of fetched service offerings is equal to the limit, more service offerings may exist.');
while (relationGr.next()) {
var parent = relationGr.parent.getRefRecord();
if (parent.isValidRecord()) {
if (parent.getValue("sys_class_name") == "service_offering")
curOfferings[parent.getUniqueValue()] = '';
}
}
},
type: 'EvtMgmtGetServicesRelationsForCsdm'
};
Sys ID
1180e74107120110a8b38c14dfd30051