Name
global.PatternLibrary
Description
ServiceWatch Pattern Library helper functions
Script
var PatternLibrary = Class.create();
PatternLibrary.prototype = {
initialize: function() {
this.notification_handler = new MIDNotificationHandler();
this.ciTypesDeflator = new SNC.CiTypesDocUtilWrapper();
this.citypes_catalog_name = 'citypes_catalog';
this.citypes_key = 'citypes_xml';
this.citypes_version_key = 'citypes_xml_version';
this.saHashName = 'ci_types_version';
},
getCiTypeData: function() {
var cis = GlideDBObjectManager.get().getAllChildrenOf('cmdb_ci');
var cisToCheck = this.getCiTypeNames();
var result = this.getCiTypeDataOnNames(this.convertToJsArray(cisToCheck));
result['cis'] = cis;
return result;
},
getCiTypeDataOnNamesJson: function(ciNames) {
var cis = GlideDBObjectManager.get().getAllChildrenOf('cmdb_ci');
var ciTypeData = this.getCiTypeDataOnNames(ciNames);
var map = ciTypeData.map;
var labels = ciTypeData.labels;
var sys_dictionary_override = ciTypeData.sys_dictionary_override;
return this.toJson(cis, map, labels,sys_dictionary_override);
},
getCiTypeDataOnNames: function(ciNames) {
var requiredAttributesEnabled = GlideProperties.getBoolean("glide.required.attribute.enabled", true);
var map = {};
var labels = {};
// populate the sys_dictionary_override map.
var sys_dictionary_override = {};
for (var i = 0; i < ciNames.length; i++) {
var table = '' + ciNames[i];
var isEndpoint = GlideDBObjectManager.get().isInstanceOf(table, 'cmdb_ci_endpoint');
var list = map[table];
if (list == null) {
list = [];
map[table] = list;
}
var td = GlideTableDescriptor.get(table);
var sc = td.getSchema();
var attrNames = sc.keySet();
var it = attrNames.iterator();
while (it.hasNext()) {
var attrName = '' + it.next();
if (attrName.startsWith('sys_') && (attrName !== 'sys_class_name'))
continue;
var ed = sc.get(attrName);
var defValue = '';
if (isEndpoint) {
defValue = '' + ed.getDefault();
if (defValue === 'null')
defValue = '';
}
list.push({
'name': attrName,
'type': '' + ed.getInternalType(),
'size' : '' + ed.getLength(),
'mandatory' : (requiredAttributesEnabled && (attrName != 'company')) ?
(ed.isMandatory() ? '1' : '0') : '0',
'attrs' : '' + ed.serializeAttributes(),
'defaultValue' : defValue
});
}
}
return {
'map': map,
'labels': labels,
'sys_dictionary_override': sys_dictionary_override
};
},
getCiTypeNames: function() {
var ciNames = GlideDBObjectManager.get().getAllExtensions('cmdb_ci');
ciNames.add(0, 'cmdb_ci');
return ciNames;
},
// create xml with ci types and their fields
getCiTypesXml: function() {
var ciData = this.getCiTypeData();
var cis = ciData.cis;
var map = ciData.map;
var labels = ciData.labels;
var sys_dictionary_override = ciData.sys_dictionary_override;
return this.toXml(cis, map, labels,sys_dictionary_override);
},
// create json with ci types and their fields
getCiTypesJson: function() {
var ciData = this.getCiTypeData();
var cis = ciData.cis;
var map = ciData.map;
var labels = ciData.labels;
var sys_dictionary_override = ciData.sys_dictionary_override;
return this.toJson(cis, map, labels,sys_dictionary_override);
},
// build map of table name -> map of field name to default value
buildDefaultValueOverride : function (sys_dictionary_override) {
var defaultValueOverride = {};
var grOverride = new GlideRecord('sys_dictionary_override');
grOverride.addQuery("default_value_override", '1');
grOverride.addQuery("base_table", ['cmdb_ci_endpoint', 'cmdb_ci_endpoint_inclusion']);
grOverride.query();
while (grOverride.next()) {
var fieldToDefaultValue = defaultValueOverride[grOverride.name];
if (fieldToDefaultValue == null) {
fieldToDefaultValue = {};
defaultValueOverride[grOverride.name] = fieldToDefaultValue;
}
fieldToDefaultValue[grOverride.element] = grOverride.default_value;
}
return defaultValueOverride;
},
// build map of table name -> map of field name to mandatory flag
buildSysOverride : function (sys_dictionary_override) {
var grOverride = new GlideRecord('sys_dictionary_override');
grOverride.addQuery("mandatory_override", '1');
grOverride.query();
while (grOverride.next()) {
var fieldToMandatory = sys_dictionary_override[grOverride.name];
if (fieldToMandatory == null) {
fieldToMandatory = [];
sys_dictionary_override[grOverride.name] = fieldToMandatory;
}
fieldToMandatory[grOverride.element] = grOverride.mandatory;
}
},
// serialize to json, return a string
toJson : function (cis, map, labels, sys_dictionary_override) {
var it = cis.iterator();
var containsRelTypeId = getContainsRelTypeId();
var requiredAttributesEnabled = GlideProperties.getBoolean("glide.required.attribute.enabled", true);
var jsonResult = {};
while (it.hasNext()) {
var ci = it.next();
if (ci.getName().indexOf('$') > -1)
continue;
if (!map.hasOwnProperty(ci.getName()))
continue;
try {
jsonResult[ci.getName()] = {};
var ciEle = jsonResult[ci.getName()];
if (ci.getParent() !== null)
ciEle.__parent = ci.getParent().getName();
ciEle.label = GlideTableDescriptor.get(ci.getName()).getLabel() + '';
var parentCiType = getParentCiType(ci.getName(), containsRelTypeId);
if (GlideStringUtil.notNil(parentCiType))
ciEle.parentCiType = parentCiType;
var fields = map[ci.getName()];
if (fields != null) {
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
//verify that there are np white spaces in the field names
if(field['name'].indexOf(' ') != -1)
continue;
try {
ciEle[field['name']] = {};
var fieldEle = ciEle[field['name']];
fieldEle.type = field['type'];
fieldEle.size = field['size'];
if (requiredAttributesEnabled) {
fieldEle.mandatory = field['mandatory'];
// If there is override on the mandatory flag then use it
var mandatoryOverride = sys_dictionary_override[ci.getName()];
if (mandatoryOverride != null && mandatoryOverride[field['name']] != null) {
fieldEle.mandatory = mandatoryOverride[field['name']];
}
} else {
fieldEle.mandatory = 0;
}
if (field['defaultValue'])
fieldEle.defaultValue = field['defaultValue'];
} catch (err) {
gs.log("PatternLibrary: Failed to create JSON element for field " + field['name'] + "." + err);
}
}
}
// Add fields from sys_dictionary override
var mandatoryOverride = sys_dictionary_override[ci.getName()];
if (mandatoryOverride != null) {
for (var fieldName in mandatoryOverride) {
fieldEle[fieldName] = {};
var fieldEle = ciEle[fieldName];
fieldEle.mandatory = mandatoryOverride[fieldName];
}
}
} catch (err) {
gs.log("PatternLibrary: Failed to create JSON element for CI type " + ci.getName() + "." + err);
}
}
return jsonResult;
},
// serialize to xml, return a document
toXml : function(cis, map, labels,sys_dictionary_override) {
var it = cis.iterator();
var $ = GlideXMLUtil;
var doc = $.newDocument('cis');
var root = doc.getDocumentElement();
var containsRelTypeId = getContainsRelTypeId();
var requiredAttributesEnabled = GlideProperties.getBoolean("glide.required.attribute.enabled", true);
while (it.hasNext()) {
var ci = it.next();
//PRB718906: In case of reparenting the temporary backup table rep$... may be created
//This can cause exception because of unescaped character $
//This table does not represent CI type, so we will ignore it
if (ci.getName().indexOf('$') > -1)
continue;
try {
var ciEle = $.newElement(root, ci.getName());
if (ci.getParent() !== null)
ciEle.setAttribute('parent', ci.getParent().getName());
ciEle.setAttribute('label', GlideTableDescriptor.get(ci.getName()).getLabel());
// In case of Inclusion CI Type, setting the parent CI type based on
// cmdb_metadata_containment
var parentCiType = getParentCiType(ci.getName(), containsRelTypeId);
if (GlideStringUtil.notNil(parentCiType))
ciEle.setAttribute('parentCiType', parentCiType);
var fields = map[ci.getName()];
if (fields != null) {
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
//verify that there are np white spaces in the field names
if(field['name'].indexOf(' ') != -1)
continue;
try {
var fieldEle = $.newElement(ciEle, field['name']);
fieldEle.setAttribute('type', field['type']);
fieldEle.setAttribute('size', field['size']);
if (requiredAttributesEnabled) {
fieldEle.setAttribute('mandatory', field['mandatory']);
// If there is override on the mandatory flag then use it
var mandatoryOverride = sys_dictionary_override[ci.getName()];
if (mandatoryOverride != null && mandatoryOverride[field['name']] != null) {
fieldEle.setAttribute('mandatory', mandatoryOverride[field['name']]);
}
} else {
fieldEle.setAttribute('mandatory', '0');
}
if (field['defaultValue'])
fieldEle.setAttribute('defaultValue', field['defaultValue']);
} catch (err) {
gs.log("PatternLibrary: Failed to create XML element for field " + field['name'] + "." + err);
}
}
}
// Add fields from sys_dictionary override
var mandatoryOverride = sys_dictionary_override[ci.getName()];
if (mandatoryOverride != null) {
for (var fieldName in mandatoryOverride) {
var fieldEle = $.newElement(ciEle, fieldName);
fieldEle.setAttribute('mandatory', mandatoryOverride[fieldName]);
}
}
} catch (err) {
gs.log("PatternLibrary: Failed to create XML element for CI type " + ci.getName() + "." + err);
}
}
return doc;
},
convertToJsArray : function(inputArr) {
var result = [];
var it = inputArr.iterator();
while(it.hasNext()) {
result.push(it.next());
}
return result;
},
// Notify MID Servers of changes in patterns
notifyMIDs : function(patternName, action, optional) {
var message = "*** Discovery pattern " + patternName +" has changed (" + action + ")";
if (optional)
message = "*** Confirmation status for discovery pattern " + patternName +" has changed (" + action + ")"
+ ", Notifying MID Servers ***";
gs.log(message);
this.notification_handler.notifyMIDServers('FileChange', 'sa_pattern');
},
//This is invoked by legacy code
getCiTypes: function() {
return this.getCiTypesXml();
},
// Notify MID Servers of changes in CI Types
notifyMIDsCitChanged : function() {
gs.log('###### CIT changed ######');
var ciTypesJson = this.getCiTypesJson();
var deflatedStr;
try {
deflatedStr = this.ciTypesDeflator.deflateJsonAsString(ciTypesJson);
} catch(err) {
gs.log('##### Unable to deflate CI types while notifying mids #####');
deflatedStr = JSON.stringifiy(ciTypesJson);
}
this.notification_handler.notifyMIDServers('CitChanged',undefined,deflatedStr);
},
// Notify MID Servers of changes in Custom Operations
notifyMIDsCustomOperationsChange : function() {
gs.log('###### Custom Operations changed ######');
this.notification_handler.notifyMIDServers('CustomOperationChanged');
},
// Notify MID Servers of changes in Custom Parsing Strategy
notifyMIDsCustomParsingStrategyChange : function() {
gs.log('###### Custom Parsing Strategy changed ######');
this.notification_handler.notifyMIDServers('CustomParsingStrategyChanged');
},
// Notify MID Servers of changes in Metadata Rules
notifyMIDsMetadataRulesChange : function() {
gs.log('###### Metadata Rules changed ######');
this.notification_handler.notifyMIDServers('MetadataRulesChanged');
},
// Notify MID Servers of changes in Library Application Category
notifyMIDsLibsApplCategoryChange : function() {
gs.log('###### Library Application Category changed ######');
this.notification_handler.notifyMIDServers('LibsApplCategoryChanged');
},
// Notify MID Servers of changes in Device Info Application Category
notifyMIDsLibsDeviceInfoCategoryChange : function() {
gs.log('###### Library Device Info Category changed ######');
this.notification_handler.notifyMIDServers('LibsDeviceInfoCategoryChanged');
},
// Notify MID Servers of changes in Pattern Extension
notifyMIDsPatternExtensionChanged: function() {
gs.log('###### Pattern Extension changed ######');
this.notification_handler.notifyMIDServers('PatternExtensionChanged');
},
type: 'PatternLibrary'
};
function getParentCiType(ciType, relTypeId) {
if (GlideStringUtil.nil(relTypeId))
return null;
var gr = new GlideRecord('cmdb_metadata_containment');
gr.addQuery('ci_type', ciType);
gr.query();
while(gr.next()) {
if (GlideStringUtil.nil(gr.getValue('parent_id'))) {
return getReversedContainmentParentCiType(gr.getValue('sys_id'), relTypeId);
} else if (gr.getValue('is_reverse') == '0') {
if (relTypeId.equals(gr.getValue('rel_type'))) {
var innerGr = new GlideRecord('cmdb_metadata_containment');
if (innerGr.get(gr.getValue('parent_id')))
return innerGr.getValue('ci_type');
}
}
}
return null;
}
function getContainsRelTypeId() {
var relTypeGr = new GlideRecord('cmdb_rel_type');
relTypeGr.addQuery('parent_descriptor','Contains');
relTypeGr.query();
if (!relTypeGr.next())
return null;
return relTypeGr.getValue('sys_id');
}
function getReversedContainmentParentCiType(parentId, relTypeId) {
var containerGr = new GlideRecord('cmdb_metadata_containment');
containerGr.addQuery('parent_id', parentId);
containerGr.addQuery('is_reverse', true);
containerGr.addQuery('rel_type', relTypeId);
containerGr.query();
if (!containerGr.next()) {
return null;
}
return containerGr.getValue('ci_type');
}
Sys ID
5b0da736ef33210039a3b14341e42201