Name
sn_itom_licensing.ITOMLicensingAggregationHelperStore
Description
Helper for ITOM Licensing CI Counts Aggregation
Script
var ITOMLicensingAggregationHelperStore = Class.create();
ITOMLicensingAggregationHelperStore.prototype = {
initialize: function() {
this.jobStartTime = new GlideDateTime();
this.CI_COUNTS_TABLE_NAME = 'itom_lu_ci_counts';
this.utils = new ITOMLicensingUtilsStore();
this.valueStreams = this.utils.getValueStreams();
this.category2Ratio = this.utils.getCategory2Ratio();
this.domains = this.utils.getDomains();
this.metadataUtil = new ITOMLicensingMetaDataStore();
this.instanceSkuList = JSON.parse(sn_lef.GlideEntitlement.getUnifiedItomLicenseInfo());
this.arrayUtils = new global.ArrayUtil();
},
getAggregateMethod: function() {
var gr = new GlideRecord('itom_lu_sku_type');
gr.query();
while (gr.next()) {
var skuType = gr.getValue('sku');
if ((skuType == "itom") || (skuType == "otm" && this.utils.isOTDependencyPresent())) {
this.aggregateCiCounts(gr.getValue('sku'));
}
}
},
aggregateCiCounts: function(skuType) {
var skuBasedLicenseInfoList = this._getSkuBasedLicenseInfoList(skuType);
var aggregates = this._initAggregatesJson(skuBasedLicenseInfoList, skuType);
var ga = new GlideAggregate(this.CI_COUNTS_TABLE_NAME);
var isDomainSeparated = this._isDomainSeparated();
var encodedQuery = 'sys_created_onONLast 90 days@javascript:gs.beginningOfLast90Days()@javascript:gs.endOfLast90Days()';
if (isDomainSeparated) {
ga.addAggregate('SUM', 'count');
var domainSeparationEnabledOn = this._getDomainSeparationEnabledDate();
if (domainSeparationEnabledOn && domainSeparationEnabledOn.length > 0) {
var domainSeparationEnabledDate = new GlideDateTime();
domainSeparationEnabledDate.setValue(domainSeparationEnabledOn);
var currentDate = new GlideDateTime();
var duration = GlideDateTime.subtract(domainSeparationEnabledDate, currentDate);
var noOfDays = (duration.getDayPart() + 1);
if (noOfDays < 90) {
//taking average from the days when domain separation is enabled
encodedQuery = "sys_created_on>=" + domainSeparationEnabledOn;
}
}
} else {
ga.addAggregate('AVG', 'count');
}
this.skuId = this.utils.skuSysId[skuType];
ga.addAggregate('AVG', 'count');
ga.addQuery('sku', this.skuId);
ga.addQuery('is_aggregated', false);
ga.addEncodedQuery(encodedQuery);
ga.addQuery('value_stream', 'IN', this.valueStreams);
ga.addQuery('category', 'IN', Object.keys(this.category2Ratio));
ga.groupBy('value_stream');
ga.groupBy('category');
ga.groupBy('sys_domain');
ga.query();
while (ga.next()) {
var valueStream = ga.getValue('value_stream');
var category = ga.getValue('category');
var domain = ga.getValue('sys_domain');
if (aggregates[valueStream][domain].hasOwnProperty(category)) {
var categoryJson = aggregates[valueStream][domain][category];
if (isDomainSeparated) {
avg = noOfDays && noOfDays < 90 ? Math.floor(ga.getAggregate('SUM', 'count') / noOfDays) : Math.floor(ga.getAggregate('SUM', 'count') / 90);
} else {
avg = Math.floor(ga.getAggregate('AVG', 'count'));
}
var suCount = this._calcSuCount(avg, categoryJson.su_ratio);
categoryJson.count = avg;
categoryJson.su_count = suCount;
}
}
this._updateCiCountsTable(aggregates);
if (!JSON.parse(sn_lef.GlideEntitlement.getUnifiedItomLicenseInfo()).length)
return;
var accountingHelper = new ITOMLicensingAccountingHelperStore();
accountingHelper.accountUsage(isDomainSeparated, skuType, aggregates);
},
_getDomainSeparationEnabledDate: function() {
var DSEnabledOn = gs.getProperty('sn_itom_license.domain_separation_enabled_date');
if (DSEnabledOn)
return DSEnabledOn;
// Check for oldest non-aggregated record where domain is not global i.e. a new domain has arrived
var gr = new GlideRecord(this.CI_COUNTS_TABLE_NAME);
gr.addQuery('sys_domain', '!=', 'global');
gr.addQuery('is_aggregated', false);
gr.setLimit(1);
gr.orderBy('sys_created_on');
gr.query();
if (gr.next()) {
// Update System Property
var systemPropertyGr = new GlideRecord('sys_properties');
systemPropertyGr.get('name', 'sn_itom_license.domain_separation_enabled_date');
systemPropertyGr.setValue('value', gr.getValue('sys_created_on'));
systemPropertyGr.update();
return gr.getValue('sys_created_on');
}
},
_isDomainSeparated: function() {
return (GlidePluginManager.isActive('com.glide.domain.msp_extensions.installer') && this.domains.length > 1);
},
_initAggregatesJson: function(skuBasedLicenseInfoList, skuType) {
var aggregates = {};
var timestamp = new GlideDateTime();
for (var i = 0; i < this.valueStreams.length; i++) {
var valueStreamJson = {};
var isLicensableValueStream = this.arrayUtils.contains(this._getLicensableValueStreams(skuBasedLicenseInfoList, skuType), this.valueStreams[i]);
for (var k = 0; k < this.domains.length; k++) {
var domain = this.domains[k];
var domainJson = {};
var categories = {};
if (isLicensableValueStream) {
categories = this._getCategoryNamesBasedonValueStream(this.valueStreams[i].toLowerCase(), skuType);
} else {
categories = Object.keys(this.utils._getCategorySuRatiosFromProperty(skuType));
}
for (var j = 0; j < categories.length; j++) {
var category = categories[j];
var categoryJson = {};
categoryJson.count = 0;
categoryJson.su_ratio = this.category2Ratio[category];
categoryJson.su_count = 0;
categoryJson.last_aggregated = timestamp;
domainJson[category] = categoryJson;
}
valueStreamJson[domain] = domainJson;
}
var valueStream = this.valueStreams[i];
aggregates[valueStream] = valueStreamJson;
}
return aggregates;
},
_updateCiCountsTable: function(aggregates) {
if (!Object.keys(aggregates).length) {
this._removeStaleRecords();
return;
}
var valueStreams = Object.keys(aggregates);
for (var i = 0; i < valueStreams.length; i++) {
var valueStream = valueStreams[i];
var valueStreamJson = aggregates[valueStream];
for (var j = 0; j < this.domains.length; j++) {
var domain = this.domains[j];
var domainJson = valueStreamJson[domain];
var categories = Object.keys(domainJson);
for (var k = 0; k < categories.length; k++) {
var category = categories[k];
this._createOrUpdate(valueStream, category, domainJson[category], domain);
}
}
}
this._removeStaleRecords();
},
_createOrUpdate: function(valueStream, category, values, domain) {
var gr = new GlideRecord(this.CI_COUNTS_TABLE_NAME);
gr.addQuery('value_stream', valueStream);
gr.addQuery('sku', this.skuId);
gr.addQuery('category', category);
gr.addQuery('is_aggregated', true);
gr.addQuery('sys_domain', domain);
gr.query();
var hasNext = gr.next();
this._setValues(gr, values);
if (hasNext) {
gr.update();
} else {
gr.setValue('value_stream', valueStream);
gr.setValue('sku', this.skuId);
gr.setValue('category', category);
gr.setValue('is_aggregated', true);
gr.setValue('sys_domain', domain);
gr.insert();
}
},
_setValues: function(gr, values) {
for (var key in values) {
var value = values[key];
if (key == 'su_ratio') {
// Formatting ratio, assuming "to one"
value = value + ":1";
}
gr.setValue(key, value);
}
},
_calcSuCount: function(count, devicesPerSu) {
if (devicesPerSu == 0)
return 0;
return parseInt(Math.floor(count / devicesPerSu));
},
_getLicensableValueStreams: function(skuBasedLicenseInfoList) {
var i;
var valueStreams = [];
for (i = 0; i < skuBasedLicenseInfoList.length; i++) {
var gr = new GlideRecord('itom_lu_bundle_mappings');
var bundleId = skuBasedLicenseInfoList[i].app_bundle;
gr.addQuery('bundle_id', bundleId);
gr.query();
while (gr.next()) {
var vs = gr.getDisplayValue('value_stream');
vs = vs.split(",");
vs.forEach(function(obj) {
obj = this.utils._localizationSupportForValueStreamName(obj);
if (valueStreams.indexOf(obj) == -1)
valueStreams.push(obj);
}.bind(this));
}
}
return valueStreams;
},
_getCategoryNamesBasedonValueStream: function(valueStream, skuType) {
var licenseInfoList = this.utils._getItomLicenseInfo();
if (!licenseInfoList.length) {
gs.error('Could not retreive license information from GlideEntitlement API');
return [];
}
var skuList = this.metadataUtil.bundleMapping[valueStream];
var bundleListforSKU = this.metadataUtil.getBundleIdFromSkuType(skuType);
if (!skuList) {
gs.error('Could not retreive a list of Bundles for a given valuestream');
return [];
}
var categories = [];
for (var i = 0; i < licenseInfoList.length; i++) {
var sku = licenseInfoList[i];
var ratioInfo = sku.ciTypeToSURatioMap || sku.su_ratio;
if (new global.ArrayUtil().contains(skuList, sku.app_bundle) && new global.ArrayUtil().contains(bundleListforSKU, sku.app_bundle) && ratioInfo) {
if (sku.app_bundle.indexOf(skuType) != -1) {
categories = this.metadataUtil.getCategoriesOfSku(ratioInfo);
break;
} else if (skuType == 'itom') {
categories = this.metadataUtil.getCategoriesOfSku(ratioInfo);
break;
}
}
}
if (new global.ArrayUtil().contains(categories, this.metadataUtil.getCategoryNameForUnknown()) && "health" != valueStream && "hla" != valueStream)
categories = categories.filter(function(category) {
return category != this.metadataUtil.getCategoryNameForUnknown();
}, this);
return categories;
},
_removeStaleRecords: function() {
var tableGr = new GlideRecord('itom_lu_ci_counts');
tableGr.addQuery('sys_updated_on', '<', this.jobStartTime);
tableGr.addQuery('is_aggregated', true);
tableGr.addQuery('sku', this.skuId);
tableGr.query();
tableGr.deleteMultiple();
},
_getSkuBasedLicenseInfoList: function(skuType) {
var skuBasedLicenseInfoList = [];
this.instanceSkuList.forEach(function(obj) {
if (skuType == 'otm' && obj.app_bundle.indexOf('otm') != -1)
skuBasedLicenseInfoList.push(obj);
else if (skuType == 'itom' && obj.app_bundle.indexOf('otm') == -1)
skuBasedLicenseInfoList.push(obj);
});
return skuBasedLicenseInfoList;
},
type: 'ITOMLicensingAggregationHelperStore'
};
Sys ID
4fd8ef1b5375301046dfddeeff7b121d