Name
sn_cmdb_ws.CMDBWsProductAdoptionUtil
Description
No description available
Script
var CMDBWsProductAdoptionUtil = Class.create();
CMDBWsProductAdoptionUtil.prototype = Object.extendsObject(CMDBWorkspaceUtil, {
initialize: function() {
this.PRODUCT_ADOPTION_STATE = {
IN_USE: {
id: "in_use",
label: gs.getMessage("In use"),
color: "positive",
variant: "primary",
positive: true
},
NOT_IN_USE: {
id: "not_in_use",
label: gs.getMessage("Not in use"),
color: "orange",
variant: "primary",
positive: false
},
INSTALLED: {
id: "installed",
label: gs.getMessage("Installed"),
color: "positive",
variant: "primary",
positive: true
},
NOT_INSTALLED: {
id: "not_installed",
label: gs.getMessage("Not installed"),
color: "orange",
variant: "primary",
positive: false
},
ENABLED: {
id: "enabled",
label: gs.getMessage("Enabled"),
color: "positive",
variant: "primary",
positive: true
},
NOT_ENABLED: {
id: "not_enabled",
label: gs.getMessage("Not enabled"),
color: "orange",
variant: "primary",
positive: false
},
NOT_LICENSED: {
id: "not_licensed",
label: gs.getMessage("Not licensed"),
color: "orange",
variant: "primary",
positive: false
},
INFO_NOT_AVAILABLE: {
id: "info_not_available",
positive: false,
hide: true
}
};
this.PRODUCT_ADOPTION_RATING = {
low: {
id: "low",
badge: {
"label": gs.getMessage("Low adoption"),
"color": "orange",
"variant": "primary"
},
dialColorConfig: {
"type": "singleColor",
"values": [{
"color": "f60b282d7709211078521605bc5a9974", //Color Grouped - Orange 2
"metric": "metric_0",
"rules": []
}]
}
},
moderate: {
id: "moderate",
badge: {
"label": gs.getMessage("Moderate adoption"),
"color": "moderate",
"variant": "primary"
},
dialColorConfig: {
"type": "singleColor",
"values": [{
"color": "f88ae42d7709211078521605bc5a99e5", //alert moderate
"metric": "metric_0",
"rules": []
}]
}
},
high: {
id: "high",
badge: {
"label": gs.getMessage("High adoption"),
"color": "positive",
"variant": "primary"
},
dialColorConfig: {
"type": "singleColor",
"values": [{
"color": "304a642d7709211078521605bc5a9993", //data vis color green 6
"metric": "metric_0",
"rules": []
}]
}
}
};
this.PRODUCT_ADOPTION_METADATA = {
"dataSourceLabel": gs.getMessage("adoption"),
"format": {
"unitFormat": "{0}%"
}
};
this.DATA_INGESTION = {
IH_ETL: {
DEMO_URL: 'https://www.youtube.com/watch?v=eIvfQcq5AgY',
LEARN_MORE_URL: '/api/now/v1/context_doc_url/IntegrationHub_ETL_Landing',
PRODUCT_URL: 'nav_to.do?uri=%2F$cmdb_integration_studio.do',
STORE_URL: this.buildAppStoreUrl('/sn_appstore_store.do#!/store/application/d43fe173dba23300c121f3c61d961958')
},
CMDB_API: {
LEARN_MORE_URL: '/api/now/v1/context_doc_url/CMDB_Cli_Commands_Landing',
STORE_URL: this.buildAppStoreUrl('/sn_appstore_store.do#!/store/application/6541a411773220108043270bba1061c7')
},
SG_CONNECTORS: {
DEMO_URL: 'https://www.youtube.com/watch?v=eIvfQcq5AgY',
LEARN_MORE_URL: '/api/now/v1/context_doc_url/Service-Graph-Connectors_Landing',
STORE_URL: this.buildAppStoreUrl('/sn_appstore_store.do#!/store/integrations?freeTrial=service_graph_certified')
}
};
this.DATA_GOVERNANCE = {
DATA_ATTESTATION: {
LEARN_MORE_URL: '/api/now/v1/context_doc_url/CI_Attestation_Landing',
PRODUCT_URL: 'governance'
},
DATA_MANAGER: {
LEARN_MORE_URL: '/api/now/v1/context_doc_url/Data_Manager_Entry',
PRODUCT_URL: 'nav_to.do?uri=%24ci_lifecycle.do',
STORE_URL: this.buildAppStoreUrl('/sn_appstore_store.do#!/store/application/6541a411773220108043270bba1061c7')
}
};
this.SEARCH_AND_ANALYTICS = {
CMDB_360: {
DEMO_URL: 'https://www.youtube.com/watch?v=xpdXGsSoOwE',
LEARN_MORE_URL: '/api/now/v1/context_doc_url/CMDB_Wrkspc_CMDB360_View',
PRODUCT_URL: 'multisource-analytics'
},
DATA_FOUNDATION_DASHBOARD: {
DEMO_URL: 'https://www.youtube.com/watch?v=aPHxWoVdD1c',
LEARN_MORE_URL: '/api/now/v1/context_doc_url/CMDB_CSDM_Foundations_Dashboard_Landing',
PRODUCT_URL: 'nav_to.do?uri=$pa_dashboard.do?sysparm_dashboard=bc4b1417537c901032b7ddeeff7b1216',
STORE_URL: this.buildAppStoreUrl('/sn_appstore_store.do#!/store/application/5c0b68e35300101032b7ddeeff7b1231')
},
INTELLIGENT_SEARCH: {
LEARN_MORE_URL: 'api/now/v1/context_doc_url/CMDB_Intelligent_Search',
PRODUCT_URL: 'home',
},
QUERY_BUILDER: {
DEMO_URL: 'https://www.youtube.com/watch?v=NArqszOamHc',
LEARN_MORE_URL: '/api/now/v1/context_doc_url/CMDB_Query_Builder_Landing',
PRODUCT_URL: '$queryBuilder.do',
},
HEALTH_DASHBOARD: {
DEMO_URL: 'https://www.youtube.com/watch?v=aPHxWoVdD1c',
LEARN_MORE_URL: '/api/now/v1/context_doc_url/CMDB_Health_Dashboard_Landing',
PRODUCT_URL: 'nav_to.do?uri=$pa_dashboard.do?sysparm_dashboard=0b35c80ceb10220078e44d3df106fe61',
}
};
},
getCIsProcessedViaIRERating: function() {
var donutUsingIreCount = 0;
var donutNotUsingIreCount = 0;
var gr = new GlideRecord(this.TABLES.SN_CMDB_WS_BASE_AGGREGATE_DATA);
gr.addQuery(this.COLS.CHART, this.SUB_CATEGORY.CIS_PROCESSED_VIA_IRE);
gr.addQuery(this.COLS.STATE, this.STATES.READY);
gr.query();
while (gr.next()) {
var groupBy = gr.getValue(this.COLS.GROUP_BY);
var count = this.parseNumericString(gr.getValue(this.COLS.COUNT));
if (groupBy == this.IF_USE_IRE_GROUPBY.USING_IRE_TYPE) {
donutUsingIreCount = count;
} else {
donutNotUsingIreCount = count;
}
}
if (donutUsingIreCount + donutNotUsingIreCount == 0) {
return 0;
}
var rating = Math.round(donutUsingIreCount / (donutUsingIreCount + donutNotUsingIreCount) * 100);
return rating > 100 ? 100 : rating;
},
getCIsProcessedViaIRE: function() {
var donutUsingIreCount = 0;
var donutNotUsingIreCount = 0;
var cmdbCount = 0;
var ga = new GlideAggregate(this.TABLES.CMDB_CI);
ga.addAggregate(this.COUNT_AGGREGATE);
ga.setCategory(this.CMDB_WORKSPACE_DB_CATEGORY);
ga.query();
if (ga.next()) {
cmdbCount = this.parseNumericString(ga.getAggregate(this.COUNT_AGGREGATE));
}
ga = new GlideAggregate(this.TABLES.SYS_OBJECT_SOURCE);
ga.addEncodedQuery(this.COLS.TARGET_TABLE + this.QUERY_INSTANCEOF + this.TABLES.CMDB_CI);
ga.addAggregate(this.COUNT_DISTINCT_AGGREGATE, this.COLS.TARGET_SYS_ID);
ga.setGroup(false);
ga.setCategory(this.CMDB_WORKSPACE_DB_CATEGORY);
ga.query();
while (ga.next()) {
donutUsingIreCount = this.parseNumericString(ga.getAggregate(this.COUNT_DISTINCT_AGGREGATE, this.COLS.TARGET_SYS_ID));
}
donutNotUsingIreCount = cmdbCount - donutUsingIreCount > 0 ? cmdbCount - donutUsingIreCount : 0;
this.createCisProcessedViaIreAggregate();
this.updateBaseAggDataState(this.STATES.READY, this.STATES.RETIRED, this.SUB_CATEGORY.CIS_PROCESSED_VIA_IRE);
this.updateDraftFeatureCategoryAggregate(this.SUB_CATEGORY.CIS_PROCESSED_VIA_IRE, this.STATES.READY, donutUsingIreCount, this.IF_USE_IRE_GROUPBY.USING_IRE_TYPE);
this.updateDraftFeatureCategoryAggregate(this.SUB_CATEGORY.CIS_PROCESSED_VIA_IRE, this.STATES.READY, donutNotUsingIreCount, this.IF_USE_IRE_GROUPBY.NOT_USING_IRE_TYPE);
},
getCIsProcessedViaIREBySource: function() {
var discoveryTypeToCount = {};
discoveryTypeToCount[this.DISCOVERY_TYPE.SGC] = 0;
discoveryTypeToCount[this.DISCOVERY_TYPE.SN] = 0;
discoveryTypeToCount[this.DISCOVERY_TYPE.SGC_SN] = 0;
discoveryTypeToCount[this.DISCOVERY_TYPE.OTHER] = 0;
var instAppSources = {};
var gr = new GlideRecord(this.TABLES.CMDB_INST_APPLICATION);
gr.query();
while (gr.next()) {
var name = gr.getValue(this.COLS.NAME);
if (name.startsWith(this.IH_ETL_DEMODATA_PREFIX)) {
continue;
}
var source = gr.getValue(this.COLS.DISCOVERY_SOURCE);
instAppSources[source] = true;
}
var snDiscoverySources = {};
for (var snSourceName in this.SERVICENOW_DISCOVERY_SOURCE) {
snDiscoverySources[this.SERVICENOW_DISCOVERY_SOURCE[snSourceName]] = true;
}
var sgsnTypeState = '';
var previousTargetId = '';
gr = new GlideRecord(this.TABLES.SYS_OBJECT_SOURCE);
gr.addEncodedQuery(this.COLS.TARGET_TABLE + this.QUERY_INSTANCEOF + this.TABLES.CMDB_CI);
gr.orderBy(this.COLS.TARGET_SYS_ID);
gr.setCategory(this.CMDB_WORKSPACE_DB_CATEGORY);
gr.query();
while (gr.next()) {
var ciId = gr.getValue(this.COLS.TARGET_SYS_ID);
var discoverySource = gr.getValue(this.COLS.NAME);
if (ciId != previousTargetId) {
previousTargetId = ciId;
this.countDiscoveryType(sgsnTypeState, discoveryTypeToCount);
sgsnTypeState = '';
}
if (discoverySource.startsWith(this.QUALIFIER.SG) || discoverySource.startsWith(this.QUALIFIER.SGO) || instAppSources[discoverySource]) {
if (sgsnTypeState == this.DISCOVERY_TYPE.OTHER || sgsnTypeState == this.DISCOVERY_TYPE.SGC_SN) {
continue;
} else if (sgsnTypeState == this.DISCOVERY_TYPE.SN) { // Already SN
sgsnTypeState = this.DISCOVERY_TYPE.SGC_SN; // Assign to both SG and SN
} else {
sgsnTypeState = this.DISCOVERY_TYPE.SGC; // Assign to SG
}
} else if (snDiscoverySources[discoverySource]) {
if (sgsnTypeState == this.DISCOVERY_TYPE.OTHER || sgsnTypeState == this.DISCOVERY_TYPE.SGC_SN) {
continue;
} else if (sgsnTypeState == this.DISCOVERY_TYPE.SGC) { // Already SG
sgsnTypeState = this.DISCOVERY_TYPE.SGC_SN; // Assign to both SG and SN
} else {
sgsnTypeState = this.DISCOVERY_TYPE.SN; // Assign to SN
}
} else {
sgsnTypeState = this.DISCOVERY_TYPE.OTHER; // Assign to other
}
}
this.countDiscoveryType(sgsnTypeState, discoveryTypeToCount);
this.createCisProcessedViaIreAggregate(true);
this.updateBaseAggDataState(this.STATES.READY, this.STATES.RETIRED, this.SUB_CATEGORY.CIS_PROCESSED_VIA_IRE_BY_SOURCE);
for (var source in this.DISCOVERY_TYPE) {
this.updateDraftFeatureCategoryAggregate(this.SUB_CATEGORY.CIS_PROCESSED_VIA_IRE_BY_SOURCE, this.STATES.READY, discoveryTypeToCount[this.DISCOVERY_TYPE[source]], this.DISCOVERY_TYPE[source]);
}
},
countDiscoveryType: function(state, discoveryTypeToCount) {
if (state == this.DISCOVERY_TYPE.SGC || state == this.DISCOVERY_TYPE.SN || state == this.DISCOVERY_TYPE.SGC_SN || state == this.DISCOVERY_TYPE.OTHER) {
discoveryTypeToCount[state] += 1;
}
},
createCisProcessedViaIreAggregate: function(isBySource) {
if (isBySource) {
this.deleteFeatureCategoryAggregate(this.SUB_CATEGORY.CIS_PROCESSED_VIA_IRE_BY_SOURCE, this.STATES.DRAFT);
for (var source in this.DISCOVERY_TYPE) {
this.populateBaseAggData(this.SUB_CATEGORY.CIS_PROCESSED_VIA_IRE_BY_SOURCE, this.DISCOVERY_TYPE[source], 0, this.STATES.DRAFT);
}
} else {
this.deleteFeatureCategoryAggregate(this.SUB_CATEGORY.CIS_PROCESSED_VIA_IRE, this.STATES.DRAFT);
for (var groupby in this.IF_USE_IRE_GROUPBY) {
this.populateBaseAggData(this.SUB_CATEGORY.CIS_PROCESSED_VIA_IRE, this.IF_USE_IRE_GROUPBY[groupby], 0, this.STATES.DRAFT);
}
}
},
getProductAdoptionStates: function(category, excludeMarketingCopy) {
var result = {};
var ratings = {};
var gr = new GlideRecord(this.TABLES.SN_CMDB_WS_FEATURE_CATEGORY);
gr.addActiveQuery();
gr.addQuery(this.COLS.FEATURE, this.CMDB_FEATURE_ADOPTION);
gr.addNotNullQuery(this.COLS.SUBCATEGORY);
if (category) {
gr.addQuery(this.COLS.CATEGORY, category);
}
gr.query();
// evaluate all the state and rating values for each record in the table
while (gr.next()) {
var currCategory = gr.getValue(this.COLS.CATEGORY);
var currSubCategory = gr.getValue(this.COLS.SUB_CATEGORY);
var currTitle = gr.getValue(this.COLS.TITLE);
var currStateScript = gr.getValue(this.COLS.STATE);
var currRatingScript = gr.getValue(this.COLS.RATING);
var currMarketingCopyScript = gr.getValue(this.COLS.MARKETING_COPY);
if (!result[currCategory]) {
result[currCategory] = {
features: {}
};
ratings[currCategory] = {};
}
var gse = new GlideScopedEvaluator();
var state = null;
if (currStateScript) {
result[currCategory].features[currSubCategory] = {
title: currTitle
};
state = gse.evaluateScript(gr, this.COLS.STATE);
result[currCategory].features[currSubCategory].state = state;
}
gse.putVariable("state", state);
if (currRatingScript) {
ratings[currCategory][currSubCategory] = gse.evaluateScript(gr, this.COLS.RATING);
}
if (currMarketingCopyScript && !excludeMarketingCopy) {
result[currCategory].features[currSubCategory].marketingCopy = gse.evaluateScript(gr, this.COLS.MARKETING_COPY);
}
}
// aggregate ratings for each category
for (var _category in result) {
var ratingSum = 0;
var total = 0;
for (var _subCategory in ratings[_category]) {
ratingSum += ratings[_category][_subCategory];
total += 100;
}
if (total > 0) {
var categoryUsagePct = ratingSum / total * 100;
result[_category].usage = this.makeUsageDataObj(categoryUsagePct);
result[_category].usagePct = categoryUsagePct;
result[_category].rating = this.PRODUCT_ADOPTION_RATING[this.lookUpRating(this.INSIGHT_PRODUCT_CATEGORIES[_category.toUpperCase()], categoryUsagePct)];
}
}
result.lastUpdatedInfoText = gs.getMessage("Last updated: {0}", new GlideDateTime().getDisplayValue());
return result;
},
makeUsageDataObj: function(usagePct) {
//this is the format needed in the data visualization, single score
var usage = [{
"data": [{
"value": usagePct
}],
"metadata": this.PRODUCT_ADOPTION_METADATA
}];
return usage;
},
lookUpRating: function(category, pct) {
var rating;
var gr = new GlideRecord(this.TABLES.SN_CMDB_WS_RATING_CONFIG);
gr.addQuery(this.COLS.CATEGORY, category);
gr.query();
while (gr.next()) {
if (pct >= gr.getValue(this.COLS.START) && pct <= gr.getValue(this.COLS.END)) {
rating = gr.getValue(this.COLS.RATING);
break;
}
}
return rating;
},
isItomDiscoveryLicenseActive: function() {
return this.hasActiveLicense(this.LICENSE.ITOM_DISCOVERY);
},
isItomDiscoveryLicensePluginActive: function() {
return this.isPluginActive(this.PLUGINS.ITOM_DISCOVERY_LICENSE);
},
isItomLicensePluginActive: function() {
return this.isPluginActive(this.PLUGINS.ITOM_LICENSE);
},
isIhEtlInstalled: function() {
return this.isPluginActive(this.PLUGINS.INTEGRATION_HUB_ETL);
},
isCmdbApplicationForApiInstalled: function() {
return this.isPluginActive(this.PLUGINS.CMDB_APPLICATION_FOR_API_AND_CLI);
},
isDataManagerUsed: function() {
var policySysIds = [this.DATAMANAGER_POLICIES.RETIRE.SYS_ID, this.DATAMANAGER_POLICIES.ARCHIVE.SYS_ID, this.DATAMANAGER_POLICIES.DELETE.SYS_ID];
var isDataManagerUsedActively = this.isDataManagerUsedForPolicies(policySysIds);
if (isDataManagerUsedActively) {
return true;
}
return this.verifyHistoricalUsage(this.PA_INDICATORS.DATA_MANAGER.ID);
},
isAttestationUsed: function() {
var attestationPolicySysId = this.DATAMANAGER_POLICIES.ATTESTATION.SYS_ID;
var isAttestationUsedActively = this.isDataManagerUsedForPolicies([attestationPolicySysId]);
if (isAttestationUsedActively) {
return true;
}
return this.verifyHistoricalUsage(this.PA_INDICATORS.DATA_ATTESTATION.ID);
},
isDataManagerUsedForPolicies: function(policySysIds) {
var encodedQuery = "cdmp_cmdb_policy_typeIN" + policySysIds.join(",");
var hasUserDefinedPolicies = this.hasRecord(this.TABLES.CMDB_DATA_MANAGER_POLICY_AND_ATTRIBUTES, encodedQuery);
var hasPolicyExecutionRecords = false;
if (!hasUserDefinedPolicies) {
encodedQuery = "cmdb_policy.cmdb_policy_typeIN" + policySysIds.join(",");
hasPolicyExecutionRecords = this.hasRecord(this.TABLES.CMDB_DATA_MANAGEMENT_POLICY_EXECUTION, encodedQuery);
}
return hasUserDefinedPolicies || hasPolicyExecutionRecords;
},
isQueryBuilderUsed: function() {
var hasQbSavedQuery = this.hasRecord(this.TABLES.QB_SAVED_QUERY, null, {
"source": this.QUERY_BUILDER_SOURCE
});
if (hasQbSavedQuery) {
return true;
}
var indicatorId = this.PA_INDICATORS.QB_USAGE.ID;
var breakdownId = this.PA_INDICATORS.QB_USAGE.BREAKDOWN.TOTAL_QUERY.ID;
var breakdownElementId = this.getSysChoiceId("language=en^name=sn_cmdb_ws_base_aggregate_data^element=group_by^value=total_queries_executed^dependent_value=qb_queries");
return this.verifyHistoricalUsage(indicatorId, breakdownId, breakdownElementId);
},
isIntelligentSearchUsed: function() {
var isIntelligentSearchActivelyUsed = this.hasRecord(this.TABLES.NLQ_QUERY_LOG, null, {
source: this.INTELLIGENT_SEARCH_SOURCE
});
if (isIntelligentSearchActivelyUsed) {
return true;
}
return this.verifyHistoricalUsage(this.PA_INDICATORS.INTELLIGENT_SEARCH.ID);
},
isCmdbHealthDashboardJobActive: function() {
return this.hasRecord(this.TABLES.SYSAUTO, "nameLIKECMDB Health Dashboard", {
active: true
});
},
isDataFoundationDashboardInstalled: function() {
return this.isPluginActive(this.PLUGINS.DATA_FOUNDATION_DASHBOARD);
},
isCmdb360Enabled: function() {
var isDiscoveryInstalled = this.isItomDiscoveryLicensePluginActive();
var isMultiSrcPropEnabled = this.getSystemProperty(this.SYS_PROPERTIES_NAME.MULTISRC_ENABLED, this.DATATYPE.BOOLEAN);
return isDiscoveryInstalled && isMultiSrcPropEnabled;
},
populateAdoptionAggregates: function() {
this._populateDataManagerAggregates();
this._populateDataAttestationAggregates();
this._populateQBAggregates();
this.getCIsProcessedViaIRE();
this._populateIntelligentSearchAggregates();
},
_populateDataManagerAggregates: function() {
if (!this.isDataManagerUsed())
return;
var policies = [this.DATAMANAGER_POLICIES.RETIRE, this.DATAMANAGER_POLICIES.ARCHIVE, this.DATAMANAGER_POLICIES.DELETE];
//if there are any agg records in "draft" state, for this chart, mark them as "retired"
this.updateBaseAggDataState(this.STATES.DRAFT, this.STATES.RETIRED, this.SUB_CATEGORY.DATA_MANAGER);
for (var i = 0; i < policies.length; i++) {
var ciCount = this._getCICountForPolicies(policies[i].SYS_ID);
this.populateBaseAggData(this.SUB_CATEGORY.DATA_MANAGER, policies[i].GROUP_BY, ciCount, this.STATES.DRAFT);
}
// Update the existing records in "Ready" state to "Retired"
this.updateBaseAggDataState(this.STATES.READY, this.STATES.RETIRED, this.SUB_CATEGORY.DATA_MANAGER);
// Update the existing records in "Draft" state to "Ready"
this.updateBaseAggDataState(this.STATES.DRAFT, this.STATES.READY, this.SUB_CATEGORY.DATA_MANAGER);
},
_populateDataAttestationAggregates: function() {
if (!this.isAttestationUsed())
return;
//if there are any agg records in "draft" state, for this chart, mark them as "retired"
this.updateBaseAggDataState(this.STATES.DRAFT, this.STATES.RETIRED, this.SUB_CATEGORY.DATA_ATTESTATION);
var ciCount = this._getCICountForPolicies(this.DATAMANAGER_POLICIES.ATTESTATION.SYS_ID);
this.populateBaseAggData(this.SUB_CATEGORY.DATA_ATTESTATION, this.DATAMANAGER_POLICIES.ATTESTATION.GROUP_BY, ciCount, this.STATES.DRAFT);
// Update the existing records in "Ready" state to "Retired"
this.updateBaseAggDataState(this.STATES.READY, this.STATES.RETIRED, this.SUB_CATEGORY.DATA_ATTESTATION);
// Update the existing records in "Draft" state to "Ready"
this.updateBaseAggDataState(this.STATES.DRAFT, this.STATES.READY, this.SUB_CATEGORY.DATA_ATTESTATION);
},
_getCICountForPolicies: function(policySysId) {
var count = 0;
var endTimeWithin24Hr = this.getRelative24hrEncodedQuery(this.COLS.END_TIME);
var encodedQuery = "cmdb_policy.cmdb_policy_typeIN" + policySysId + "^execution_summaryISNOTEMPTY^" + endTimeWithin24Hr;
var gr = new GlideRecord(this.TABLES.CMDB_DATA_MANAGEMENT_POLICY_EXECUTION);
this.addQueryConditions(gr, encodedQuery);
gr.query();
while (gr.next()) {
var execSummary = gr.getValue(this.COLS.EXECUTION_SUMMARY);
var execSummarySplit = execSummary.split(this.EXEC_SUMM_CI_COUNT_PREFIX);
var ciCount = execSummarySplit.length > 1 ? parseInt(execSummarySplit[1].trim()) : 0;
count += ciCount;
}
return count;
},
_populateQBAggregates: function() {
//if there are any agg records in "draft" state, for this chart, mark them as "retired"
this.updateBaseAggDataState(this.STATES.DRAFT, this.STATES.RETIRED, this.SUB_CATEGORY.QUERY_BUILDER);
if(!this.isQueryBuilderUsed()) {
this.populateBaseAggData(this.SUB_CATEGORY.QUERY_BUILDER, this.QB_REPORTS_GROUPBY.TOTAL_CI, this.getRowCount(this.TABLES.CMDB_CI), this.STATES.DRAFT);
this.populateBaseAggData(this.SUB_CATEGORY.QUERY_BUILDER, this.QB_REPORTS_GROUPBY.TOTAL_CI_REL, this.getRowCount(this.TABLES.CMDB_REL_CI), this.STATES.DRAFT);
} else {
var resultObj = this._getQueriesExecutedCount();
for (var groupby in resultObj) {
this.populateBaseAggData(this.SUB_CATEGORY.QUERY_BUILDER, groupby, resultObj[groupby], this.STATES.DRAFT);
}
}
// Update the existing records in "Ready" state to "Retired"
this.updateBaseAggDataState(this.STATES.READY, this.STATES.RETIRED, this.SUB_CATEGORY.QUERY_BUILDER);
// Update the existing records in "Draft" state to "Ready"
this.updateBaseAggDataState(this.STATES.DRAFT, this.STATES.READY, this.SUB_CATEGORY.QUERY_BUILDER);
},
getCIandCIRelCount: function() {
var ciCount = 0;
var ciRelCount = 0;
var gr = new GlideRecord(this.TABLES.SN_CMDB_WS_BASE_AGGREGATE_DATA);
gr.addQuery(this.COLS.CHART, this.SUB_CATEGORY.QUERY_BUILDER);
gr.addQuery(this.COLS.STATE, this.STATES.READY);
gr.query();
while (gr.next()) {
var groupBy = gr.getValue(this.COLS.GROUP_BY);
var count = gr.getValue(this.COLS.COUNT);
if (groupBy === this.QB_REPORTS_GROUPBY.TOTAL_CI) {
ciCount = count;
} else if (groupBy === this.QB_REPORTS_GROUPBY.TOTAL_CI_REL) {
ciRelCount = count;
}
}
return {
ciCount: this.abbreviateNumber(ciCount),
ciRelCount: this.abbreviateNumber(ciRelCount)
};
},
_getQueriesExecutedCount: function() {
var result = {};
var queriesCount = 0;
var queriesWithReportsCount = 0;
var createdWithin24Hr = this.getRelative24hrEncodedQuery(this.COLS.SYS_CREATED_ON);
// No of queries executed with source as QB
var gr = new GlideRecord(this.TABLES.QB_QUERY_STATUS);
gr.addEncodedQuery(createdWithin24Hr);
gr.query();
while (gr.next()) {
var sq = new GlideRecord(this.TABLES.QB_SAVED_QUERY);
sq.addQuery(this.COLS.RESULT_TABLE, gr.getValue(this.COLS.TABLE_NAME));
sq.addQuery(this.COLS.SOURCE, this.QUERY_BUILDER_SOURCE);
sq.query();
if (sq.next()) {
queriesCount++;
if (sq.getValue(this.COLS.REPORT_SOURCE) != null) {
queriesWithReportsCount++;
}
}
}
// Also consider record that exists in query_status table but not in saved_query table
gr = new GlideRecord(this.TABLES.QB_QUERY_STATUS);
gr.addEncodedQuery(createdWithin24Hr);
gr.query();
while (gr.next()) {
sq = new GlideRecord(this.TABLES.QB_SAVED_QUERY);
sq.addQuery(this.COLS.RESULT_TABLE, gr.getValue(this.COLS.TABLE_NAME));
sq.query();
if (!sq.next()) {
var query = gr.getValue(this.COLS.QUERY);
// Exclude NLQ queries
if (query && this.isJson(query) && JSON.parse(query) && JSON.parse(query)[this.SOURCE_TYPE] != this.CMDB_QB) {
queriesCount++;
}
}
}
result[this.QB_REPORTS_GROUPBY.TOTAL_QUERIES_EXECUTED] = queriesCount;
result[this.QB_REPORTS_GROUPBY.TOTAL_QUERIES_EXECUTED_REPORTS] = queriesWithReportsCount;
return result;
},
/**
* Returns the total and installed count of Service Graph Connectors
* @return {object} count of total and installed SGC
*/
getSGCCount: function() {
var totalAgg = this.getAggregateData(this.SUB_CATEGORY.SERVICE_GRAPH_CONNECTOR, this.SGC_GROUP_BY_VALUE.SGC_TOTAL, this.STATES.READY);
// if we don't have any data or if the data is older than 24 hrs refetch the data
var shouldRefetch = gs.nil(totalAgg) || totalAgg.length === 0 || new GlideDateTime(totalAgg[0].updatedDt).before(new GlideDateTime(gs.hoursAgo(24)));
var sgcData = this.getAllSGCs(shouldRefetch);
var totalCount = sgcData.length;
var installedCount = this.countInstalledSGC(sgcData);
return {
total: totalCount,
installed: installedCount
};
},
/**
* Returns a list of Service Graph Connectors.
* - If refetch is true, calls the API to get the SGC data
* - If refetch is false, returns the SGC data currently stored
*
* @param {boolean} refetch - whether or not to call the API again to refetch the data
* @return {array} list of SGC
*/
getAllSGCs: function(refetch) {
var savedSgcData = [];
var gr = new GlideRecord(this.TABLES.SN_CMDB_WS_SERVICE_GRAPH_CONNECTOR);
gr.query();
while (gr.next()) {
savedSgcData.push({
scope: gr.getValue(this.COLS.SCOPE),
company: gr.getValue(this.COLS.COMPANY),
appId: gr.getValue(this.COLS.APPLICATION_ID),
updatedDt: gr.getValue(this.COLS.SYS_UPDATED_DATE)
});
}
var sgcData = savedSgcData;
if (refetch) {
var sgcApiResults = this.fetchSGCDataFromAppStore();
// if Store API returned data, merge with the existing data and update the aggregates
if (!gs.nil(sgcApiResults) && sgcApiResults.length > 0) {
this.mergeSGCDataWithApiResults(savedSgcData, sgcApiResults);
sgcData = sgcApiResults;
}
this.updateSGCAggData(sgcApiResults);
}
return sgcData;
},
/**
* Updates the aggregate data for SGC
*/
updateSGCAggData: function(sgcData) {
var totalCount = sgcData.length;
var installedCount = this.countInstalledSGC(sgcData);
this.populateBaseAggData(this.SUB_CATEGORY.SERVICE_GRAPH_CONNECTOR, this.SGC_GROUP_BY_VALUE.SGC_TOTAL, totalCount, this.STATES.DRAFT);
this.populateBaseAggData(this.SUB_CATEGORY.SERVICE_GRAPH_CONNECTOR, this.SGC_GROUP_BY_VALUE.SGC_INSTALLED, installedCount, this.STATES.DRAFT);
// Update the existing records in "Ready" state to "Retired"
this.updateBaseAggDataState(this.STATES.READY, this.STATES.RETIRED, this.SUB_CATEGORY.SERVICE_GRAPH_CONNECTOR);
// Update the existing records in "Draft" state to "Ready"
this.updateBaseAggDataState(this.STATES.DRAFT, this.STATES.READY, this.SUB_CATEGORY.SERVICE_GRAPH_CONNECTOR);
},
/**
* Given the list of SGC data, counts how many of them are installed
*/
countInstalledSGC: function(sgcList) {
var installedCount = 0;
for (var idx in sgcList) {
var isInstalled = this.isPluginActive(sgcList[idx].scope);
if (isInstalled) {
installedCount++;
}
}
return installedCount;
},
/**
* Makes API call to fetch SGC data
*/
fetchSGCDataFromAppStore: function() {
var sgcEndpointUrl = this.buildAppStoreUrl("api/sn_appstore/v1/store_applications/service_graph");
var response = this.httpGet(sgcEndpointUrl);
if (response.status === 200) {
return response.body.result;
} else {
gs.error("Unable to fetch Service Graph Connector data from AppStore. " + JSON.stringify(response));
return [];
}
},
/**
* Merges SGC data stored in the table with the SGC data returned by the API
*
* @param {array} sgcStoredData - SGC data stored in the table
* @param {array} sgcApiResults - SGC data returned by the API
*/
mergeSGCDataWithApiResults: function(sgcStoredData, sgcApiResults) {
var sgcStoredDataMap = {};
var sgcApiResultsMap = {};
var removedData = {};
var addedData = {};
for (var i in sgcStoredData) {
var oElm = sgcStoredData[i];
sgcStoredDataMap[oElm.scope] = oElm;
}
for (var j in sgcApiResults) {
var nElm = sgcApiResults[j];
sgcApiResultsMap[nElm.scope] = nElm;
}
// if a scope from sgcApiResultsMap doesn't exist on sgcStoredDataMap, it was added
for (var _nKey in sgcApiResultsMap) {
if (!sgcStoredDataMap[_nKey]) {
addedData[_nKey] = sgcApiResultsMap[_nKey];
}
}
// if a key from sgcStoredDataMap doesn't exist on sgcApiResultsMap, it was removed
for (var _oKey in sgcStoredDataMap) {
if (!sgcApiResultsMap[_oKey]) {
removedData[_oKey] = sgcStoredDataMap[_oKey];
}
}
// delete scope that was not part of the API response
var deletedScopes = Object.keys(removedData);
gr = new GlideRecord(this.TABLES.SN_CMDB_WS_SERVICE_GRAPH_CONNECTOR);
gr.addQuery(this.COLS.SCOPE, this.COLS.IN, deletedScopes.join());
gr.query();
gr.deleteMultiple();
// add new scope from the API response
for (var _newScope in addedData) {
var sgc = addedData[_newScope];
gr = new GlideRecord(this.TABLES.SN_CMDB_WS_SERVICE_GRAPH_CONNECTOR);
gr.initialize();
gr.setValue(this.COLS.SCOPE, sgc.scope);
gr.setValue(this.COLS.COMPANY, sgc.company);
gr.setValue(this.COLS.APPLICATION_ID, sgc.appId);
gr.insert();
}
},
_populateIntelligentSearchAggregates: function() {
//if there are any agg records in "draft" state, for this chart, mark them as "retired"
this.updateBaseAggDataState(this.STATES.DRAFT, this.STATES.RETIRED, this.SUB_CATEGORY.INTELLIGENT_SEARCH);
var createdTimeWithin24Hr = this.getRelative24hrEncodedQuery(this.COLS.SYS_CREATED_ON);
this.populateBaseAggData(this.SUB_CATEGORY.INTELLIGENT_SEARCH, this.NLQ_GROUP_BY_VALUE.NLQ_NO_OF_QUERIES, this.getRowCount(this.TABLES.NLQ_QUERY_LOG, createdTimeWithin24Hr), this.STATES.DRAFT);
// Update the existing records in "Ready" state to "Retired"
this.updateBaseAggDataState(this.STATES.READY, this.STATES.RETIRED, this.SUB_CATEGORY.INTELLIGENT_SEARCH);
// Update the existing records in "Draft" state to "Ready"
this.updateBaseAggDataState(this.STATES.DRAFT, this.STATES.READY, this.SUB_CATEGORY.INTELLIGENT_SEARCH);
},
verifyHistoricalUsage: function(indicatorId, breakdownId, breakdownElementId) {
var indicatorDetails = this.getIndicatorDetails(indicatorId, breakdownId, breakdownElementId, true, this.PA_SCORES_LOOKBACK_LIMIT);
if (indicatorDetails && indicatorDetails.length > 0) {
return this.atLeastOneScoreGreaterThan(indicatorDetails[0].scores, 0);
}
return false;
},
type: 'CMDBWsProductAdoptionUtil'
});
Sys ID
6828c489eb30611094bbb5d5d852284c