Name
sn_itom_licensing.ITOMDEXLicenseCounterStore
Description
Script Include to calculate license usage of DEX
Script
var ITOMDEXLicenseCounterStore = Class.create();
ITOMDEXLicenseCounterStore.prototype = {
initialize: function(enableLog) {
this.metaDataUtils = new ITOMLicensingMetaDataStore();
this.batchUtil = new global.BatchCommandUtilScript();
this.pluginManager = new GlidePluginManager();
this.utils = new ITOMLicensingUtilsStore();
this.globalUtils = new global.UtilScript();
this.ITOM_LU_CI_COUNTS = "itom_lu_ci_counts";
this.LICENSE_EXCLUSION_LIST = "license_exclusion_list";
this.ITOM_LU_LICENSABLE_CIS = "itom_lu_licensable_cis";
this.ITOM_LU_DEX_CIS = "sn_itom_licensing_itom_lu_dex_ci";
this.DX_MENU_APP = "sn_dex_systray_desktop_exp";
this.DX_CHROME_PLUGIN = "dem_ci_browser_extension";
this.DEM_CONTENT_PLUGIN = "sn_dem_content";
this.SYS_OBJECT_SOURCE = "sys_object_source";
this.CMDB_CI_COMPUTER = "cmdb_ci_computer";
this.CHROME_PLUGIN = "sn_dem";
this.MENU_APP_PLUGIN = "sn_dex_systray";
this.DEX_DISCOVERY_SOURCE = "ServiceNow DEX";
this.DATE_FILTER = 'Last 90 days@javascript:gs.beginningOfLast90Days()@javascript:gs.endOfLast90Days()';
this.CATEGORY = 'enduser_devices';
this.valueStream = "DEX";
this.enableLog = enableLog;
this.ciTableCategoryMap = {};
this.domainsMap = this.utils.getDomainsMap();
},
process: function(skuTypeGr) {
var start = new Date().getTime();
this._logMessage("Process Started");
this.skuId = skuTypeGr.getValue("sys_id");
this.skuType = skuTypeGr.getValue("sku");
//Step1: delete all previous records
this._deletePreviousCIs();
//Step2: populated CIs to central table
if (this._isPluginActive(this.CHROME_PLUGIN))
this._populateCisToCentralTable(this.DX_CHROME_PLUGIN);
if (this._isPluginActive(this.MENU_APP_PLUGIN))
this._populateCisToCentralTable(this.DX_MENU_APP);
if(this._isPluginActive(this.DEM_CONTENT_PLUGIN))
this._populateCisToCentralTable(this.CMDB_CI_COMPUTER);
//Step3: calculate usage
this._calculateLicenseUsgae();
this._logMessage("Process ended");
var end = new Date().getTime();
gs.debug("ITOMDEXLicenseCounter - Total Time taken :- " + Math.abs(end - start));
},
populateReportTable: function(skuTypeGr) {
var start = new Date().getTime();
this._logMessage("Listing process started");
var skuType = skuTypeGr.getValue('sku');
var skuTypeSysId = skuTypeGr.getValue('sys_id');
var counter = 0;
var total = 0;
var jsonArr = [];
var bulkSize = parseInt(gs.getProperty("dex.batchInsert.bulk_size", 5000));
var suRatio = this.utils.getCategory2Ratio();
var ciConditions = this.globalUtils.getAdditionalFiltersQuery(this.ITOM_LU_DEX_CIS, 'cmdb_ci', this.valueStream);
var maxRecords = this.utils.getMaxResultsFor(this.valueStream, skuType);
var gr = new GlideRecord(this.ITOM_LU_DEX_CIS);
if (!gs.nil(ciConditions))
gr.addEncodedQuery(ciConditions);
gr.addQuery('sku_type', skuTypeSysId);
gr.query();
while (gr.next()) {
var jsonObj = {};
if (!gs.nil(gr.cmdb_ci))
jsonObj.configuration_item = '' + gr.cmdb_ci;
var category = gr.category;
var su_ratio = suRatio[category];
jsonObj.sys_domain = '' + gr.domain;
jsonObj.value_stream = '' + this.valueStream;
jsonObj.category = '' + category;
jsonObj.su_ratio = '' + su_ratio + ':1';
jsonObj.sku = '' + skuTypeSysId;
jsonArr.push(jsonObj);
counter++;
total++;
if (total >= maxRecords)
break;
if (counter >= bulkSize) {
if (this.utils.isDEXJobCanceled())
return;
this._logMessage("Going to insert CIs:- " + JSON.stringify(jsonArr));
this.batchUtil.batchInsertMultiple(JSON.stringify(jsonArr), this.ITOM_LU_LICENSABLE_CIS, '');
counter = 0;
jsonArr = [];
}
}
if (counter > 0) {
if (this.utils.isDEXJobCanceled())
return;
this._logMessage("Going to insert CIs:- " + JSON.stringify(jsonArr));
this.batchUtil.batchInsertMultiple(JSON.stringify(jsonArr), this.ITOM_LU_LICENSABLE_CIS, '');
}
this._logMessage("Listing process ended");
var end = new Date().getTime();
gs.debug("ITOMDEXLicenseCounter - Time taken in listing CIs :- " + Math.abs(end - start));
},
_calculateLicenseUsgae: function() {
this._logMessage("In calculateUsage function");
var categoriesHashMap = this._getCategoriesHashMap();
var ga = new GlideAggregate(this.ITOM_LU_DEX_CIS);
ga.addAggregate('COUNT');
ga.addQuery('sku_type', this.skuId);
ga.groupBy('category');
ga.groupBy('domain');
ga.query();
var jsonArr = [];
var counter = 0;
var bulkSize = parseInt(gs.getProperty("dex.batchInsert.bulk_size", 5000));
while (ga.next()) {
var category = ga.getValue('category');
this._addJsonObjToJsonArr(jsonArr, ga.getValue('domain'), category, ga.getAggregate('COUNT'));
++counter;
if (categoriesHashMap[category])
delete categoriesHashMap[category];
if (counter >= bulkSize) {
this._logMessage("Before insertion 1 :: " + JSON.stringify(jsonArr));
this.batchUtil.batchInsertMultiple(JSON.stringify(jsonArr), this.ITOM_LU_CI_COUNTS, '');
jsonArr = [];
counter = 0;
}
}
if (Object.keys(categoriesHashMap).length > 0) {
for (var category in categoriesHashMap) {
this._addJsonObjToJsonArr(jsonArr, 'global', category, 0);
++counter;
}
}
if (counter > 0) {
this._logMessage("Before insertion 2 :: " + JSON.stringify(jsonArr));
this.batchUtil.batchInsertMultiple(JSON.stringify(jsonArr), this.ITOM_LU_CI_COUNTS, '');
}
this._logMessage("Done calculation");
},
_getCategoriesHashMap: function() {
var categoriesHashMap = [];
var categories = this.metaDataUtils.getCategoryNamesBasedonValueStream(this.valueStream.toLowerCase(), this.skuType);
for (var i = 0; i < categories.length; i++)
categoriesHashMap[categories[i]] = 1;
return categoriesHashMap;
},
_logMessage: function(message) {
if (this.enableLog)
gs.info("ITOMDEXLicenseCounterStore - " + message);
},
_isPluginActive: function(plugin) {
return this.pluginManager.isActive(plugin);
},
_addJsonObjToJsonArr: function(jsonArr, domain, category, count) {
var jsonObj = {};
jsonObj.value_stream = '' + this.valueStream;
jsonObj.is_aggregated = '' + false;
jsonObj.sku = '' + this.skuId;
jsonObj.sys_domain = '' + domain;
jsonObj.category = '' + category;
jsonObj.count = '' + count;
jsonArr.push(jsonObj);
},
_deletePreviousCIs: function() {
this._logMessage("Deleting records from " + this.ITOM_LU_DEX_CIS + " table for sku " + this.skuType);
var cleanupGr = new GlideRecord(this.ITOM_LU_DEX_CIS);
cleanupGr.addQuery("sku_type", this.skuId);
cleanupGr.deleteMultiple();
},
_populateCisToCentralTable: function(tableName) {
if(!gs.tableExists(tableName))
return;
this._logMessage("Populating CIs from table");
var totalRecords = 0;
var bulkSize = parseInt(gs.getProperty("dex.batchInsert.bulk_size", 5000));
totalRecords += this._saveData(this._queryForNotNullCis(tableName), bulkSize, tableName);
this._logMessage("DEX processed total records: " + totalRecords);
},
_queryForNotNullCis: function(table) {
var start = new Date().getTime();
var gr = new GlideRecord(table);
if(table == this.DX_CHROME_PLUGIN) {
gr.addNotNullQuery("ci_id");
gr.addNullQuery("ci_id.duplicate_of")
this.utils.addCiStatusQuery(gr, "ci_id.install_status");
} else if (table == this.DX_MENU_APP) {
gr.addNotNullQuery("installed_on");
gr.addNullQuery("installed_on.duplicate_of");
this.utils.addCiStatusQuery(gr, "installed_on.install_status");
} else if (table == this.CMDB_CI_COMPUTER) {
gr.addQuery('duplicate_of', 'NULL');
this.utils.addCiStatusQuery(gr, "install_status");
this._addConditionForDEX(gr, 'sys_id', this.DEX_DISCOVERY_SOURCE);
}
gr.query();
var end = new Date().getTime();
gs.debug("ITOMDEXLicenseCounter - Time taken to query cmdb CIs :- " + Math.abs(end - start));
return gr;
},
_addConditionForDEX: function(gr, ref, dex_discovery_source) {
var sourceQuery = gr.addJoinQuery('sys_object_source', ref, 'target_sys_id');
sourceQuery.addCondition('name', dex_discovery_source);
},
_saveData: function(gr, bulkSize, tableName) {
var counter = 0;
var total = 0;
var jsonArr = [];
var computerGR = new GlideRecord(this.CMDB_CI_COMPUTER);
while (gr.next()) {
var jsonObj = {};
if(tableName == this.DX_CHROME_PLUGIN) {
jsonObj.cmdb_ci = this._validateAndGetValue('ci_id', gr);
jsonObj.domain = '' + this._getDomainFromCITable(gr.getValue('ci_id'), computerGR);
} else if (tableName == this.DX_MENU_APP) {
jsonObj.cmdb_ci = this._validateAndGetValue('installed_on', gr);
jsonObj.domain = '' + this._getDomainFromCITable(gr.getValue('installed_on'), computerGR);
} else if (tableName == this.CMDB_CI_COMPUTER) {
jsonObj.cmdb_ci = this._validateAndGetValue('sys_id', gr);
jsonObj.domain = '' + this._getDomain(gr.sys_domain);
}
jsonObj.table_name = tableName;
jsonObj.category = this.CATEGORY;
jsonObj.sku_type = '' + this.skuId;
jsonArr.push(jsonObj);
counter++;
total++;
if (counter >= bulkSize) {
this._logMessage("Before calling _insertRecord function 1 :: " + JSON.stringify(jsonArr));
this._insertRecords(jsonArr);
counter = 0;
jsonArr = [];
}
}
if (counter > 0) {
this._logMessage("Before calling _insertRecord function 2 :: " + JSON.stringify(jsonArr));
this._insertRecords(jsonArr);
}
return total;
},
_validateAndGetValue: function(field, gr) {
var value = gr.getValue(field);
if (!value) {
gs.error("ITOMDEXLicenseCounter - getting undefined value for " + field);
return '';
}
return '' + value;
},
_insertRecords: function(jsonArr) {
jsonArr = this._deDuplicateCis(jsonArr);
this._logMessage("After deduplication :: " + JSON.stringify(jsonArr));
jsonArr = this._removeExcludedCis(jsonArr);
this._logMessage("After removing excluded cis :: " + JSON.stringify(jsonArr));
var start = new Date().getTime();
this.batchUtil.batchInsertMultiple(JSON.stringify(jsonArr), this.ITOM_LU_DEX_CIS, '');
var end = new Date().getTime();
gs.debug("ITOMDEXLicenseCounter - Time taken to insert " + jsonArr.length + " records in " + this.ITOM_LU_DEX_CIS + " table :- " + Math.abs(end - start));
},
_getDomainFromCITable: function(ciColumn, computerGR) {
computerGR.initialize();
computerGR.addQuery('sys_id', ciColumn);
computerGR.query();
var domain;
if(computerGR.next())
domain = computerGR.getValue('sys_domain');
if (!domain || domain == "" || !this.pluginManager.isActive("com.glide.domain.msp_extensions.installer") || !this.domainsMap[domain])
return "global";
return domain;
},
_getDomain: function(domain) {
if (!domain || domain == "" || !this.pluginManager.isActive("com.glide.domain.msp_extensions.installer") || !this.domainsMap[domain])
return "global";
return domain;
},
_removeExcludedCis: function(jsonArr) {
var start = new Date().getTime();
var ciHashMap = {};
var finalCiList = [];
for (var i = 0; i < jsonArr.length; i++)
ciHashMap[jsonArr[i].cmdb_ci] = jsonArr[i];
var excludeGr = new GlideRecord(this.LICENSE_EXCLUSION_LIST);
excludeGr.addQuery('ci', 'IN', Object.keys(ciHashMap).join(','));
excludeGr.addQuery('exclusion_reason.value_stream', this.valueStream).addOrCondition('exclusion_reason.value_stream', 'All');
excludeGr.query();
while (excludeGr.next())
delete ciHashMap[excludeGr.getValue('ci')];
for (var ciHash in ciHashMap)
finalCiList.push(ciHashMap[ciHash]);
var end = new Date().getTime();
gs.debug("ITOMDEXLicenseCounter - Time taken to exclude CIs :- " + Math.abs(end - start));
return finalCiList;
},
_deDuplicateCis: function(jsonArr) {
var start = new Date().getTime();
var ciHashMap = {};
var dedupedCiList = [];
var column = 'cmdb_ci';
for (var i = 0; i < jsonArr.length; i++)
ciHashMap[jsonArr[i][column]] = jsonArr[i];
var dedupGr = new GlideRecord(this.ITOM_LU_DEX_CIS);
dedupGr.addQuery(column, 'IN', Object.keys(ciHashMap).join(','));
dedupGr.query();
while (dedupGr.next())
delete ciHashMap[dedupGr.getValue(column)];
for (var ciHash in ciHashMap)
dedupedCiList.push(ciHashMap[ciHash]);
var end = new Date().getTime();
gs.debug("ITOMDEXLicenseCounter - Time taken to deduplicate CIs :- " + Math.abs(end - start));
return dedupedCiList;
},
type: 'ITOMDEXLicenseCounterStore'
};
Sys ID
fc2871f2875d619010f08519dabb35da