Name
sn_cmdb_int_util.MakeAndModelAndNumberJs
Description
No description available
Script
//test call:gs.info(new sn_cmdb_int_util.MakeAndModelAndNumberJs().fromNames("Made up Company", "Model1", "modelnumber1", "hardware").model_id_name);
//in order for the de-duplication code to work on all cmdb_model children and on cmdb_model on itself select the "can delete" flag
// on application access then run the following scripts as global:
//GlideTableManager.invalidateTable("cmdb_hardware_product_model");
//GlideCacheManager.flushTable("cmdb_hardware_product_model");
//GlideTableManager.invalidateTable("cmdb_model");
//GlideCacheManager.flushTable("cmdb_model");
//GlideTableManager.invalidateTable("sys_db_object");
//GlideCacheManager.flushTable("sys_db_object");
var MakeAndModelAndNumberJs = Class.create();
/**
*/
MakeAndModelAndNumberJs.prototype = {
initialize: function(checkFlipNameNumber, checkModelNumberOnlyNoConflicts, checkModelNumberOnly, checkNameOnlyNoConflicts, checkNameOnly, updateEmptyNameFromName, updateEmptyModelNumberFromModelNumber, overwriteIncompleteOnFlipMatch, overwriteOnCurrentModelNumberMatchesName, updateEmptyModelNameFromModelNumber, updateEmptyModelNumberFromName) {
if (gs.nil(checkFlipNameNumber)) {
this.MODEL_LOOKUP_FLIP_NAME_NUMBER = gs.getProperty('sn_cmdb_int_util.model_lookup_flip_name_number', 'true') == "true";
} else {
this.MODEL_LOOKUP_FLIP_NAME_NUMBER = ("true" == checkFlipNameNumber || true == checkFlipNameNumber);
}
//these checkModelNumber and checkName flags relate to the recieved data, not the db table
if (gs.nil(checkModelNumberOnlyNoConflicts)) {
this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS = gs.getProperty('sn_cmdb_int_util.model_lookup_check_model_number_only_no_conflicts', 'true') == "true";
} else {
this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS = ("true" == checkModelNumberOnlyNoConflicts || true == checkModelNumberOnlyNoConflicts);
}
if (gs.nil(checkModelNumberOnly)) {
this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY = gs.getProperty('sn_cmdb_int_util.model_lookup_check_model_number_only', 'true') == "true";
} else {
this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY = ("true" == checkModelNumberOnly || true == checkModelNumberOnly);
}
if (gs.nil(checkNameOnlyNoConflicts)) {
this.MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS = gs.getProperty('sn_cmdb_int_util.model_lookup_check_name_only_no_conflicts', 'true') == "true";
} else {
this.MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS = ("true" == checkNameOnlyNoConflicts || true == checkNameOnlyNoConflicts);
}
if (gs.nil(checkNameOnly)) {
this.MODEL_LOOKUP_CHECK_NAME_ONLY = gs.getProperty('sn_cmdb_int_util.model_lookup_check_name_only', 'true') == "true";
} else {
this.MODEL_LOOKUP_CHECK_NAME_ONLY = ("true" == checkNameOnly || true == checkNameOnly);
}
if (gs.nil(updateEmptyNameFromName)) {
this.MODEL_UPDATE_EMPTY_NAME_WITH_NAME = gs.getProperty('sn_cmdb_int_util.model_update_empty_name_with_name', 'true') == "true";
} else {
this.MODEL_UPDATE_EMPTY_NAME_WITH_NAME = ("true" == updateEmptyNameFromName || true == updateEmptyNameFromName);
}
if (gs.nil(updateEmptyModelNumberFromModelNumber)) {
this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_MODEL_NUMBER = gs.getProperty('sn_cmdb_int_util.model_update_empty_model_number_with_model_number', 'true') == "true";
} else {
this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_MODEL_NUMBER = ("true" == updateEmptyModelNumberFromModelNumber || true == updateEmptyModelNumberFromModelNumber);
}
if (gs.nil(overwriteIncompleteOnFlipMatch)) {
this.MODEL_UPDATE_OVERWRITE_INCOMPLETE_ON_FLIP_MATCH = gs.getProperty('sn_cmdb_int_util.model_update_overwrite_incomplete_on_flip_match', 'true') == "true";
} else {
this.MODEL_UPDATE_OVERWRITE_INCOMPLETE_ON_FLIP_MATCH = ("true" == overwriteIncompleteOnFlipMatch || true == overwriteIncompleteOnFlipMatch);
}
if (gs.nil(overwriteOnCurrentModelNumberMatchesName)) {
this.MODEL_UPDATE_OVERWRITE_ON_CURRENT_NAME_MODEL_NUMBER_MATCH = gs.getProperty('sn_cmdb_int_util.model_update_overwrite_on_current_name_model_number_match', 'true') == "true";
} else {
this.MODEL_UPDATE_OVERWRITE_ON_CURRENT_NAME_MODEL_NUMBER_MATCH = ("true" == overwriteOnCurrentModelNumberMatchesName || true == overwriteOnCurrentModelNumberMatchesName);
}
if (gs.nil(updateEmptyModelNameFromModelNumber)) {
this.MODEL_UPDATE_OVERWRITE_ON_CURRENT_NAME_MODEL_NUMBER_MATCH = gs.getProperty('sn_cmdb_int_util.model_update_overwrite_on_current_name_model_number_match', 'true') == "true";
} else {
this.MODEL_UPDATE_OVERWRITE_ON_CURRENT_NAME_MODEL_NUMBER_MATCH = ("true" == updateEmptyModelNameFromModelNumber || true == updateEmptyModelNameFromModelNumber);
}
if (gs.nil(updateEmptyModelNameFromModelNumber)) {
this.MODEL_UPDATE_EMPTY_NAME_WITH_MODEL_NUMBER = gs.getProperty('sn_cmdb_int_util.model_update_empty_name_with_model_number', 'true') == "true";
} else {
this.MODEL_UPDATE_EMPTY_NAME_WITH_MODEL_NUMBER = ("true" == updateEmptyModelNameFromModelNumber || true == updateEmptyModelNameFromModelNumber);
}
if (gs.nil(updateEmptyModelNumberFromName)) {
this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_NAME = gs.getProperty('sn_cmdb_int_util.model_update_empty_model_number_with_name', 'false') == "true";
} else {
this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_NAME = ("true" == updateEmptyModelNumberFromName || true == updateEmptyModelNumberFromName);
}
this.NAME = 'name';
this.MANUFACTURER = 'manufacturer';
this.MODEL_NUMBER = 'model_number';
this.UNDEFINED = "undefined";
this.SYS_CLASS_NAME = 'sys_class_name';
this.SYS_ID = 'sys_id';
this.CREATED_DATE = "sys_created_on";
this.TABLE = "table";
this.FIELD = "field";
this.DISCOVERED_NAME_HASH = "discovered_name_hash";
this.CMDB_MODEL = 'cmdb_model';
this.CMDB_TABLE_NAME_PREFIX = 'cmdb_';
this.CORE_COMPANY = "core_company";
this.CMDB_HARDWARE_PRODUCT_MODEL = "cmdb_hardware_product_model";
this.CMDB_CONSUMABLE_PRODUCT_MODEL = "cmdb_consumable_product_model";
this.CMDB_SOFTWARE_PRODUCT_MODEL = "cmdb_software_product_model";
this.CMDB_APPLICATION_PRODUCT_MODEL = "cmdb_application_product_model";
this.CANONICAL_CLIENT_PLUGIN = "com.glide.data_services_canonicalization.client";
this.CANONICAL_PROPERTY_COMPANY_ENABLED = "glide.cmdb.canonical.company.enabled";
this.CANONICAL_PROPERTY_DEBUG = "glide.cmdb.canonical.debug";
this.CANONICAL_PROPERTY_DISCOVERY_ENABLED = "glide.cmdb.canonical.discovery.enabled";
this.CANONICAL_PROPERTY_ALWAYS_RUN = "glide.cmdb.canonical.always_run";
this.SYSCACHE_CANONICAL_NAME = "syscache_canonical_name";
this.SYSCACHE_CANONICAL_NAME_ID = "syscache_canonical_name_id";
//Tables
this.CDS_CLIENT_STAGING = "cds_client_staging";
this.CDS_CLIENT_MAPPING = "cds_client_mapping";
this.CDS_CLIENT_NAME = "cds_client_name";
//Fields
this.STATE = "state";
this.SOURCE_FIELD = "source_field";
this.SOURCE_TABLE = "source_table";
this.FREQUENCY = "frequency";
this.DISCOVERED_NAME = "discovered_name";
this.DISCOVERED_NAME_HASH = "discovered_name_hash";
this.CANONICAL_NAME = "canonical_name";
this.CANONICAL_NAME_NAME = this.CANONICAL_NAME + "." + this.NAME;
this.CANONICAL = "canonical";
this.HASH = "hash";
this.CUSTOMER_OVERRIDE = "customer_override";
//States
this.READY = "ready";
this.PROCESSED = "processed";
},
fromNames: function(make, model, modelNumber, modelType) {
var modelTable = this._determineModelTableTableName(modelType);
return this._fromNames(make, model, modelTable, modelNumber);
},
_fromNames: function(mfrName, modelName, modelTable, modelNumber, useCMDBHelperMode) {
if (gs.nil(useCMDBHelperMode)) {
useCMDBHelperMode = false;
}
var mfr = this._getManufacturerRec(mfrName, useCMDBHelperMode);
var mfrID = !gs.nil(mfr) ? mfr.getUniqueValue() : null;
var model = this._getModelRec(mfrID, modelName, modelNumber, modelTable);
var answer = {};
if (!gs.nil(model)) {
answer.model_id_sys_id = model.getUniqueValue();
answer.model_id_name = model.getValue(this.NAME);
}
answer.manufacturer_sys_id = mfrID;
answer.manufacturer_name = !gs.nil(mfr) ? mfr.getValue(this.NAME) : null;
return answer;
},
_directLookupOnModelRec: function(mfrID, modelName, modelNumber, modelTable, allowNonConflictMatchOnField, ignoreField) {
var gr = new GlideRecord(modelTable);
this._initModelTableQuery(gr, mfrID, modelName, modelNumber, modelTable, allowNonConflictMatchOnField, ignoreField);
gr.orderBy(this.MODEL_NUMBER);
gr.query();
if (!gr.next()) {
return null;
}
return gr;
},
_singlePrimaryFieldLookupOnModelRec: function(mfrID, modelName, modelNumber, modelTable, allowNonConflictMatchOnField, ignoreField, primaryFieldWhenSorting) {
if (gs.nil(primaryFieldWhenSorting)) {
return this._directLookupOnModelRec(mfrID, modelName, modelNumber, modelTable, allowNonConflictMatchOnField, ignoreField);
}
var gr = new GlideRecord(modelTable);
this._initModelTableQuery(gr, mfrID, modelName, modelNumber, modelTable, allowNonConflictMatchOnField, ignoreField);
// 2 main sorts
// if update <non primary field> == true
// 1. where <non primary field> is empty
// 2. where current name != number
// 3. where current name == number
// else
// 1. where current name != number (and both non-null)
// 2. where current name == number
// 3. where <non primary field> is empty
var secondaryField = primaryFieldWhenSorting === this.NAME ? this.MODEL_NUMBER : this.NAME;
if (secondaryField === this.NAME && (this.MODEL_UPDATE_EMPTY_NAME_WITH_NAME || this.MODEL_UPDATE_EMPTY_NAME_WITH_MODEL_NUMBER)) {
gs.debug("Sorting for case when updating empty name");
return this._sortForUpdatingSecondaryField(gr, this.NAME, modelTable);
}
if (secondaryField === this.MODEL_NUMBER && (this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_MODEL_NUMBER || this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_NAME)) {
gs.debug("Sorting for case when updating empty model number");
return this._sortForUpdatingSecondaryField(gr, this.MODEL_NUMBER, modelTable);
}
gs.debug("Sorting for case when not updating empty " + secondaryField);
return this._sortForNotUpdatingSecondaryField(gr, secondaryField, modelTable);
},
_sortForNotUpdatingSecondaryField: function(gr, field, modelTable) {
gr.orderByDesc(field);
gr.query();
var targetRecordSysId = null;
while (gr.next()) {
// if the values aren't equal and
if (gr.getValue(this.NAME) !== gr.getValue(this.MODEL_NUMBER) && !gs.nil(gr.getValue(this.NAME)) && !gs.nil(gr.getValue(this.MODEL_NUMBER))) {
return gr;
}
// possible match
if (gr.getValue(this.NAME) === gr.getValue(this.MODEL_NUMBER)) {
targetRecordSysId = gr.getUniqueValue();
}
// if we hit a null then we take the previous best match
if (gs.nil(gr.getValue(field))) {
if (gs.nil(targetRecordSysId)) {
return gr;
}
var answer = new GlideRecord(modelTable);
answer.get(targetRecordSysId);
return answer;
}
}
if (!gs.nil(targetRecordSysId)) {
var answer2 = new GlideRecord(modelTable);
answer2.get(targetRecordSysId);
return answer2;
}
return null;
},
_sortForUpdatingSecondaryField: function(gr, field, modelTable) {
gr.orderBy(field);
gr.query();
var targetRecordSysId = null;
while (gr.next()) {
if (gs.nil(gr.getValue(field))) {
return gr;
}
// possible match
if (gr.getValue(this.NAME) === gr.getValue(this.MODEL_NUMBER)) {
targetRecordSysId = gr.getUniqueValue();
}
// if they're not equal, return
else {
return gr;
}
}
if (!gs.nil(targetRecordSysId)) {
var answer = new GlideRecord(modelTable);
answer.get(targetRecordSysId);
return answer;
}
return null;
},
/**
* do all of the lookups for a model on a single model table
*
* @return GlideRecord for the target record, else null if record can't be found
*/
_multiLookupOnModelRec: function(mfrID, modelName, modelNumber, modelTable) {
var haveModelName = !gs.nil(modelName);
var haveModelNumber = !gs.nil(modelNumber);
//conflicts are considered to be the following:
//non-null does not conflict with null
//non-null conflicts with non-null (assume different values)
//lookup on target model table with manf, model_name, model_number (null == null)
//if no match && MODEL_LOOKUP_FLIP_NAME_NUMBER prop then lookup on manf, model_name, model_number (null === null) flip name and number
//if no match && MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS prop then lokup on manf and match only if name does not conflict
//if no match && MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY prop then lookup on manf, model_number
//if no match && MODEL_LOOKUP_FLIP_NAME_NUMBER prop && MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS then lookup on lookup on manf, model_name with model_number and no conflicts with name on model_number
//if no match && MODEL_LOOKUP_FLIP_NAME_NUMBER prop && MODEL_LOOKUP_CHECK_NAME_ONLY then lookup on lookup on manf, model_name with model_number
//if no match && MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS prop then lookup on manf, name, and no conflict on model_number
//if no match && MODEL_LOOKUP_CHECK_NAME_ONLY prop then lookup on manf, model_name
//if no match && MODEL_LOOKUP_FLIP_NAME_NUMBER prop && MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS then lookup on lookup on manf, model_number with name and no conflicts with model_number on name
//if no match && MODEL_LOOKUP_FLIP_NAME_NUMBER prop && MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY then lookup on lookup on manf, model_number with model_name
var gr = this._directLookupOnModelRec(mfrID, modelName, modelNumber, modelTable);
if (gr) {
gs.debug("Model match on direct lookup");
}
if (gr === null && haveModelNumber && this.MODEL_LOOKUP_FLIP_NAME_NUMBER) {
gr = this._directLookupOnModelRec(mfrID, modelNumber, modelName, modelTable);
if (gr) {
gs.debug("Model match on direct lookup flip");
}
}
if (gr === null && haveModelNumber && this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS) {
gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, modelName, modelNumber, modelTable, 'MODEL_NUMBER', null);
if (gr) {
gs.debug("Model match on MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS");
}
}
if (gr === null && haveModelNumber && this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY) {
gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, null, modelNumber, modelTable, null, 'NAME', 'MODEL_NUMBER');
if (gr) {
gs.debug("Model match on MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY");
}
}
if (gr === null && haveModelNumber && this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS) {
gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, modelNumber, modelName, modelTable, 'NAME', null);
if (gr) {
gs.debug("Model match on MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS && MODEL_LOOKUP_FLIP_NAME_NUMBER");
}
}
if (gr === null && haveModelNumber && this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY) {
gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, modelNumber, null, modelTable, null, 'MODEL_NUMBER', 'NAME');
if (gr) {
gs.debug("Model match on this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY");
}
}
if (gr === null && haveModelName && this.MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS) {
gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, modelName, modelNumber, modelTable, 'NAME', null);
if (gr) {
gs.debug("Model match on MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS");
}
}
if (gr === null && haveModelName && this.MODEL_LOOKUP_CHECK_NAME_ONLY) {
gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, modelName, null, modelTable, null, 'MODEL_NUMBER', 'NAME');
if (gr) {
gs.debug("Model match on MODEL_LOOKUP_CHECK_NAME_ONLY");
}
}
if (gr === null && haveModelName && this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS) {
gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, modelNumber, modelName, modelTable, 'MODEL_NUMBER');
if (gr) {
gs.debug("Model match on this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS");
}
}
if (gr === null && haveModelName && this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_NAME_ONLY) {
gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, null, modelName, modelTable, null, 'NAME', 'MODEL_NUMBER');
if (gr) {
gs.debug("Model match on this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_NAME_ONLY");
}
}
return gr;
},
_determineModelTableTableName: function(modelType) {
if (gs.nil(modelType))
return this.CMDB_MODEL;
if (modelType.indexOf(this.CMDB_TABLE_NAME_PREFIX) == 0)
return modelType;
var mtype = modelType.toLowerCase();
var table = '';
switch (mtype) {
case "hardware":
table = this.CMDB_HARDWARE_PRODUCT_MODEL;
break;
case "consumable":
table = this.CMDB_CONSUMABLE_PRODUCT_MODEL;
break;
case "software":
table = this.CMDB_SOFTWARE_PRODUCT_MODEL;
break;
case "application":
table = this.CMDB_APPLICATION_PRODUCT_MODEL;
break;
default:
table = this.CMDB_MODEL;
}
return table;
},
_insertModelRecord: function(mfrID, modelName, modelNumber, modelTable) {
gs.debug("Creating model with name:" + modelName + " modelNumber:" + modelNumber + " on modelTable:" + modelTable);
gr = new GlideRecord(modelTable);
gr.initialize();
gr.setValue(this.NAME, modelName);
if (!gs.nil(mfrID)) {
gr.setValue(this.MANUFACTURER, mfrID);
}
if (!gs.nil(modelNumber)) {
gr.setValue(this.MODEL_NUMBER, modelNumber);
}
gr.insert();
gr = this._doDuplicateCheckModel(gr);
return gr;
},
_getModelRec: function(mfrID, modelName, modelNumber, modelTable) {
var gr = this._multiLookupOnModelRec(mfrID, modelName, modelNumber, modelTable);
// check the cmdb_model table
if (gr === null && modelTable !== this.CMDB_MODEL) {
gr = this._multiLookupOnModelRec(mfrID, modelName, modelNumber, this.CMDB_MODEL);
if (gr !== null) {
// update to the current model table
gr.setValue(this.SYS_CLASS_NAME, modelTable);
gr.update();
}
}
// found a glide record and applying update flags
if (gr !== null) {
var lowerModelName = gs.nil(modelName) ? "" : modelName.toLowerCase();
var lowerModelNumber = gs.nil(modelNumber) ? "" : modelNumber.toLowerCase();
var lowerGrModelName = gs.nil(gr.getValue(this.NAME)) ? "" : gr.getValue(this.NAME).toLowerCase();
var lowerGrModelNumber = gs.nil(gr.getValue(this.MODEL_NUMBER)) ? "" : gr.getValue(this.MODEL_NUMBER).toLowerCase();
var updated = false;
if (this.MODEL_UPDATE_OVERWRITE_INCOMPLETE_ON_FLIP_MATCH &&
(lowerModelName === lowerGrModelNumber || lowerModelNumber === lowerGrModelName) &&
(gs.nil(gr.getValue(this.MODEL_NUMBER)) || gs.nil(gr.getValue(this.NAME))) &&
(lowerGrModelName !== lowerModelName || lowerGrModelNumber !== lowerModelNumber) &&
!gs.nil(lowerModelName) && !gs.nil(lowerModelNumber)) {
gs.debug("Updating record on name and model number flipped match to recieved data");
gr.setValue(this.NAME, modelName);
gr.setValue(this.MODEL_NUMBER, modelNumber);
gr.update();
updated = true;
} else if (this.MODEL_UPDATE_OVERWRITE_ON_CURRENT_NAME_MODEL_NUMBER_MATCH &&
lowerGrModelName === lowerGrModelNumber &&
lowerModelName !== lowerModelNumber &&
!gs.nil(lowerModelName) && !gs.nil(lowerModelNumber)) {
gs.debug("Updating record on name and model number because current model number and name");
gr.setValue(this.NAME, modelName);
gr.setValue(this.MODEL_NUMBER, modelNumber);
gr.update();
updated = true;
} else if (gs.nil(lowerGrModelName) && !gs.nil(modelName) && this.MODEL_UPDATE_EMPTY_NAME_WITH_NAME) {
// first check to see if an update would cause a duplicate
// if there is no name, then the match was on number == name (a flip)
var tempNumber = gs.nil(modelNumber) ? modelName : modelNumber;
var gr2 = this._directLookupOnModelRec(mfrID, modelName, tempNumber, modelTable);
if (gr2 !== null) {
gr = gr2;
} else {
gs.info("Updating model with sys_id:" + gr.getUniqueValue() + " with name:" + modelName);
gr.setValue(this.NAME, modelName);
gr.update();
updated = true;
}
} else if (gs.nil(lowerGrModelNumber) && !gs.nil(modelNumber) && this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_MODEL_NUMBER) {
// first check to see if an update would cause a duplicate
// if there is no name, then the match was on number == name (a flip)
var tempName = gs.nil(modelName) ? modelNumber : modelName;
var gr3 = this._directLookupOnModelRec(mfrID, tempName, modelNumber, modelTable);
if (gr3 !== null) {
gr = gr3;
} else {
gs.info("Updating model with sys_id:" + gr.getUniqueValue() + " with model_number:" + modelNumber);
gr.setValue(this.MODEL_NUMBER, modelNumber);
gr.update();
updated = true;
}
} else if (this.MODEL_UPDATE_EMPTY_NAME_WITH_MODEL_NUMBER && gs.nil(lowerGrModelName) && !gs.nil(lowerModelNumber)) {
var gr4 = this._directLookupOnModelRec(mfrID, modelNumber, modelNumber, modelTable);
if (gr4 !== null) {
gr = gr4;
} else {
gs.info("Updating model with sys_id:" + gr.getUniqueValue() + " with model_number:" + modelNumber);
gr.setValue(this.NAME, modelNumber);
gr.update();
updated = true;
}
} else if (this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_NAME && gs.nil(lowerGrModelNumber) && !gs.nil(lowerModelName)) {
var gr5 = this._directLookupOnModelRec(mfrID, modelName, modelName, modelTable);
if (gr5 !== null) {
gr = gr5;
} else {
gs.info("Updating model with sys_id:" + gr.getUniqueValue() + " with model_number:" + modelName);
gr.setValue(this.MODEL_NUMBER, modelName);
gr.update();
updated = true;
}
}
if (updated) {
this._doDuplicateCheckModel(gr);
}
}
// no record found, insert
else if (gr === null) {
gr = this._insertModelRecord(mfrID, modelName, modelNumber, modelTable);
}
return gr;
},
_doDuplicateCheckModel: function(gr) {
var gr2 = new GlideRecord(gr.getTableName());
gr2.addQuery(this.NAME, gr.getValue(this.NAME));
gr2.addQuery(this.MANUFACTURER, gr.getValue(this.MANUFACTURER));
gr2.addQuery(this.MODEL_NUMBER, gr.getValue(this.MODEL_NUMBER));
gr2.orderBy(this.CREATED_DATE);
gr2.query();
var answer = gr;
if (gr2.getRowCount() > 1) {
gr2.next();
var answerGr = new GlideRecord(gr.getTableName());
answerGr.get(gr2.getUniqueValue());
answer = answerGr;
while (gr2.next()) {
gr2.deleteRecord();
}
}
return answer;
},
_doDuplicateCheckCompany: function(gr) {
var gr2 = new GlideRecord(gr.getTableName());
gr2.addQuery(this.NAME, gr.getValue(this.NAME));
gr2.orderBy(this.CREATED_DATE);
gr2.query();
var answer = gr;
if (gr2.getRowCount() > 1) {
gr2.next();
var answerGr = new GlideRecord(gr.getTableName());
answerGr.get(gr2.getUniqueValue());
answer = answerGr;
while (gr2.next()) {
gr2.deleteRecord();
}
}
return answer;
},
_initModelTableQuery: function(gr, mfrID, modelName, modelNumber, modelTable, allowNonConflictMatchOnField, ignoreField) {
gr.addQuery(this.SYS_CLASS_NAME, modelTable);
if (!gs.nil(mfrID)) {
gr.addQuery(this.MANUFACTURER, mfrID);
} else {
gr.addNullQuery(this.MANUFACTURER);
}
if ('NAME' !== ignoreField) {
if (!gs.nil(modelName)) {
if ('NAME' === allowNonConflictMatchOnField) {
gr.addEncodedQuery('name=' + modelName + '^ORnameISEMPTY');
} else {
gr.addQuery(this.NAME, modelName);
}
} else {
// if we allow non conflicts and this value is null then any value matches
if ('NAME' !== allowNonConflictMatchOnField) {
gr.addNullQuery(this.NAME);
}
}
}
if ('MODEL_NUMBER' !== ignoreField) {
if (!gs.nil(modelNumber)) {
if ('MODEL_NUMBER' === allowNonConflictMatchOnField) {
gr.addEncodedQuery('model_number=' + modelNumber + '^ORmodel_numberISEMPTY');
} else {
gr.addQuery(this.MODEL_NUMBER, modelNumber);
}
} else {
// if we allow non conflicts and this value is null then any value matches
if ('MODEL_NUMBER' !== allowNonConflictMatchOnField) {
gr.addNullQuery(this.MODEL_NUMBER);
}
}
}
},
_getManufacturerRec: function(mfrName, useCMDBHelperMode) {
if (gs.nil(mfrName)) {
return '';
}
mfrName = mfrName.trim();
// PRB1422465: Need to cut down mfrName to match maximum length of table to prevent creating extra manufacturer records.
var grInc = new GlideRecord('CORE_COMPANY');
for (var i = 0; i < grInc.getElements().length; i++) {
if (grInc.getElements()[i].getED().getName().toLowerCase() === 'name') {
var nameMaxLength = grInc.getElements()[i].getED().getLength();
if (mfrName.length() > nameMaxLength)
mfrName = mfrName.substring(0, nameMaxLength);
}
break;
}
var useCanonical = this._useCanonicalLookup();
gs.debug("getManufacturerRec(): useCanonical=" + useCanonical + ", mfrName=" + mfrName + ", useCMDBHelperMode=" + useCMDBHelperMode);
// For performance, try to get rec without a mutex since it will usually exist.
var gr = this._getManufacturerRecIfExists(mfrName, useCanonical);
if (gr != null) {
return gr;
}
if (useCanonical) {
// Get canonical name. If no canonical name exists, returns same name
mfrName = this._normalizeCompany(mfrName, true);
}
gr = new GlideRecord(this.CORE_COMPANY);
gr.setValue(this.NAME, mfrName);
if (useCMDBHelperMode)
gr.setValue(this.MANUFACTURER, true);
gr.insert();
gr = this._doDuplicateCheckCompany(gr);
return gr;
},
_useCanonicalLookup: function() {
// PRB1292140: Force DISCOVERY_ENABLED on if ALWAYS_RUN on
return GlidePluginManager.isActive('com.glide.data_services_canonicalization.client') &&
((gs.getProperty('glide.cmdb.canonical.discovery.enabled') == "true") ||
(gs.getProperty('glide.cmdb.canonical.always_run') == "true"));
},
_getManufacturerRecIfExists: function(mfrName, useCanonical) {
var gr = new GlideRecord(this.CORE_COMPANY);
if (useCanonical) {
// Get sysid of canonical core_company rec if it exists
var mfrSysID = this._normalizeCompany(mfrName, false);
if (gs.nil(mfrSysID))
return null;
gr.addQuery(this.SYS_ID, mfrSysID);
gr.query();
if (gr.next()) {
gs.debug("getManufacturerRec(): canconical rec for discovery name =" + mfrName + ", rec name/sysid=" + gr.getValue("name") + " / " + gr.getValue("sys_id"));
return gr;
}
} else {
// Return the core_company rec if it exists.
gr.addQuery(this.NAME, mfrName);
gr.orderBy(this.CREATED_DATE);
gr.query();
if (gr.next()) {
return gr;
}
}
return null; // rec not found
},
_normalizeCompany: function(discoveredName, returnName) {
if (gs.nil(discoveredName))
return "";
//If plugin is not active or feature is disabled try to return default information
if (!GlidePluginManager.isActive(this.CANONICAL_CLIENT_PLUGIN) ||
!(gs.getProperty(this.CANONICAL_PROPERTY_COMPANY_ENABLED) == 'true')) {
gs.debug("Returning with default values");
if (returnName)
return discoveredName;
return this._getCoreCompanyId(discoveredName, false);
}
var companyName = "";
var discoveredNameHash = this._getHash(discoveredName);
if (gs.nil(discoveredNameHash)) {
gs.warn("Canonical Hash came back empty or invalid for: '" + discoveredName + "'");
if (returnName)
return discoveredName;
return null;
}
gs.debug("Canonical Lookup DiscoveredName: '" + discoveredName + "' hash: '" + discoveredNameHash + "'");
var cacheName = "";
//If it's not cached, find it and cache it
if (gs.nil(cacheName)) {
companyName = this._getCompanyName(discoveredName);
} else {
companyName = cacheName;
}
gs.info("Discovered Name: '" + discoveredName + "' Canonical is: '" + companyName + "'");
if (returnName) {
return companyName;
}
//Find the core_company record and return the sys_id
var companyID = this._getCoreCompanyId(companyName, true);
gs.info("Discovered Name: " + discoveredName + " core_company is: " + companyID);
return companyID;
},
_getCompanyName: function(discoveredName) {
return this._getConanicalName(discoveredName, this.CORE_COMPANY, this.NAME);
},
_getConanicalName: function(lookupName, tableName, fieldName) {
var hash = this._getHash(lookupName);
if (gs.nil(hash)) {
return lookupName;
}
var mapping = new GlideRecord(this.CDS_CLIENT_MAPPING);
if (!mapping.isValid()) {
return lookupName;
}
mapping.addQuery(this.DISCOVERED_NAME_HASH, hash);
mapping.addQuery(this.TABLE, tableName);
mapping.addQuery(this.FIELD, fieldName);
mapping.query();
if (mapping.next()) {
var canonicalName = mapping.canonical_name.name; //getValue(this.CANONICAL_NAME_NAME);
gs.info("Found canonical name:" + canonicalName + " in Canonical db");
if (!gs.nil(canonicalName)) {
return canonicalName;
}
}
gs.debug("DiscoveredName '" + lookupName + "' not found in Canonical db");
return lookupName;
},
_getCoreCompanyId: function(companyName, useHash) {
var companyNameHash = this._getHash(companyName);
var coreCompany = new GlideRecord(this.CORE_COMPANY);
//Use hash or regular name
if (useHash) {
coreCompany.addQuery(this.HASH, companyNameHash);
coreCompany.addQuery(this.CANONICAL, true);
} else
coreCompany.addQuery(this.NAME, companyName);
coreCompany.query();
if (coreCompany.next()) {
return coreCompany.getUniqueValue();
}
gs.debug("core_company entry not found for: " + companyName);
return "";
},
_getHash: function(value) {
if (gs.nil(value)) {
return '';
}
return new GlideDigest().md5_digest(value);
},
type: 'MakeAndModelAndNumberJs'
};
Sys ID
47003a891b460550ebe09712b24bcb4f