Name

sn_itom_licensing.ITOMGovernanceLicenseCounter

Description

No description available

Script

var ITOMGovernanceLicenseCounter = Class.create();
ITOMGovernanceLicenseCounter.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_GOVERNANCE_CI = "itom_lu_governance_ci";
      this.ITOM_LU_CI_COUNTS = "itom_lu_ci_counts";
      this.ITOM_LU_GOVERNANCE_APP_MAPPING = "itom_lu_governance_app_mapping";
      this.LICENSE_EXCLUSION_LIST = "license_exclusion_list";
      this.ITOM_LU_LICENSABLE_CIS = "itom_lu_licensable_cis";
      this.valueStream = "Governance";
      this.enableLog = enableLog;
      this.ciTableCategoryMap = {};
  	this.domainsMap = this.utils.getDomainsMap();
  },

  // Main function to be called in scheduled job
  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
      var mappingGr = new GlideRecord(this.ITOM_LU_GOVERNANCE_APP_MAPPING);
      mappingGr.addQuery("sku_type", this.skuId);
      mappingGr.query();
      while (mappingGr.next()) {
          if (this.pluginManager.isActive(mappingGr.getValue("plugin_id"))) {
              this._populateCisToCentralTable(mappingGr.getValue("table_name"), Boolean(mappingGr.is_external));
          }
      }

      //Step3: calculate usage
      this._calculateUsage();
      this._logMessage("Process ended");
      var end = new Date().getTime();
      gs.debug("ITOMGovernanceLicenseCounter - 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("governance.batchInsert.bulk_size", 5000));
      var suRatio = this.utils.getCategory2Ratio();
      var ciConditions = this.globalUtils.getAdditionalFiltersQuery(this.ITOM_LU_GOVERNANCE_CI, 'cmdb_ci', this.valueStream);
      var maxRecords = this.utils.getMaxResultsFor(this.valueStream, skuType);
      var gr = new GlideRecord(this.ITOM_LU_GOVERNANCE_CI);
      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;
          } else {
              jsonObj.node_id = '' + gr.ext_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.isGovernanceJobCanceled())
                  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.isGovernanceJobCanceled())
              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("ITOMGovernanceLicenseCounter - Time taken in listing CIs :- " + Math.abs(end - start));
  },

  _calculateUsage: function() {
      var start = new Date().getTime();
      this._logMessage("In calculateUsage function");
      var categoriesHashMap = this._getCategoriesHashMap();
      var ga = new GlideAggregate(this.ITOM_LU_GOVERNANCE_CI);
      ga.addAggregate('COUNT');
      ga.addQuery('sku_type', this.skuId);
      ga.groupBy('category');
      ga.groupBy('domain');
      ga.query();
      var jsonArr = [];
      var counter = 0;
      var test = this.ciCountsMap;
      var bulkSize = parseInt(gs.getProperty("governance.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;
  },

  _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);
  },

  _populateCisToCentralTable: function(tableName, isExternal) {
      this._logMessage("Populating CIs from table:- " + tableName + " isExternal: " + isExternal);
      var totalRecords = 0;
      var bulkSize = parseInt(gs.getProperty("governance.batchInsert.bulk_size", 5000));
      if (isExternal)
          totalRecords += this._saveData(this._queryForExternalCis(tableName), bulkSize, true);
      totalRecords += this._saveData(this._queryForNotNullCis(tableName), bulkSize, false);
      this._logMessage("Governance processed total records: " + totalRecords);
  },

  _deletePreviousCIs: function() {
      this._logMessage("Deleting records from " + this.ITOM_LU_GOVERNANCE_CI + " table for sku " + this.skuType);
      var cleanupGr = new GlideRecord(this.ITOM_LU_GOVERNANCE_CI);
      cleanupGr.addQuery("sku_type", this.skuId);
      cleanupGr.deleteMultiple();
  },

  _logMessage: function(message) {
      if (this.enableLog) {
          gs.info("ITOMGovernanceLicenseCounter - " + message);
      }
  },

  _queryForExternalCis: function(table) {
      var start = new Date().getTime();
      var gr = new GlideRecord(table);
      gr.addNotNullQuery("ext_source");
      gr.addNullQuery("cmdb_ci");
      gr.addQuery("is_licensable", true);
      gr.query();
      var end = new Date().getTime();
      gs.debug("ITOMGovernanceLicenseCounter - Time taken to query external CIs :- " + Math.abs(end - start));
      return gr;
  },

  _queryForNotNullCis: function(table) {
      var start = new Date().getTime();
      var gr = new GlideRecord(table);
      gr.addNotNullQuery("cmdb_ci");
      gr.addNullQuery("cmdb_ci.duplicate_of");
      this.utils.addCiStatusQuery(gr, "cmdb_ci.install_status");
      gr.addQuery("is_licensable", true);
      gr.query();
      var end = new Date().getTime();
      gs.debug("ITOMGovernanceLicenseCounter - Time taken to query cmdb CIs :- " + Math.abs(end - start));
      return gr;
  },

  _saveData: function(gr, bulkSize, isExternal) {
      var counter = 0;
      var total = 0;
      var jsonArr = [];
      while (gr.next()) {
          var jsonObj = {};
          var tableName = this._validateAndGetValue('table_name', gr);
          if (isExternal)
              jsonObj.ext_ci = this._validateAndGetValue('ext_source', gr);
          else
              jsonObj.cmdb_ci = this._validateAndGetValue('cmdb_ci', gr);
          jsonObj.domain = '' + this._getDomain(gr.sys_domain);
          jsonObj.table_name = tableName;
          jsonObj.category = '' + this._getCategory(tableName);
          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, isExternal);
              counter = 0;
              jsonArr = [];
          }
      }
      if (counter > 0) {
          this._logMessage("Before calling _insertRecord function 2 :: " + JSON.stringify(jsonArr));
          this._insertRecords(jsonArr, isExternal);
      }
      return total;
  },

  _validateAndGetValue: function(field, gr) {
      var value = gr.getValue(field);
      if (!value) {
          gs.error("ITOMGovernanceLicenseCounter - getting undefined value for " + field);
          return '';
      }
      return '' + value;
  },

  _getCategory: function(tableName) {
      if (!this.ciTableCategoryMap[tableName]) {
          var category = this.metaDataUtils.getCategories([tableName], 'itom')[tableName];
          this.ciTableCategoryMap[tableName] = category ? category : "Uncategorized Object";
      }
      return this.ciTableCategoryMap[tableName];
  },

  _insertRecords: function(jsonArr, isExternal) {
      jsonArr = this._deDuplicateCis(jsonArr, isExternal);
      this._logMessage("After deduplication :: " + JSON.stringify(jsonArr));
      if (!isExternal)
          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_GOVERNANCE_CI, '');
      var end = new Date().getTime();
      gs.debug("ITOMGovernanceLicenseCounter - Time taken to insert " + jsonArr.length + " records in " + this.ITOM_LU_GOVERNANCE_CI + " table :- " + Math.abs(end - start));
  },

  _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("ITOMGovernanceLicenseCounter - Time taken to exclude CIs :- " + Math.abs(end - start));
      return finalCiList;
  },

  _getDomain: function(domain) {
      if (!domain || domain == "" || !this.pluginManager.isActive("com.glide.domain.msp_extensions.installer") || !this.domainsMap[domain])
          return "global";
      return domain;
  },

  _deDuplicateCis: function(jsonArr, isExternal) {
      var start = new Date().getTime();
      var ciHashMap = {};
      var dedupedCiList = [];
      var column = isExternal ? 'ext_ci' : 'cmdb_ci';
      for (var i = 0; i < jsonArr.length; i++)
          ciHashMap[jsonArr[i][column]] = jsonArr[i];
      var dedupGr = new GlideRecord(this.ITOM_LU_GOVERNANCE_CI);
      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("ITOMGovernanceLicenseCounter - Time taken to deduplicate CIs :- " + Math.abs(end - start));
      return dedupedCiList;
  },

  type: 'ITOMGovernanceLicenseCounter'
};

Sys ID

c56ac97e7771011021c742aa5b5a99c3

Offical Documentation

Official Docs: