Name

sn_itom_licensing.ITOMVisibilityLicenseCounterStore

Description

No description available

Script

var ITOMVisibilityLicenseCounterStore = Class.create();
ITOMVisibilityLicenseCounterStore.MAX_BATCH_SIZE = 5000;
ITOMVisibilityLicenseCounterStore.prototype = {
  initialize: function() {
      this.utils = new ITOMLicensingUtilsStore();
      this.metadata = new ITOMLicensingMetaDataStore();
      this.batchUtil = new global.BatchCommandUtilScript();
      this.skuId = this.utils._getSKUIDs();
      this.domainsList = this._getDomains();
  	this.arrayUtil = new global.ArrayUtil();
  },

  //Dummy function
  calculateUsage: function(isCount, skuType, valueStream) {
      this.calculateLicenseUsage(isCount, skuType, valueStream);
  },

  calculateLicenseUsage: function(isCount, skuType, valueStream, saveInTemp) {

      // is the new license model in place for this customer ?
      if (!this.utils.isNewLicenseModel())
          return;

      this.isDiscoverySkuPresent = this.utils.isDiscoveryPresent(skuType);
  	
  	if(!valueStream)
  	var	valueStream = (!this.utils.ignoreITOMDiscovery(skuType)) ? "Discovery" : "Visibility";

      this.maxResult = this.utils.getMaxResultsFor(valueStream, skuType);

      var dateFilter = 'Last 90 days@javascript:gs.beginningOfLast90Days()@javascript:gs.endOfLast90Days()';
      var CIListForCounting = {};
      this.totalListingCount = 0;

      //Calculate visibility license usage 
      var counts = this.utils.getCountsJsonTemplate(valueStream, skuType);

      for (var category in counts) {
          // NOTE: special case for enduser_devices where we *ONLY* want to count ACC-Visibility sourced CIs
          // This hard coding will be removed and externalised as part of DEF0201901
          var allowedSources = this._getDiscoverySources(category, this.skuId[skuType]);

          var tables = this.metadata.getTablesForSku(category, this.skuId[skuType]);
          var totalCount = 0;
          var domains = {};
          var categoryTotalCIs = [];

          // for each table that's found for a category
          for (var tableIndex in tables) {
              var excludedSysIds = {};

              var tableName = tables[tableIndex];
              if (!gs.tableExists(tableName))
                  continue;

              gs.debug("\tprocessing table : " + tableName);
              var tableCountGr = new GlideRecord(tableName);
              this._addCountConditions(tableCountGr, allowedSources, dateFilter);

              if (tableName == 'cmdb_ci_computer' && category == 'enduser_devices')
                  tableCountGr.addQuery('sys_class_name', 'cmdb_ci_computer');

  			if (this.utils.isOTDependencyPresent()) {
  				if (skuType == 'itom')
  					tableCountGr.addNullQuery('cmdb_ot_entity');

  				if (skuType == 'otm') {
  					tableCountGr.addNotNullQuery('cmdb_ot_entity');
  					if (tableName == 'cmdb_ci_ot' && category == 'Unclassed OT')
  						this.utils.addUnclassedOTCondition(tableCountGr);
  				}
  			}

              this.utils.addExclusionCondition(tableCountGr, valueStream, this.skuId[skuType], category);
              tableCountGr.query();

              // Making Record List 
              while (tableCountGr.next()) {
                  var sysId = tableCountGr.getUniqueValue();
                  var domainId = tableCountGr.getValue('sys_domain');

                  if(!this.domainsList[domainId])
                      domainId='global';

                  var ci = {
                      'sysId': sysId,
                      'domain': domainId
                  };
                  categoryTotalCIs.push(ci);
              }
          }

          categoryTotalCIs.forEach(function(ci) {
              if (domains.hasOwnProperty(ci.domain))
                  domains[ci.domain]++;
              else
                  domains[ci.domain] = 1;
          });

          // Adding 0 count with default domain in case of empty object
          counts[category] = (Object.keys(domains).length) ? domains : {
              "global": 0
          };

          // To List the CIs
          if (!isCount) {

              if (categoryTotalCIs.length <= ITOMVisibilityLicenseCounterStore.MAX_BATCH_SIZE) {
                  this._listResources(categoryTotalCIs, category, valueStream, skuType, saveInTemp);
              } else {
                  var length = categoryTotalCIs.length;
                  var low = 0;
                  var high = ITOMVisibilityLicenseCounterStore.MAX_BATCH_SIZE;
                  while (!this.utils.isVisibilityJobCanceled(skuType) && high <= length) {
                      var trimmedList = categoryTotalCIs.slice(low, high);
                      this._listResources(trimmedList, category, valueStream, skuType, saveInTemp);
                      low = high;
                      high += ITOMVisibilityLicenseCounterStore.MAX_BATCH_SIZE;
                  }
                  if (high > length && low < length) {
                      trimmedList = categoryTotalCIs.slice(low, length);
                      this._listResources(trimmedList, category, valueStream, skuType, saveInTemp);
                  }
              }
          }

      }
      // now persist the counts into the licensing counts table
      if (isCount) {
          for (var countedCategory in counts) {
              var checkInDiscovery = this._getCheckInDiscovery(valueStream, countedCategory, skuType);
              for (var countedDomain in counts[countedCategory]) {
  				this._insertRecord(valueStream, skuType, countedDomain, countedCategory, counts[countedCategory][countedDomain], checkInDiscovery);
              }
          }
      }
  },
  
  _insertRecord: function(valueStream, skuType, domain, category, count, checkInDiscovery) {
  	if(checkInDiscovery) {
  		var discoveryGR = new GlideRecord('itom_lu_ci_counts');
          discoveryGR.addQuery('value_stream', 'Discovery');
          discoveryGR.addQuery('sku', this.skuId[skuType]);
  	    discoveryGR.addQuery('sys_domain', domain);
          discoveryGR.addQuery('category', category);
          discoveryGR.addQuery('count', '>', 0);
          discoveryGR.addQuery('sys_created_on', 'ON', new GlideDate());
          discoveryGR.orderByDesc('sys_created_on');
  		discoveryGR.setLimit(1);
          discoveryGR.query();
  		if(discoveryGR.next()) {
  		   count -= discoveryGR.getValue('count');
              if(count < 0)
                  count = 0;
  		}
  	}
  	var countsGR = new GlideRecord('itom_lu_ci_counts');
      countsGR.setValue('value_stream', valueStream);
      countsGR.setValue('is_aggregated', 'false');
      countsGR.setValue('sku', this.skuId[skuType]);
  	countsGR.setValue('sys_domain', domain);
      countsGR.setValue('category', category);
      countsGR.setValue('count', count);
      countsGR.insert();
  },


  // NOTE: This function is overriden in ITOMVisibilityLicenseCounterWithServices
  _addCountConditions: function(tableCountGr, allowedSources, dateFilter) {
      tableCountGr.addQuery('duplicate_of', 'NULL');
      this.utils.addCiStatusQuery(tableCountGr, 'install_status');
      this._addSourceFilter(tableCountGr, 'sys_id', allowedSources, dateFilter);
  },

  _addSourceFilter: function(gr, ref, allowedSources, dateFilter) {
      var sourceQuery = gr.addJoinQuery('sys_object_source', ref, 'target_sys_id');
      sourceQuery.addCondition('name', 'IN', allowedSources.join(","));
      sourceQuery.addCondition('last_scan', 'ON', dateFilter);
  },

  _getDiscoverySources: function(category, skuId) {
  	var sources = [];
  	if(!category || !skuId)
  		return sources;
  	var licenseDiscoverySourceGr = new GlideRecord('itom_lu_discovery_source_mapping');
  	licenseDiscoverySourceGr.addQuery('sku_type', skuId);
  	licenseDiscoverySourceGr.addQuery('category', category);
  	licenseDiscoverySourceGr.query();
  	if(licenseDiscoverySourceGr.next()) {
  		var sourcesGr = new GlideRecord('itom_lu_discovery_sources');
  		sourcesGr.addQuery('sys_id', 'IN', licenseDiscoverySourceGr.sources.split(','));
  		sourcesGr.query();
  		while(sourcesGr.next()) {
  				sources.push(sourcesGr.getValue('source'));
  		}
  	}
      return sources;
  },

  // This method will get map with key as domains and value as 'true'
  _getDomains: function(){
      var domains = {};
      domains['global']=true;
      var domainGR = new GlideRecord('domain');
      if (domainGR.isValid()){
          domainGR.query();
          while (domainGR.next())
  	      domains[domainGR.getValue('sys_id')]=true;
      }

   return domains;
  },

  _listResources: function(ciListForCounting, category, valueStream, skuType, saveInTemp) {
  	if(saveInTemp)
  		this._listResourcesInTemporay(ciListForCounting);
  	else
  		this._listResourcesInOriginal(ciListForCounting, category, valueStream, skuType);
  	
  },
  
  _listResourcesInOriginal: function(ciListForCounting, category, valueStream, skuType) {

      if (this.maxResult <= this.totalListingCount)
          return;
      var sysIds = [];
      var ratio = this.utils.getCategory2Ratio()[category] + ":1";
      ciListForCounting.forEach(function(obj) {
          sysIds.push(obj.sysId);
      });

      var tableName = this.utils._getLicensableCIsTableInfo(valueStream, 'ci_table', skuType);
      var encodedQuery = this.utils.getAdditionalFiltersFor(valueStream, skuType);

      var gr = new GlideRecord(tableName);
      gr.addQuery('sys_id', 'IN', sysIds.join(','));
      if (encodedQuery)
          gr.addEncodedQuery(encodedQuery);
      gr.query();

      var jsonArr = [];
      var checkInDiscovery = this._getCheckInDiscovery(valueStream, category, skuType);
      var isSysIdPresentInDiscoveryMap = this._getIsSysIdPresentInDiscoveryMap(gr, sysIds);
      while (gr.next()) {
  		if(checkInDiscovery && isSysIdPresentInDiscoveryMap[gr.sys_id])
  		   continue;
          jsonCountRecord = {};
          jsonCountRecord.configuration_item = gr.sys_id + '';
          jsonCountRecord.category = category + '';
          jsonCountRecord.value_stream = valueStream + '';
          jsonCountRecord.sys_domain = gr.sys_domain + '';
          jsonCountRecord.su_ratio = ratio + '';
          jsonCountRecord.sku = this.skuId[skuType];

          this.totalListingCount++;
          jsonArr.push(jsonCountRecord);
          if (this.totalListingCount >= this.maxResult)
              break;
      }

      this.batchUtil.batchInsertMultiple(JSON.stringify(jsonArr), 'itom_lu_licensable_cis', '');
  },
  
  _listResourcesInTemporay: function(ciListForCounting) {
      var jsonArr = [];
      ciListForCounting.forEach(function(obj) {
          jsonCountRecord = {};
          jsonCountRecord.configuration_item = obj.sysId + '';
          jsonArr.push(jsonCountRecord);
      });
      this.batchUtil.batchInsertMultiple(JSON.stringify(jsonArr), 'visibility_lu_temp', '');
  },
  
  _getIsSysIdPresentInDiscoveryMap: function(gr, sysIds) {
      var isSysIdPresentInDiscoveryMap = [];
  	var grDisTemp = new GlideRecord('visibility_lu_temp');
      grDisTemp.addQuery('configuration_item', 'IN', sysIds.join(','));
      grDisTemp.query();
      while(grDisTemp.next()) {
          isSysIdPresentInDiscoveryMap[grDisTemp.configuration_item] = true;
      }
  	return isSysIdPresentInDiscoveryMap;
  },

  _getCheckInDiscovery: function(valueStream, category, skuType) {
      var commonCategories = this.utils.getCommonCategories('Discovery', 'Visibility', skuType);
      return (valueStream == 'Visibility' && this.isDiscoverySkuPresent && this.arrayUtil.contains(commonCategories, category));
  },

  type: 'ITOMVisibilityLicenseCounterStore'
};

Sys ID

8f1b4480b7c6301046df8985de11a9c4

Offical Documentation

Official Docs: