Name
sn_int_studio.CMDBIntegrationStudioUtility
Description
Utility scripts for the CMDB Integration Studio
Script
var CMDBIntegrationStudioUtility = Class.create();
CMDBIntegrationStudioUtility.prototype = {
initialize: function() {
this.CMDB_INST_APPLICATION = "cmdb_inst_application";
this.CMDB_INST_APPLICATION_FEED = "cmdb_inst_application_feed";
this.SYS_DATA_SOURCE = "sys_data_source";
this.SYS_IMPORT_SET = "sys_import_set";
this.NUMBER = "number";
this.CMDB_INST_ENTITY = 'cmdb_inst_entity';
this.IMPORT_LOG = 'import_log';
this.SYS_DICTIONARY = "sys_dictionary";
this.ELEMENT = "element";
this.SYS_PREFIX = "sys_";
this.SYS_RTE_EB_DEFINITION = "sys_rte_eb_definition";
this.SYS_RTE_EB_ENTITY = "sys_rte_eb_entity";
this.CMDB_INST_ENTITY = "cmdb_inst_entity";
this.SYS_RTE_EB_FIELD = "sys_rte_eb_field";
this.SYS_RTE_EB_ENTITY_MAPPING = "sys_rte_eb_entity_mapping";
this.SYS_RTE_EB_FIELD_MAPPING = "sys_rte_eb_field_mapping";
this.SYS_RTE_EB_SCRIPT_OPERATION = "sys_rte_eb_script_operation";
this.SYS_RTE_EB_OPERATION_TYPE = 'sys_rte_eb_operation_type';
this.OPERATION_TYPE_PARAMETER_TABLE = 'sn_cmdb_int_util_rte_eb_operation_type_parameter';
this.SYS_RTE_EB_OPERATION = 'sys_rte_eb_operation';
this.SCHEDULED_IMPORT_SET = 'scheduled_import_set';
this.SET = 'SET';
this.INTEGRATION_STUDIO_API_PLUGIN = 'com.glide.integration_studio';
// COMMON FIELDS
this.ORDER = "order";
this.SYS_ID = "sys_id";
this.SYS_NAME = "sys_name";
this.SYS_CREATED_ON = 'sys_created_on';
this.SUCCESS = 'success';
// ENTITY FIELDS
this.PATH = "path";
this.TABLE = "table";
// CMDB ENTITY FIELDS
this.LOOKUP_FOR_ENTITY = "lookup_for_entity";
this.RELATED_FOR_ENTITY = "related_for_entity";
this.RELATIONSHIP_TYPE = "relationship_type";
// ENTITY MAPPING FIELDS
this.CONDITION_SCRIPT = "condition_script";
this.IS_CONDITIONAL = "is_conditional";
this.NAME = "name";
this.SOURCE_SYS_RTE_EB_ENTITY = "source_sys_rte_eb_entity";
this.TARGET_SYS_RTE_EB_ENTITY = "target_sys_rte_eb_entity";
this.ENTITY_MAPPING_GROUP = 'entity_mapping_group';
this.ENCODED_QUERY = 'encoded_query';
this.IGNORE = 'ignore';
// ENTITY FIELD FIELDS
this.FIELD = "field";
// FIELD MAPPING FIELDS
this.REFERENCED_SYS_RTE_EB_ENTITY = "referenced_sys_rte_eb_entity";
this.SOURCE_SYS_RTE_EB_FIELD = "source_sys_rte_eb_field";
this.TARGET_SYS_RTE_EB_FIELD = "target_sys_rte_eb_field";
// TEMPLATE STATE
this.CMDB_INST_TEMPLATE_STATE = "sn_int_studio_template_state";
this.APPLICATION_FEED_ID = "application_feed_id";
this.TEMPLATE_STATE = "template_state";
this.MAX_STATE = "500";
this.NESTED_PAYLOAD_SCHEMA = 'nested_payload_schema';
this.LOAD_COMPLETE_SCHEMA = 'load_complete_schema';
this.IS_COMPLETE_SCHEMA = 'is_complete_schema';
this.PREVIEW_SIZE_OVERRIDE = "preview_size_override";
this.IMPORT_SET_ID = 'import_set_id';
// IMPORT LOG FIELDS
this.LEVEL = 'level';
this.RUN_HISTORY = 'run_history';
this.ACTIVITY = 'activity';
this.MESSAGE = 'message';
this.SOURCE = 'source';
//REL
this.CMDB_REL_CI = 'cmdb_rel_ci';
this.PARENT = 'parent';
this.CHILD = 'child';
this.TYPE = 'type';
// OPERATION TYPE FIELDS
this.DESCRIPTION = 'description';
this.HAS_MULTIPLE_INPUT_FIELDS = 'has_multiple_input_fields';
this.HAS_MULTIPLE_OUTPUT_FIELDS = 'has_multiple_output_fields';
this.IS_TEMPLATE_SCRIPT = 'is_template_script';
this.INPUT_OUTPUT = 'input_output';
this.IS_OPTIONAL = 'is_optional';
this.IS_MULTIPLE = 'is_multiple';
this.IS_FIXED_VALUE = 'is_fixed_value';
this.FIXED_VALUE = 'fixed_value';
this.PARAMETER_TYPE = 'parameter_type';
this.OPERATION_COLUMN_NAME = 'operation_column_name';
this.CHOICE_LIST = 'choice_list';
this.HINT = 'hint';
this.SOURCE_SYS_RTE_EB_FIELDS = "source_sys_rte_eb_fields";
this.TARGET_SYS_RTE_EB_FIELDS = "target_sys_rte_eb_fields";
this.EXTRACT_NUMERIC_OPERATION = 'sys_rte_eb_extract_numeric_operation';
this.TEMP = "Temp";
this.IMPORT = "Import";
this.POST = "post";
this.INPUT_PREFIX = "input.";
this.DATA_SOURCE_EXCEPTION = "DataSourceException";
this.NO_INCLUSIVE_REL_EXCEPTION = "NoInclusiveRelException";
this.NESTED_PAYLOAD_PLACEHOLDER_FIELD = "placeholder#";
this.IRE_SETTINGS_PREFIX = "settings.";
this.STATUS_SUCCESS = 200;
this.STATUS_ERROR = 500;
this.PREVIEW_SIZE_PROPERTY_NAME = 'sn_int_studio.preview.size';
this.MAX_PREVIEW_SIZE = 10000;
this.DEFAULT_PREVIEW_SIZE = 100;
this.DISABLE_ENTITY_MAPPING_REORDER_PROPERTY_NAME = 'sn_int_studio.nested_payload.mapping_reorder.disabled.list';
this.UA_EVENT_TYPE_CUSTOM = 'custom_metric';
this.UA_INSTRUMENTATION_POINT = 'ih_etl_metrics';
this.UA_INSTRUMENTATION_EVENT = 'ih_etl_api_usage';
this.ACTION = 'action';
this.FEED_NAME = 'feed_name';
this.STEP_NUMBER = 'step_number';
this.RECORD_VALUE = 'record_value';
this.RECORD_ID = 'record_id';
this.CLASS_SAVED = 'class_saved';
this.CLASS_DELETED = 'class_deleted';
this.CLASS_UPDATED = 'class_updated';
this.FIELD_MAPPING_SAVED = 'field_mapping_saved';
this.FIELD_MAPPING_UPDATED = 'field_mapping_updated';
this.FIELD_MAPPING_DELETED = 'field_mapping_deleted';
this.TRANSFORM_OPERATION_SAVED = 'transform_operation_saved';
this.TRANSFORM_OPERATION_DELETED = 'transform_operation_deleted';
this.RELATIONSHIP_DELETED = 'relationship_deleted';
this.RELATIONSHIP_SAVED = 'relationship_saved';
this.RELATIONSHIP_UPDATED = 'relationship_updated';
this.ASSOCIATED_CLASS_UPDATED = 'associated_class_updated';
this.BASIC_DETAIL_UPDATED = 'basic_detail_updated';
this.TRANSFORM_MAP_CREATED = 'transform_map_created';
this.TRANSFORM_MAP_DUPLICATED = 'transform_map_duplicated';
this.DATA_ROLLED_BACK = 'data_rolled_back';
this.BASIC_DETAIL_STEP_NUMBER = 100;
this.PREVIEW_AND_PREPARE_STEP_NUMBER = 200;
this.CLASS_MAPPING_STEP_NUMBER = 300;
this.RELATIONSHIP_MAPPING_STEP_NUMBER = 350;
this.TEST_AND_ROLLBACK_STEP_NUMBER = 400;
this.SET_SCHEDULE_STEP_NUMBER = 450;
// ROLLBACK
this.SYS_ROLLBACK_RUN = 'sys_rollback_run';
this.ROLLBACK_CONTEXT_FIELD = 'context';
this.ROLLBACK_STATE_FIELD = 'state';
this.ROLLBACK_FINISHED_STATE = 'finished';
this.LOOKDOWN_CLASS = 'lookdown_class';
this.NESTED_PAYLOAD_TOP_NODE_NAME = 'object';
},
buildErrorObject: function(message, detail, additionalDebugObject) {
var obj = {};
if (message)
obj.message = message;
if (detail)
obj.detail = detail;
if (additionalDebugObject)
obj.additionalDebug = additionalDebugObject;
return obj;
},
getInternalServerError: function(errorConfig) {
var internalError = new sn_ws_err.ServiceError();
internalError.setStatus(this.STATUS_ERROR);
if (errorConfig.message)
internalError.setMessage(errorConfig.message);
if (errorConfig.detail)
internalError.setDetail(errorConfig.detail);
gs.error(JSON.stringify(errorConfig));
return internalError;
},
getApplicationFeed: function(applicationFeedId) {
if (!applicationFeedId)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("No application feed passed to getApplicationFeed")));
var gr = new GlideRecord(this.CMDB_INST_APPLICATION_FEED);
if (gr.get(applicationFeedId))
return gr;
return null;
},
getApplication: function(applicationId) {
if (!applicationId)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("No application passed to getApplication")));
var gr = new GlideRecord(this.CMDB_INST_APPLICATION);
if (gr.get(applicationId))
return gr;
return null;
},
getTemplateState: function(templateStateId) {
if (!templateStateId)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("No template state passed to getTemplateState")));
var gr = new GlideRecord(this.CMDB_INST_TEMPLATE_STATE);
if (gr.get(templateStateId))
return gr;
return null;
},
getEntitiesForApplicationFeed: function(applicationFeedId, encodedQuery) {
var entities = [];
if (!applicationFeedId)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("No application feed passed to getEntitiesForApplicationFeed")));
var gr = new GlideRecord(this.CMDB_INST_ENTITY);
gr.addQuery(this.SYS_RTE_EB_DEFINITION, applicationFeedId);
if (encodedQuery)
gr.addEncodedQuery(encodedQuery);
gr.orderBy('sys_created_on');
gr.query();
while (gr.next()) {
entities.push({
name: gr.getValue(this.NAME),
table: gr.getValue(this.TABLE),
path: gr.getValue(this.PATH),
lookup_for_entity: gr.getValue(this.LOOKUP_FOR_ENTITY),
related_for_entity: gr.getValue(this.RELATED_FOR_ENTITY),
relationship_type: gr.getValue(this.RELATIONSHIP_TYPE),
sys_id: gr.getUniqueValue()
});
}
return entities;
},
getEntityFieldsForEntity: function(entityId) {
var fields = [];
if (!entityId)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("No entity passed to getEntityFieldsForEntity")));
var gr = new GlideRecord(this.SYS_RTE_EB_FIELD);
gr.addQuery(this.SYS_RTE_EB_ENTITY, entityId);
gr.orderBy(this.FIELD);
gr.query();
while (gr.next()) {
fields.push({
field: gr.getValue(this.FIELD),
name: gr.getValue(this.NAME),
sys_id: gr.getUniqueValue()
});
}
return fields;
},
getEntityMappingsForApplicationFeed: function(applicationFeedId, encodedQuery) {
var entityMappings = [];
if (!applicationFeedId)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("No application feed passed to getEntityMappingsForApplicationFeed")));
var gr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
gr.addQuery(this.SYS_RTE_EB_DEFINITION, applicationFeedId);
if (encodedQuery)
gr.addEncodedQuery(encodedQuery);
gr.query();
while (gr.next()) {
entityMappings.push({
condition_script: gr.getValue(this.CONDITION_SCRIPT),
is_conditional: gr.getDisplayValue(this.IS_CONDITIONAL),
name: gr.getValue(this.NAME),
order: gr.getValue(this.ORDER),
encoded_query: gr.getValue(this.ENCODED_QUERY),
group_id: gr.getValue(this.ENTITY_MAPPING_GROUP),
source_sys_rte_eb_entity: gr.getValue(this.SOURCE_SYS_RTE_EB_ENTITY),
sys_id: gr.getUniqueValue(),
target_sys_rte_eb_entity: gr.getValue(this.TARGET_SYS_RTE_EB_ENTITY),
active: !this.parseBooleanString(gr.getDisplayValue(this.IGNORE))
});
}
return entityMappings;
},
getFieldMappingsForEntityMapping: function(entityMappingId, encodedQuery) {
var fieldMappings = [];
if (!entityMappingId)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("No entity mapping passed to getFieldMappingsForEntityMapping")));
var gr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
gr.addQuery(this.SYS_RTE_EB_ENTITY_MAPPING, entityMappingId);
if (encodedQuery)
gr.addEncodedQuery(encodedQuery);
gr.query();
while (gr.next()) {
var targetFieldDisplayValue = gr.getDisplayValue(this.TARGET_SYS_RTE_EB_FIELD + '.field').split(".");
targetFieldDisplayValue = targetFieldDisplayValue[targetFieldDisplayValue.length - 1];
fieldMappings.push({
order: gr.getValue(this.ORDER),
referenced_sys_rte_eb_entity: gr.getValue(this.REFERENCED_SYS_RTE_EB_ENTITY),
referenced_sys_rte_eb_entity_display_value: gr.getDisplayValue(this.REFERENCED_SYS_RTE_EB_ENTITY + '.name'),
source_sys_rte_eb_field: gr.getValue(this.SOURCE_SYS_RTE_EB_FIELD),
source_sys_rte_eb_field_display_value: gr.getDisplayValue(this.SOURCE_SYS_RTE_EB_FIELD + '.field'),
sys_id: gr.getValue(this.SYS_ID),
target_sys_rte_eb_field: gr.getValue(this.TARGET_SYS_RTE_EB_FIELD),
target_sys_rte_eb_field_display_value: targetFieldDisplayValue,
target_sys_rte_eb_entity_name: gr.sys_rte_eb_entity_mapping.target_sys_rte_eb_entity.name + '',
target_sys_rte_eb_entity_table_name: gr.sys_rte_eb_entity_mapping.target_sys_rte_eb_entity.table + ''
});
}
return fieldMappings;
},
createEntity: function(feedId, name, table) {
return this.createCmdbEntity(feedId, name, table, table, '', '');
},
createCmdbEntity: function(feedId, name, path, table, relType, lookupEntity) {
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.initialize();
entityGr.setValue(this.NAME, name);
entityGr.setValue(this.SYS_RTE_EB_DEFINITION, feedId);
if (table)
entityGr.setValue(this.TABLE, table);
if (path)
entityGr.setValue(this.PATH, path);
if (relType)
entityGr.setValue(this.RELATIONSHIP_TYPE, relType);
if (lookupEntity)
entityGr.setValue(this.LOOKUP_FOR_ENTITY, lookupEntity);
if (entityGr.insert())
return entityGr;
var errorObj = this.buildErrorObject(gs.getMessage("Failed to create entity"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
},
createRelCmdbEntity: function(feedId, name, path, relType) {
return this.createCmdbEntity(feedId, name, path, this.CMDB_REL_CI, relType);
},
findImpCmdbEntity: function(applicationFeedId) {
var errorObj = {};
if (applicationFeedId) {
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_RTE_EB_DEFINITION, applicationFeedId);
entityGr.addNullQuery(this.PATH);
entityGr.addEncodedQuery('nameSTARTSWITHImp');
entityGr.query();
var count = 0;
if (!entityGr.hasNext()) {
errorObj = this.buildErrorObject(gs.getMessage("No imp entity was found"));
return this.getInternalServerError(errorObj);
}
while (entityGr.next()) {
if (count === 0)
count++;
else {
errorObj = this.buildErrorObject(gs.getMessage("More than one imp entity was found"));
throw this.getInternalServerError(errorObj);
}
}
return entityGr;
}
errorObj = this.buildErrorObject(gs.getMessage("No application feed sent to findImpCmdbEntity"));
throw this.getInternalServerError(errorObj);
},
findTempCmdbEntity: function(applicationFeedId, impEntityId) {
var errorObj = {};
if (applicationFeedId && impEntityId) {
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SOURCE_SYS_RTE_EB_ENTITY, impEntityId);
entityMappingGr.addNotNullQuery(this.TARGET_SYS_RTE_EB_ENTITY);
entityMappingGr.query();
if (!entityMappingGr.hasNext()) {
errorObj = this.buildErrorObject(gs.getMessage("There should be one entity mapping from imp to temp"), '', {args: arguments});
return this.getInternalServerError(errorObj);
}
var tempEntities = {};
while (entityMappingGr.next()) {
var tempEntityId = entityMappingGr.getValue(this.TARGET_SYS_RTE_EB_ENTITY);
var tempEntityGr = new GlideRecord(this.SYS_RTE_EB_ENTITY);
if (!tempEntityGr.get(tempEntityId)) {
errorObj = this.buildErrorObject(gs.getMessage("Temp entity record not found"), '', {args: arguments});
return this.getInternalServerError(errorObj);
}
var currentTempEntity = {
name: tempEntityGr.getValue(this.NAME),
table: tempEntityGr.getValue(this.TABLE),
path: tempEntityGr.getValue(this.PATH),
lookup_for_entity: tempEntityGr.getValue(this.LOOKUP_FOR_ENTITY),
related_for_entity: tempEntityGr.getValue(this.RELATED_FOR_ENTITY),
relationship_type: tempEntityGr.getValue(this.RELATIONSHIP_TYPE),
sys_id: tempEntityId
};
tempEntities[currentTempEntity.path] = currentTempEntity;
}
return tempEntities;
}
errorObj = this.buildErrorObject(gs.getMessage("Invalid parameters sent to function findTempCmdbEntity"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
},
getRecordsFromTable: function(table, ids, fields) {
var result = {};
var gr = new GlideRecord(table);
gr.addQuery(this.SYS_ID, ids);
gr.query();
while (gr.next()) {
if (!gr.canRead()) {
continue;
}
var sys_id = gr.getValue(this.SYS_ID);
result[sys_id] = {};
for (var i = 0; i < fields.length; i++) {
fields[i] = fields[i].trim();
if (!fields[i] || !gr.isValidField(fields[i]))
continue;
result[sys_id][fields[i]] = gr.getDisplayValue(fields[i]);
}
}
return result;
},
createMappingBetweenEntities: function(applicationFeedId, name, sourceEntitySysId, targetEntitySysId, condition, order, groupId, encodedQuery, ignore) {
var errorObj = {};
if (name && sourceEntitySysId && targetEntitySysId) {
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.initialize();
entityMappingGr.setValue(this.NAME, name);
entityMappingGr.setValue(this.SYS_RTE_EB_DEFINITION, applicationFeedId);
entityMappingGr.setValue(this.SOURCE_SYS_RTE_EB_ENTITY, sourceEntitySysId);
entityMappingGr.setValue(this.TARGET_SYS_RTE_EB_ENTITY, targetEntitySysId);
if (groupId)
entityMappingGr.setValue(this.ENTITY_MAPPING_GROUP, groupId);
if (encodedQuery)
entityMappingGr.setValue(this.ENCODED_QUERY, encodedQuery);
if (order)
entityMappingGr.setValue(this.ORDER, order);
else
entityMappingGr.setValue(this.ORDER, '100');
if (condition) {
entityMappingGr.setValue(this.IS_CONDITIONAL, true);
entityMappingGr.setValue(this.CONDITION_SCRIPT, condition);
}
if (ignore) {
entityMappingGr.setValue(this.IGNORE, true);
}
if (entityMappingGr.insert())
return entityMappingGr;
errorObj = this.buildErrorObject(gs.getMessage("Failed to insert into mapping entity table"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
errorObj = this.buildErrorObject(gs.getMessage("No entities sys_id provided to createMappingBetweenEntities"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
},
findMappingBetweenEntities: function(sourceEntitySysId, targetEntitySysId) {
var errorObj = {};
if (sourceEntitySysId && targetEntitySysId) {
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SOURCE_SYS_RTE_EB_ENTITY, sourceEntitySysId);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, targetEntitySysId);
entityMappingGr.query();
var count = 0;
if (!entityMappingGr.hasNext()) {
errorObj = this.buildErrorObject(gs.getMessage("No entity mapping found"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
while (entityMappingGr.next()) {
if (count === 0)
count++;
else {
errorObj = this.buildErrorObject(gs.getMessage("More than one mapping between 2 entities"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
}
return entityMappingGr;
}
errorObj = this.buildErrorObject(gs.getMessage("No entities sys_id provided to findMappingBetweenEntities"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
},
// function to remove spaces and limit max chars to a name
prettifyName: function(name, maxChars) {
if (name) {
name = name.toLowerCase().replace(/ /g, '_');
if (!isNaN(maxChars) && name.length > maxChars)
name = name.substring(0, maxChars);
return name;
}
return '';
},
getTableColumns: function(tableName) {
if (!tableName)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("No table name sent to getTableColumns")));
var columns = [];
var gr = new GlideRecord(this.SYS_DICTIONARY);
gr.addQuery(this.NAME, tableName);
gr.addNotNullQuery(this.ELEMENT);
gr.orderBy(this.ELEMENT);
gr.query();
while (gr.next()) {
var name = gr.getValue(this.ELEMENT);
if (!name || name.indexOf(this.SYS_PREFIX) === 0)
continue;
columns.push(name);
}
return columns;
},
createEntityField: function(applicationFeedSysId, entityId, field, name) {
var errorObj = {};
if (applicationFeedSysId && entityId && field && name) {
var entityFieldGr = new GlideRecord(this.SYS_RTE_EB_FIELD);
entityFieldGr.initialize();
entityFieldGr.setValue(this.SYS_RTE_EB_DEFINITION, applicationFeedSysId);
entityFieldGr.setValue(this.SYS_RTE_EB_ENTITY, entityId);
entityFieldGr.setValue(this.FIELD, field);
entityFieldGr.setValue(this.NAME, name);
if (entityFieldGr.insert())
return entityFieldGr;
errorObj = this.buildErrorObject(gs.getMessage("Failed to insert into entity field table"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
errorObj = this.buildErrorObject(gs.getMessage("Invalid parameters sent to createEntityField"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
},
createMappingBetweenEntityFields: function(applicationFeedSysId, entityMappingId, sourceField, targetField, order) {
var errorObj = {};
if (applicationFeedSysId && entityMappingId && sourceField && targetField && order) {
var entityFieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
entityFieldMappingGr.initialize();
entityFieldMappingGr.setValue(this.SYS_RTE_EB_DEFINITION, applicationFeedSysId);
entityFieldMappingGr.setValue(this.SOURCE_SYS_RTE_EB_FIELD, sourceField);
entityFieldMappingGr.setValue(this.TARGET_SYS_RTE_EB_FIELD, targetField);
entityFieldMappingGr.setValue(this.SYS_RTE_EB_ENTITY_MAPPING, entityMappingId);
entityFieldMappingGr.setValue(this.ORDER, order);
if (entityFieldMappingGr.insert())
return entityFieldMappingGr;
errorObj = this.buildErrorObject(gs.getMessage("Failed to insert into entity field mapping table"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
errorObj = this.buildErrorObject(gs.getMessage("Invalid parameters sent to createMappingBetweenEntityFields"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
},
deleteEntity: function(entitySysId) {
if (!entitySysId)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("No entity sys id sent to deleteEntity")));
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
if (entityGr.get(entitySysId))
return entityGr.deleteRecord();
else
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("Entity sys id sent to deleteEntity does not exist")));
},
loadAllMetadataForApplicationFeed: function(applicationFeedSysId, impEntityGr) {
var errorObj = {};
if (applicationFeedSysId && impEntityGr) {
var impEntityId = impEntityGr.getUniqueValue();
var result = {
entities: {},
fieldsPerEntity: {},
entitiesMapping: [],
fieldMappingPerEntityMapping: {},
operationGraph: {},
savedOperations: []
};
// import entity
result.entities.imp_entity = {
name: impEntityGr.getValue(this.NAME),
table: impEntityGr.getValue(this.TABLE),
path: impEntityGr.getValue(this.PATH),
lookup_for_entity: impEntityGr.getValue(this.LOOKUP_FOR_ENTITY),
related_for_entity: impEntityGr.getValue(this.RELATED_FOR_ENTITY),
relationship_type: impEntityGr.getValue(this.RELATIONSHIP_TYPE),
sys_id: impEntityId
};
// temp entity
var tempEntities = this.findTempCmdbEntity(applicationFeedSysId, impEntityId);
if (tempEntities) {
result.entities.temp_entity = tempEntities;
// the rest of the entities
var encodedQuery = '';
var tempEntityPaths = Object.keys(tempEntities);
for (var i = 0; i < tempEntityPaths.length; i++) {
var tempEntityId = tempEntities[tempEntityPaths[i]].sys_id;
if (i == 0) {
encodedQuery += 'sys_id!=' + tempEntityId;
} else {
encodedQuery += '^sys_id!=' + tempEntityId;
}
var tempFields = this.getEntityFieldsForEntity(tempEntityId);
result.fieldsPerEntity[tempEntityId] = tempFields;
}
encodedQuery += '^sys_id!=' + impEntityId;
result.entities.other_entities = this.getEntitiesForApplicationFeed(applicationFeedSysId, encodedQuery);
var impFields = this.getEntityFieldsForEntity(impEntityId);
result.fieldsPerEntity[impEntityId] = impFields;
for (var i = 0; i < result.entities.other_entities.length; i++) {
var entity = result.entities.other_entities[i];
if (entity && entity.sys_id)
result.fieldsPerEntity[entity.sys_id] = this.getEntityFieldsForEntity(entity.sys_id);
}
result.entitiesMapping = this.getEntityMappingsForApplicationFeed(applicationFeedSysId, '');
for (i = 0; i < result.entitiesMapping.length; i++) {
var entityMapping = result.entitiesMapping[i];
if (entityMapping && entityMapping.sys_id)
result.fieldMappingPerEntityMapping[entityMapping.sys_id] = this.getFieldMappingsForEntityMapping(entityMapping.sys_id, '');
}
// load all operations
result.savedOperations = this.getSavedOperationsForFeed(applicationFeedSysId);
// set the operation graph
var graph = {};
for (var i = 0; i < tempEntityPaths.length; i++) {
var currentPath = tempEntityPaths[i];
var currentTempEntity = result.entities.temp_entity[currentPath];
graph[currentPath] = this.getOperationGraph(currentTempEntity.sys_id);
}
result.operationGraph = graph;
return result;
}
errorObj = this.buildErrorObject(gs.getMessage("Failed to find temp entity record in loadAllMetadataForApplicationFeed"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
errorObj = this.buildErrorObject(gs.getMessage("Invalid parameters sent to loadAllMetadataForApplicationFeed"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
},
createFieldMappingsWithEntityRef: function(appFeedSysId, entityMappingId, referencedEntityId, targetField, order) {
if (!appFeedSysId || !entityMappingId || !referencedEntityId || !targetField || !order)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("Invalid parameters sent to createFieldMappingsWithEntityRef"), '', {args: arguments}));
var isNestedPayload = this.isNestedPayload(appFeedSysId);
if (isNestedPayload) {
var currentEntityId = '';
var currentEntityTempPath = '';
var currentEntityTable = '';
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_ID, entityMappingId);
entityMappingGr.query();
if (entityMappingGr.next()) {
currentEntityId = entityMappingGr.getValue(this.TARGET_SYS_RTE_EB_ENTITY);
currentEntityTempPath = entityMappingGr.source_sys_rte_eb_entity.path + '';
currentEntityTable = entityMappingGr.target_sys_rte_eb_entity.table + '';
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity mapping with id {0}', entityMappingId));
throw this.getInternalServerError(errorObj);
}
var referenceEntityTempPath = '';
var referenceEntityName = '';
entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, referencedEntityId);
entityMappingGr.query();
if (entityMappingGr.next()) {
referenceEntityTempPath = entityMappingGr.source_sys_rte_eb_entity.path + '';
referenceEntityName = entityMappingGr[this.TARGET_SYS_RTE_EB_ENTITY].name + '';
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity mapping with target entity id {0}', referencedEntityId));
throw this.getInternalServerError(errorObj);
}
if (currentEntityTable != this.CMDB_REL_CI) {
this.checkIsDifferentDataBranch(currentEntityId, referencedEntityId, currentEntityTempPath, referenceEntityTempPath);
}
}
var entityFieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
entityFieldMappingGr.initialize();
entityFieldMappingGr.setValue(this.SYS_RTE_EB_DEFINITION, appFeedSysId);
entityFieldMappingGr.setValue(this.SYS_RTE_EB_ENTITY_MAPPING, entityMappingId);
entityFieldMappingGr.setValue(this.TARGET_SYS_RTE_EB_FIELD, targetField);
entityFieldMappingGr.setValue(this.REFERENCED_SYS_RTE_EB_ENTITY, referencedEntityId);
entityFieldMappingGr.setValue(this.ORDER, order);
if (entityFieldMappingGr.insert()) {
return entityFieldMappingGr;
}
var errorObj = this.buildErrorObject(gs.getMessage("Failed to insert into entity field mapping table"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
},
deleteFields: function(fieldIds) {
if (!fieldIds)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("No fields sent to deleteFields")));
var fieldGr = new GlideRecord(this.SYS_RTE_EB_FIELD);
fieldGr.addQuery(this.SYS_ID, 'IN', fieldIds);
fieldGr.query();
fieldGr.deleteMultiple();
},
getParamAsString: function(paramName) {
if (request.queryParams.hasOwnProperty(paramName))
return request.queryParams[paramName] + '';
return '';
},
transformQueryToFailingPathScript: function(query, sourceEntityPath, hasElseClause) {
var conditionBlocksArray = [];
for (var i = 0; i < query.length; i++) {
var conditionBlocks = this._processQueryString(query[i]);
if (conditionBlocks.length > 0) {
conditionBlocksArray.push(conditionBlocks);
}
}
var resultArr = [];
if (conditionBlocksArray.length <= 0) {
return resultArr;
}
var conditionArr = [];
for (var j = 0; j < conditionBlocksArray.length; j++) {
var condition = this._processConditionBlocksForFailingPathScript(conditionBlocksArray[j], '');
conditionArr.push(condition);
}
var sourceEntityPathParts = sourceEntityPath.split('.');
var sourceEntityLoops = this._getEntityLoopsFromPathParts(sourceEntityPathParts);
for (var k = 0; k < conditionArr.length; k++) {
var currCondition = conditionArr[k];
var result = '(function(input, failingPaths) {\n';
var prevConditions = [];
var prevCollectionConditions = [];
if (k > 0) {
conditionArr.slice(0, k).forEach(function(elem) {
if (elem.nonCollection && elem.nonCollection.condition) {
prevConditions.push(elem.nonCollection.condition);
}
if (elem.collection && elem.collection.condition) {
prevCollectionConditions.push(elem.collection.condition);
}
});
}
// If there are non-collection conditions from previous blocks that pass, automatically return false
if (prevConditions && prevConditions.length) {
result += 'if (' + prevConditions.join(' || ') + '){\n';
result += ' return false;\n';
result += '}\n';
}
// If there are conditions outside the for loop that fail, automatically return false
if (currCondition.nonCollection && currCondition.nonCollection.notCondition) {
result += 'if (' + currCondition.nonCollection.notCondition + '){\n';
result += ' return false;\n';
result += '}\n';
}
// Add the for loops based off the sourceEntity if there are conditions for it
if ((prevCollectionConditions && prevCollectionConditions.length) || (currCondition.collection && currCondition.collection.notCondition)) {
result += this._processForLoops(sourceEntityLoops);
// If there are collection conditions from previous blocks that pass, automatically return false
if (prevCollectionConditions && prevCollectionConditions.length) {
result += 'if (' + prevCollectionConditions.join(' || ') + '){\n';
result += ' return false;\n';
result += '}\n';
}
// Check the failing condition for the collection to add path to failingPaths array
if (currCondition.collection && currCondition.collection.notCondition) {
result += 'if (' + currCondition.collection.notCondition + ') {\n';
result += ' failingPaths.push(\'';
result += this._processFailingPath(sourceEntityPathParts);
result += '\');\n';
result += '}\n';
}
// Close out the for loops
for (var o = 0; o < sourceEntityLoops.length; o++) {
result += '}\n';
}
}
result += 'return true;\n';
result += '})(input, failingPaths);';
resultArr[k] = result;
}
if (hasElseClause) {
var elsePrevConditions = [];
var elsePrevCollectionConditions = [];
conditionArr.forEach(function(elem) {
if (elem.nonCollection && elem.nonCollection.condition) {
elsePrevConditions.push(elem.nonCollection.condition);
}
if (elem.collection && elem.collection.condition) {
elsePrevCollectionConditions.push(elem.collection.condition);
}
});
var elseScript = '(function(input, failingPaths) {\n';
if (elsePrevConditions && elsePrevConditions.length) {
elseScript += 'if (' + elsePrevConditions.join(' || ') + '){\n';
elseScript += ' return false;\n';
elseScript += '}\n';
}
if (elsePrevCollectionConditions && elsePrevCollectionConditions.length) {
elseScript += this._processForLoops(sourceEntityLoops);
elseScript += ' if (' + elsePrevCollectionConditions.join(' || ') + ') {\n';
elseScript += ' failingPaths.push(\'';
elseScript += this._processFailingPath(sourceEntityPathParts);
elseScript += '\');\n';
elseScript += ' }\n';
// Close out the for loops
for (var p = 0; p < sourceEntityLoops.length; p++) {
elseScript += '}\n';
}
}
elseScript += ' return true;\n';
elseScript += '})(input, failingPaths);';
resultArr.push(elseScript);
}
return resultArr;
},
transformQueryToScript: function(query, tempEntityPath, hasElseClause) {
var conditionBlocksArray = [];
for (var i = 0; i < query.length; i++) {
var conditionBlocks = this._processQueryString(query[i]);
if (conditionBlocks.length > 0) {
conditionBlocksArray.push(conditionBlocks);
}
}
var resultArr = [];
if (conditionBlocksArray.length <= 0) {
return resultArr;
}
var conditionArr = [];
for (var j = 0; j < conditionBlocksArray.length; j++) {
var condition = this._processConditionBlocks(conditionBlocksArray[j], tempEntityPath);
conditionArr.push(condition);
}
for (var k = 0; k < conditionArr.length; k++) {
var result = '(function() {\n';
var currCondition = '(' + conditionArr[k] + ')';
for (var l = 0; l < k; l++) {
var notCondition = '!(' + conditionArr[l] + ')';
currCondition += ' && ' + notCondition;
}
result += ' if (' + currCondition + ') {\n';
result += ' return true;\n';
result += ' }\n';
result += ' return false;\n';
result += '})();';
resultArr[k] = result;
}
if (hasElseClause) {
var elseScript = '(function() {\n';
var conditionClause = '';
for (var m = 0; m < conditionArr.length; m++) {
var complementaryCondition = '!(' + conditionArr[m] + ')';
conditionClause += complementaryCondition;
if (m < conditionArr.length - 1)
conditionClause += ' && ';
}
elseScript += ' if (' + conditionClause + ') {\n';
elseScript += ' return true;\n';
elseScript += ' }\n';
elseScript += ' return false;\n';
elseScript += '})();';
resultArr.push(elseScript);
}
return resultArr;
},
_processQueryString: function(queryString) {
var conditionList = [];
var blocks = queryString.split('^');
for (var i = 0; i < blocks.length; i++) {
var section = [];
section.push(this._processBlock(blocks[i]));
for (var j = i + 1; j < blocks.length; j++) {
if (!blocks[j].startsWith('OR')) {
break;
}
section.push(this._processBlock(blocks[j].slice(2)));
}
i = j - 1;
conditionList.push(section);
}
return conditionList;
},
_processBlock: function(block) {
var parts = block.split(/(=|!=|ANYTHING|IN|STARTSWITH|ENDSWITH|LIKE|NOT LIKE|ISEMPTY|ISNOTEMPTY|ISACTIVATED|ISNOTACTIVATED)/);
var processedBlock = {};
processedBlock.field = parts[0];
processedBlock.operator = parts[1];
parts.splice(0, 2);
processedBlock.condition = parts.join(''); // Edge case: testSTARTSWITHANYTHINGLIKE
return processedBlock;
},
_processConditionBlocks: function(blocks, tempEntityPath) {
var outerConditions = [];
for (var i = 0; i < blocks.length; i++) {
var innerConditions = [];
for (var j = 0; j < blocks[i].length; j++) {
innerConditions.push(this._decodeOperator(blocks[i][j], tempEntityPath).operatorString);
}
outerConditions.push('(' + innerConditions.join(' || ') + ')');
}
return outerConditions.join(' && ');
},
// for failing path condition, need to create each condition block with !({condition]) and join them with ||
_processConditionBlocksForFailingPathScript: function(blocks, tempEntityPath) {
var conditions = {
nonCollection: {
condition: '',
notCondition: ''
},
collection: {
condition: '',
notCondition: ''
}
}
var nonCollectionOuterPassing = [];
var nonCollectionOuterFailing = [];
var collectionOuterPassing = [];
var collectionOuterFailing = [];
for (var i = 0; i < blocks.length; i++) {
var innerConditions = [];
var isCollectionCondition = false;
for (var j = 0; j < blocks[i].length; j++) {
var decodedOperator = this._decodeOperator(blocks[i][j], tempEntityPath);
// Used to track if any inner conditions are a collection condition
if (!isCollectionCondition && decodedOperator.isCollectionCondition)
isCollectionCondition = decodedOperator.isCollectionCondition;
innerConditions.push(decodedOperator.operatorString);
}
var joinedInnerConditions = innerConditions.join(' || ');
if (isCollectionCondition) {
collectionOuterPassing.push('(' + joinedInnerConditions + ')');
collectionOuterFailing.push('!(' + joinedInnerConditions + ')');
} else {
nonCollectionOuterPassing.push('(' + joinedInnerConditions + ')');
nonCollectionOuterFailing.push('!(' + joinedInnerConditions + ')');
}
}
conditions.nonCollection.condition = nonCollectionOuterPassing.join(' && ');
conditions.nonCollection.notCondition = nonCollectionOuterFailing.join(' || ');
conditions.collection.condition = collectionOuterPassing.join(' && ');
conditions.collection.notCondition = collectionOuterFailing.join(' || ');
return conditions;
},
_decodeOperator: function(section, tempEntityPath) {
var field = section.field;
var operator = section.operator;
var condition = GlideStringUtil.escapeTicks(section.condition);
var decodeResult = '';
var isCollectionCondition = false;
if (tempEntityPath) {
tempEntityPath = tempEntityPath + '.';
} else {
tempEntityPath = '';
field = field.replace(/\#/g, '.');
var fieldParts = field.split('.');
var collectionIndex = -1;
for (var i = 0; i < fieldParts.length; i++) {
var part = fieldParts[i];
if (part.endsWith('[*]')) {
collectionIndex++;
isCollectionCondition = true;
var collectionName = part.slice(0, part.indexOf('['));
fieldParts[i] = collectionName + '[' + collectionName + '_' + collectionIndex + ']';
}
}
field = fieldParts.join('.');
}
switch (operator) {
case '=':
decodeResult += this.INPUT_PREFIX + tempEntityPath + field + ' === ' + '\'' + condition + '\'';
break;
case '!=':
decodeResult += this.INPUT_PREFIX + tempEntityPath + field + ' !== ' + '\'' + condition + '\'';
break;
case 'ANYTHING':
decodeResult += this.INPUT_PREFIX + tempEntityPath + field + ' || ' + this.INPUT_PREFIX + tempEntityPath + field + ' === null || ' + this.INPUT_PREFIX + tempEntityPath + field + ' === \'\'';
break;
case 'IN':
decodeResult += '\'' + condition + '\'' + '.split(\',\').indexOf(' + this.INPUT_PREFIX + tempEntityPath + field + ') > -1';
break;
case 'STARTSWITH':
decodeResult += this.INPUT_PREFIX + tempEntityPath + field + '.startsWith(' + '\'' + condition + '\'' + ')';
break;
case 'ENDSWITH':
decodeResult += this.INPUT_PREFIX + tempEntityPath + field + '.endsWith(' + '\'' + condition + '\'' + ')';
break;
case 'LIKE':
decodeResult += this.INPUT_PREFIX + tempEntityPath + field + '.indexOf(' + '\'' + condition + '\'' + ') > -1';
break;
case 'NOT LIKE':
decodeResult += this.INPUT_PREFIX + tempEntityPath + field + '.indexOf(' + '\'' + condition + '\'' + ') < 0';
break;
case 'ISEMPTY':
decodeResult += '!' + this.INPUT_PREFIX + tempEntityPath + field;
break;
case 'ISNOTEMPTY':
decodeResult += this.INPUT_PREFIX + tempEntityPath + field;
break;
case 'ISACTIVATED':
decodeResult += 'GlidePluginManager.isActive(\'' + field + '\')';
break;
case 'ISNOTACTIVATED':
decodeResult += '!GlidePluginManager.isActive(\'' + field + '\')';
break;
default:
decodeResult += '';
}
return {
operatorString: decodeResult,
isCollectionCondition: isCollectionCondition
}
},
_getEntityLoopsFromPathParts: function(pathPartsArray) {
var currentPath = [];
var loops = [];
for (var i = 0; i < pathPartsArray.length; i++) {
currentPath.push(pathPartsArray[i]);
if (pathPartsArray[i].endsWith('[*]')) {
loops.push(currentPath.join('.'));
}
}
return loops;
},
_processForLoops: function(entityLoops) {
var resultString = '';
for (var i = 0; i < entityLoops.length; i++) {
var collectionName = '';
var collectionIndex = -1;
var finalLoopParts = [];
var splitPath = entityLoops[i].split('.');
for (var j = 0; j < splitPath.length; j++) {
var part = splitPath[j];
if (part.endsWith('[*]')) {
collectionIndex++;
collectionName = part.slice(0, part.indexOf('['));
var collectionString = collectionName;
// if not the last collection in the path, add index from previous loop
if (j < splitPath.length - 1) {
collectionString += '[' + collectionName + '_' + collectionIndex + ']';
}
finalLoopParts.push(collectionString);
} else {
finalLoopParts.push(part);
}
}
var entityVarName = collectionName + '_' + collectionIndex;
var comparisonVarName = this.INPUT_PREFIX + finalLoopParts.join('.');
resultString += 'for (var ' + entityVarName + ' = 0; ' + entityVarName + ' < ' + comparisonVarName + '.length; ' + entityVarName + '++) {\n';
}
return resultString;
},
_processFailingPath: function(sourceEntityPathParts) {
var resultString = '';
var collectionIndex = -1;
var failingPathParts = [];
for (var i = 0; i < sourceEntityPathParts.length; i++) {
var part = sourceEntityPathParts[i];
if (part.endsWith('[*]')) {
collectionIndex++;
var collectionName = part.slice(0, part.indexOf('['));
failingPathParts.push(collectionName + '[\'+' + collectionName + '_' + collectionIndex + '+\']');
} else {
failingPathParts.push(part);
}
}
resultString += failingPathParts.join('.');
return resultString;
},
deleteOperations: function(operationIds) {
if (!operationIds)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("No operation ids sent to deleteOperations")));
var operationGr = new GlideRecord(this.SYS_RTE_EB_OPERATION);
operationGr.addQuery(this.SYS_ID, 'IN', operationIds);
operationGr.query();
operationGr.deleteMultiple();
},
getOperationType: function(typeId) {
if (!typeId)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("No type id sent to getOperationTypes")));
var typeGr = new GlideRecord(this.SYS_RTE_EB_OPERATION_TYPE);
typeGr.get(typeId);
return typeGr;
},
getOperationGraph: function(entityId) {
var errorObj = {};
if (!entityId)
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("No entity id sent to getOperationGraph")));
var graph = {};
var nodes = {};
var edges = {};
var fields = this.getEntityFieldsForEntity(entityId);
for (var i = 0; i < fields.length; i++) {
nodes[fields[i].sys_id] = {};
nodes[fields[i].sys_id].name = fields[i].name;
nodes[fields[i].sys_id].field = fields[i].field;
}
edges[this.SET] = {};
var operationGr = new GlideRecord(this.SYS_RTE_EB_OPERATION);
operationGr.addQuery(this.SYS_RTE_EB_ENTITY, entityId);
operationGr.query();
while (operationGr.next()) {
var isSetOperation = false;
var sys_id = operationGr.getUniqueValue();
var type = operationGr.getValue(this.TYPE);
isSetOperation = (type === this.getSetOperationTypeSysId());
var sourceIds = operationGr.getValue(this.SOURCE_SYS_RTE_EB_FIELD);
if (!sourceIds)
sourceIds = operationGr.getValue(this.SOURCE_SYS_RTE_EB_FIELDS);
var targetIds = operationGr.getValue(this.TARGET_SYS_RTE_EB_FIELD);
if (!targetIds)
targetIds = operationGr.getValue(this.TARGET_SYS_RTE_EB_FIELDS);
if ((!sourceIds && !isSetOperation) || !targetIds) {
gs.error("Error while reading operation " + sys_id + ", source or target ids are missing");
errorObj = this.buildErrorObject(gs.getMessage("Missing source or target fields in RTE Entity Operations table records invalidates the ETL Transform Map, which might have happened during data migration. Contact ServiceNow Support for assistance."), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
if (isSetOperation)
sourceIds = '';
sourceIds = sourceIds.split(',');
targetIds = targetIds.split(',');
// handle special case for extract first numeric which creates a different value
if (operationGr.getDisplayValue("type.table") === this.EXTRACT_NUMERIC_OPERATION) {
var realTableOperationGr = new GlideRecord(this.EXTRACT_NUMERIC_OPERATION);
if (!realTableOperationGr.get(sys_id)) {
gs.error("Error while getting operation " + sys_id + ", operation does not exist in correct table");
continue;
}
var remainderField = realTableOperationGr.getValue("remainder_target_field");
if (remainderField)
targetIds.push(remainderField);
}
if (!isSetOperation) {
for (var j = 0; j < sourceIds.length; j++) {
for (var k = 0; k < targetIds.length; k++) {
edges[sourceIds[j]] = edges[sourceIds[j]] || {};
edges[sourceIds[j]][targetIds[k]] = {};
edges[sourceIds[j]][targetIds[k]].operationTypeId = type;
edges[sourceIds[j]][targetIds[k]].operationId = sys_id;
}
}
}
// handle SET scenario
else if (isSetOperation && targetIds.length === 1) {
edges[this.SET][targetIds[0]] = {};
edges[this.SET][targetIds[0]].operationTypeId = type;
edges[this.SET][targetIds[0]].operationId = sys_id;
}
}
graph.nodes = nodes;
graph.edges = edges;
return graph;
},
saveOperation: function(feedId, source, target, operation, option) {
var errorObj = {};
var isNewOperation = (option === this.POST);
var isSetOperation = operation.type === this.getSetOperationTypeSysId();
var result = {
fieldsCreated: [],
operationCreated: {},
status: ''
};
var operationTypeGr = new GlideRecord(this.SYS_RTE_EB_OPERATION_TYPE);
if (!operationTypeGr.get(operation.type)) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to find operation type"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
var targetFieldIds = [];
var multipleInputFields = this.parseBooleanString(operationTypeGr.getDisplayValue(this.HAS_MULTIPLE_INPUT_FIELDS));
var multipleOutputFields = this.parseBooleanString(operationTypeGr.getDisplayValue(this.HAS_MULTIPLE_OUTPUT_FIELDS));
if (isNewOperation) {
var targetNames = target.split(',');
for (var i = 0; i < targetNames.length; i++) {
var targetGr = this.createEntityField(feedId, source.entityId, targetNames[i], targetNames[i]);
if (!targetGr.getValue)
return targetGr;
result.fieldsCreated.push({
field: targetGr.getValue(this.FIELD),
name: targetGr.getValue(this.NAME),
sys_id: targetGr.getUniqueValue()
});
targetFieldIds.push(targetGr.getValue(this.SYS_ID));
}
}
var sourceFields = [];
if (!isSetOperation)
sourceFieldIds = source.fieldIds.split(',');
var operationGr = new GlideRecord(this.SYS_RTE_EB_OPERATION);
operationGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
operationGr.addNotNullQuery(this.ORDER);
operationGr.orderByDesc(this.ORDER);
operationGr.setLimit(1);
operationGr.query();
var highestOrder = 0;
if (operationGr.next())
highestOrder = operationGr.getValue('order');
highestOrder = parseInt(highestOrder);
// determine the order
var order = 100;
if (!isNaN(highestOrder))
order = Math.max(100, highestOrder + 100);
if (isSetOperation)
order = 1;
var table = operationTypeGr.getValue(this.TABLE);
operationGr = new GlideRecord(table);
if (isNewOperation)
operationGr.initialize();
else {
if (!operationGr.get(option)) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to find operation"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
}
operationGr.setValue(this.SYS_RTE_EB_DEFINITION, feedId);
operationGr.setValue(this.SYS_RTE_EB_ENTITY, source.entityId);
operationGr.setValue(this.TYPE, operation.type);
operationGr.setValue(this.NAME, operation.transformDescription);
if (isNewOperation)
operationGr.setValue(this.ORDER, order);
if (!isSetOperation) {
if (multipleInputFields)
operationGr.setValue(this.SOURCE_SYS_RTE_EB_FIELDS, sourceFieldIds.join());
else
operationGr.setValue(this.SOURCE_SYS_RTE_EB_FIELD, sourceFieldIds.join());
}
if (isNewOperation) {
if (multipleOutputFields)
operationGr.setValue(this.TARGET_SYS_RTE_EB_FIELDS, targetFieldIds.join());
else
operationGr.setValue(this.TARGET_SYS_RTE_EB_FIELD, targetFieldIds.join());
}
for (var param in operation.optionalParams) {
// First check if this a valid param on the operation table
if (operationGr.isValidField(param)) {
// Get the type of the param and the actual value
var paramType = operation.optionalParams[param].type;
var paramValue = operation.optionalParams[param].value;
if (paramType === 'string' || paramType === 'choice') {
operationGr.setValue(param, paramValue);
}
else if (isNewOperation && paramType === 'field' && paramValue) {
// create a new field for this operation
var newFieldGr = this.createEntityField(feedId, source.entityId, paramValue, paramValue);
if (!newFieldGr.getValue)
return newFieldGr;
operationGr.setValue(param, newFieldGr.getUniqueValue());
result.fieldsCreated.push({
field: newFieldGr.getValue(this.FIELD),
name: newFieldGr.getValue(this.NAME),
sys_id: newFieldGr.getUniqueValue()
});
}
}
}
if (isNewOperation) {
if (!operationGr.insert()) {
// revert the created fields
var listOfFieldIds = result.fieldsCreated.map(function(field) {
return field.sys_id;
}).join();
if (listOfFieldIds)
this.deleteFields(listOfFieldIds);
errorObj = this.buildErrorObject(gs.getMessage("Failed to insert operation"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
} else {
if (!operationGr.update()) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to update operation"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
}
order = parseInt(operationGr.getValue(this.ORDER));
if (isNaN(order))
order = -1;
result.operationCreated = {
operationTypeSysId: operationGr.getValue(this.TYPE),
operationType: operationGr.type.name + '',
description: operationGr.getValue(this.NAME),
order: order,
sourceField: operationGr.getValue(this.SOURCE_SYS_RTE_EB_FIELD),
sourceFields: operationGr.getValue(this.SOURCE_SYS_RTE_EB_FIELDS),
targetField: operationGr.getValue(this.TARGET_SYS_RTE_EB_FIELD),
targetFields: operationGr.getValue(this.TARGET_SYS_RTE_EB_FIELDS),
operationSysId: operationGr.getUniqueValue(),
additionalParams: operation.optionalParams
};
for (var parameter in operation.optionalParams) {
if (operationGr.isValidField(parameter)) {
result.operationCreated.additionalParams[parameter] = {
value: operationGr.getValue(parameter),
displayValue: operationGr.getDisplayValue(parameter)
};
}
}
// update the created fields to add the operation
for (var j = 0; j < result.fieldsCreated.length; j++) {
var field = result.fieldsCreated[j];
field.operation = result.operationCreated;
}
result.status = this.SUCCESS;
return result;
},
deleteClass: function(feedId, entityId, isRecommendedClass, isRecursionLevel) {
var errorObj = {};
entityId = entityId.split(',');
var entityMappingId = [];
var entityIdToConceptualClassMap = {};
var entityIdToEntityMappingIdMap = {};
var entityPath = '';
var isNestedPayload = this.isNestedPayload(feedId);
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, entityId);
entityGr.query();
while (entityGr.next()) {
entityIdToConceptualClassMap[entityGr.getValue(this.SYS_ID)] = entityGr.getValue('table');
entityPath = entityGr.getValue(this.PATH);
}
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, entityId);
entityMappingGr.query();
// Get entity mapping ids
while (entityMappingGr.next()) {
var mappingId = entityMappingGr.getValue(this.SYS_ID);
var targetEntityId = entityMappingGr.getValue(this.TARGET_SYS_RTE_EB_ENTITY);
entityMappingId.push(mappingId);
entityIdToEntityMappingIdMap[targetEntityId] = mappingId;
}
// Delete fields
var entityFieldGr = new GlideRecord(this.SYS_RTE_EB_FIELD);
entityFieldGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityFieldGr.addQuery(this.SYS_RTE_EB_ENTITY, entityId);
entityFieldGr.query();
entityFieldGr.deleteMultiple();
// Delete field mappings for this entity mapping
var entityFieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
entityFieldMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityFieldMappingGr.addQuery(this.SYS_RTE_EB_ENTITY_MAPPING, entityMappingId);
entityFieldMappingGr.query();
entityFieldMappingGr.deleteMultiple();
// Get all entity mapping ids for relationship entities
var relEntityMappings = this.getCmdbRelationEntityMappings(feedId);
var relEntityMappingIds = Object.keys(relEntityMappings);
// Also delete all field mappings where this is referenced
entityFieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
entityFieldMappingGr.addQuery(this.REFERENCED_SYS_RTE_EB_ENTITY, entityId);
entityFieldMappingGr.query();
if (relEntityMappingIds.length > 0) {
while (entityFieldMappingGr.next()) {
// Check if this is for rel
var id = entityFieldMappingGr.getValue(this.SYS_RTE_EB_ENTITY_MAPPING);
if (relEntityMappingIds.indexOf(id) > -1)
this.deleteClass(feedId, relEntityMappings[id], false, true);
}
}
// Delete field mapping records;
entityFieldMappingGr.deleteMultiple();
var lookupEntityGr = new GlideRecord(this.CMDB_INST_ENTITY);
lookupEntityGr.addQuery(this.LOOKUP_FOR_ENTITY, entityId);
lookupEntityGr.query();
while (lookupEntityGr.next()) {
var sysId = lookupEntityGr.getUniqueValue();
this.deleteClass(feedId, sysId, false, true);
}
if (isNestedPayload && entityPath) {
var entityPathParts = entityPath.split('.');
var selfPath = entityPathParts[entityPathParts.length - 1];
this.updateChildEntityPath(entityId, selfPath + '.', '');
}
var cmdbRecommendations = new CmdbRecommendations();
var isRecommendationDataCaptureEnabled = this.parseBooleanString(gs.getProperty('sn_int_studio.recommendation.data_capture'));
if(isRecommendationDataCaptureEnabled && !isRecursionLevel) {
var applicationFeed = this.getApplicationFeed(feedId);
if (!applicationFeed) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to get Application Feed"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
var dataSource = applicationFeed.sys_data_source.name + '';
if (!dataSource) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to get Data Source from Application Feed"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
var tempEntities = "";
var impEntityGr = this.findImpCmdbEntity(feedId);
if (impEntityGr.getUniqueValue) {
tempEntities = this.findTempCmdbEntity(feedId, impEntityGr.getUniqueValue());
}
var tempEntityPaths = Object.keys(tempEntities);
var sourceFields = [];
for (var i = 0; i < tempEntityPaths.length; i++) {
var tempEntityPath = tempEntityPaths[i];
var tempEntity = tempEntities[tempEntityPath];
var tempEntityId = tempEntity[this.SYS_ID];
var sourceFieldsList = this.getEntityFieldsForEntity(tempEntityId);
for (var j = 0; j < sourceFieldsList.length; j++) {
sourceFields.push(sourceFieldsList[j].field);
}
}
// Delete recommendation state record
if(isRecommendedClass) {
var delStateRe = cmdbRecommendations.deleteClassRecommendationState(feedId, entityIdToConceptualClassMap[entityId[0]]);
if (delStateRe.status == 'failure') {
errorObj = this.buildErrorObject(deleteClassRecState.error.message, '', {deleteState: deleteClassRecState});
throw this.getInternalServerError(errorObj);
}
}
for (var k = 0; k < entityId.length; k++) {
var currentEntityId = entityId[k];
var conceptualClass = entityIdToConceptualClassMap[currentEntityId];
var currentEntityMappingId = entityIdToEntityMappingIdMap[currentEntityId];
// Delete class recommendation record
var deleteClassRec = cmdbRecommendations.deleteClassRecommendation(currentEntityMappingId, dataSource, conceptualClass, sourceFields);
if (deleteClassRec.status == 'failure') {
errorObj = this.buildErrorObject(deleteClassRec.error.message, '', {deleteState: deleteClassRec});
throw this.getInternalServerError(errorObj);
}
}
}
// Delete entity mapping
entityMappingGr.deleteMultiple();
// Delete entity
entityGr.deleteMultiple();
if (isRecommendationDataCaptureEnabled) {
var delEmptyAttrState = cmdbRecommendations.deleteAttributeRecommendationStateWithEmptyEntityMapping();
if (delEmptyAttrState.status == 'failure') {
this.internalServerError.setMessage(delEmptyAttrState.error.message);
return this.internalServerError;
}
}
return this.SUCCESS;
},
saveClass: function(feedId, tempEntityPath, tempEntitySysId, name, path, table, conditionScript, order, groupId, condition, lookupEntity, isRecommendedClass, ignore) {
var errorObj = {};
var cmdbEntityIdRecord = this.createCmdbEntity(feedId, name, path, table, '', lookupEntity);
var cmdbEntityId = cmdbEntityIdRecord.getUniqueValue();
if (!cmdbEntityId) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to save class"), gs.getMessage('Failed to insert CMDB entity record'), {args: arguments});
throw this.getInternalServerError(errorObj);
}
var entityMappingGr = this.createMappingBetweenEntities(feedId, tempEntityPath + 'To' + name, tempEntitySysId, cmdbEntityId, conditionScript, order, groupId, condition, ignore);
if (!entityMappingGr || !entityMappingGr.getUniqueValue()) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to save class"), gs.getMessage('Failed to insert entity mapping record'), {args: arguments});
throw this.getInternalServerError(errorObj);
}
var isNestedPayload = this.isNestedPayload(feedId);
if (isNestedPayload) {
this.orderSecondStageMapping(feedId);
}
var isRecommendationDataCaptureEnabled = this.parseBooleanString(gs.getProperty('sn_int_studio.recommendation.data_capture'));
if(isRecommendationDataCaptureEnabled && isRecommendedClass) {
var cmdbRecomendations = new CmdbRecommendations();
var classRecomendationStateId = cmdbRecomendations.changeClassRecommendationState(feedId, table, 'applied');
if (classRecomendationStateId == null) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to change class recommendation state"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
}
return {
entities: {
name: cmdbEntityIdRecord.getValue(this.NAME),
table: cmdbEntityIdRecord.getValue(this.TABLE),
path: cmdbEntityIdRecord.getValue(this.PATH),
lookup_for_entity: cmdbEntityIdRecord.getValue(this.LOOKUP_FOR_ENTITY),
related_for_entity: cmdbEntityIdRecord.getValue(this.RELATED_FOR_ENTITY),
relationship_type_string: cmdbEntityIdRecord.getValue(this.RELATIONSHIP_TYPE_STRING),
sys_id: cmdbEntityIdRecord.getUniqueValue()
},
entitiesMapping: {
encoded_query: entityMappingGr.getValue(this.ENCODED_QUERY),
condition_script: entityMappingGr.getValue(this.CONDITION_SCRIPT),
is_conditional: entityMappingGr.getDisplayValue(this.IS_CONDITIONAL),
name: entityMappingGr.getValue(this.NAME),
order: entityMappingGr.getValue(this.ORDER),
source_sys_rte_eb_entity: entityMappingGr.getValue(this.SOURCE_SYS_RTE_EB_ENTITY),
sys_id: entityMappingGr.getUniqueValue(),
target_sys_rte_eb_entity: entityMappingGr.getValue(this.TARGET_SYS_RTE_EB_ENTITY),
group_id: entityMappingGr.getValue(this.ENTITY_MAPPING_GROUP)
}
};
},
createFieldAndFieldMapping: function(feedId, entityId, source, target, refEntityId, entityMappingId, targetFieldPath) {
var isNestedPayload = this.isNestedPayload(feedId);
var isFirstFieldMapping = false;
var targetTempEntityId = '';
var targetTempPath = '';
if (!targetFieldPath) {
targetFieldPath = target;
}
if (!refEntityId && isNestedPayload) {
var fieldGr = new GlideRecord(this.SYS_RTE_EB_FIELD);
fieldGr.addQuery(this.SYS_ID, source);
fieldGr.query();
if (fieldGr.next()) {
targetTempPath = fieldGr.sys_rte_eb_entity.path + '';
targetTempEntityId = fieldGr.getValue(this.SYS_RTE_EB_ENTITY);
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find field with id {0}', source));
throw this.getInternalServerError(errorObj);
}
var fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.SYS_RTE_EB_ENTITY_MAPPING, entityMappingId);
fieldMappingGr.addNullQuery(this.REFERENCED_SYS_RTE_EB_ENTITY);
fieldMappingGr.query();
if (fieldMappingGr.next()) {
var existingTempPath = fieldMappingGr.sys_rte_eb_entity_mapping.source_sys_rte_eb_entity.path + '';
if (existingTempPath != targetTempPath) {
errorObj = this.buildErrorObject(gs.getMessage('Target field temp path {0} does not match existing temp path {1}', [targetTempPath, existingTempPath]));
throw this.getInternalServerError(errorObj);
}
} else {
isFirstFieldMapping = true;
}
}
var entityFields = this.getEntityFieldsForEntity(entityId);
var foundEntityField = -1;
for (var i = 0; i < entityFields.length; i++) {
if (entityFields[i].field === targetFieldPath) {
foundEntityField = i;
break;
}
}
if (foundEntityField > -1)
var cmdbFieldId = entityFields[foundEntityField].sys_id;
else {
var cmdbFieldGr = this.createEntityField(feedId, entityId, targetFieldPath, target);
if (!cmdbFieldGr.getValue) {
return cmdbFieldGr;
}
var cmdbFieldId = cmdbFieldGr.getValue(this.SYS_ID);
}
var fieldMappingGr;
var field_mapping_ids = [];
// Check if this is reference or direct attribute mapping
if (refEntityId) {
if (isNestedPayload) {
fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.SYS_RTE_EB_ENTITY_MAPPING, entityMappingId);
fieldMappingGr.addNullQuery(this.REFERENCED_SYS_RTE_EB_ENTITY);
fieldMappingGr.query();
if (!fieldMappingGr.next()) {
var targetClassName = '';
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_ID, entityMappingId);
entityMappingGr.query();
if (entityMappingGr.next()) {
targetClassName = entityMappingGr[this.TARGET_SYS_RTE_EB_ENTITY].name + '';
}
errorObj = this.buildErrorObject(gs.getMessage('Please map at least one non-reference field in class \'{0}\'.', targetClassName));
throw this.getInternalServerError(errorObj);
}
}
var refEntityIdArr = refEntityId.split(',');
for (var i = 0; i < refEntityIdArr.length; i++) {
fieldMappingGr = this.createFieldMappingsWithEntityRef(feedId, entityMappingId, refEntityId, cmdbFieldId, '100');
field_mapping_ids.push(fieldMappingGr.getValue(this.SYS_ID));
}
} else {
if (isFirstFieldMapping && isNestedPayload) {
var targetEntityId = '';
var targetEntityPath = '';
var targetEntityLookupEntityId = '';
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_ID, entityMappingId);
entityMappingGr.query();
if (entityMappingGr.next()) {
targetEntityId = entityMappingGr.getValue(this.TARGET_SYS_RTE_EB_ENTITY);
targetEntityPath = entityMappingGr.target_sys_rte_eb_entity.path + '';
targetEntityLookupEntityId = entityMappingGr.target_sys_rte_eb_entity.lookup_for_entity + '';
var targetEntityName = entityMappingGr.target_sys_rte_eb_entity.name + '';
var currentTempEntityId = entityMappingGr.getValue(this.SOURCE_SYS_RTE_EB_ENTITY);
var targetTempPathParts = targetTempPath.split('.');
var targetTempSelfPath = targetTempPathParts[targetTempPathParts.length - 1];
var targetEntityPathParts = targetEntityPath.split('.');
var targetEntitySelfPath = targetEntityPathParts[targetEntityPathParts.length - 1];
if (currentTempEntityId != targetTempEntityId) {
var prefixErrorMsg = gs.getMessage('Cannot change the branch of source data because class');
var lookupEntityName = entityMappingGr.target_sys_rte_eb_entity.lookup_for_entity.name + '';
var associatedEntityName = entityMappingGr.target_sys_rte_eb_entity.related_for_entity.name + '';
if (lookupEntityName) {
errorObj = this.buildErrorObject(gs.getMessage('{0} \'{1}\' has lookup class \'{2}\'', [prefixErrorMsg, targetEntityName, lookupEntityName]));
throw this.getInternalServerError(errorObj);
}
if (associatedEntityName) {
errorObj = this.buildErrorObject(gs.getMessage('{0} \'{1}\' has associated class \'{2}\'', [prefixErrorMsg, targetEntityName, associatedEntityName]));
throw this.getInternalServerError(errorObj);
}
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.LOOKUP_FOR_ENTITY, targetEntityId);
entityGr.query();
if (entityGr.next()) {
var className = entityGr.getValue(this.NAME);
errorObj = this.buildErrorObject(gs.getMessage('{0} \'{1}\' is lookup class for class \'{2}\'', [prefixErrorMsg, targetEntityName, className]));
throw this.getInternalServerError(errorObj);
}
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.RELATED_FOR_ENTITY, targetEntityId);
entityGr.query();
if (entityGr.next()) {
var className = entityGr.getValue(this.NAME);
errorObj = this.buildErrorObject(gs.getMessage('{0} \'{1}\' is associated class for class \'{2}\'', [prefixErrorMsg, targetEntityName, className]));
throw this.getInternalServerError(errorObj);
}
var fieldMappingGr2 = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr2.addQuery(this.SYS_RTE_EB_ENTITY_MAPPING, entityMappingId);
fieldMappingGr2.addNotNullQuery(this.REFERENCED_SYS_RTE_EB_ENTITY);
fieldMappingGr2.query();
if (fieldMappingGr2.next()) {
var childEntityName = fieldMappingGr2[this.REFERENCED_SYS_RTE_EB_ENTITY].name + '';
errorObj = this.buildErrorObject(gs.getMessage('{0} \'{1}\' references class \'{2}\'', [prefixErrorMsg, targetEntityName, childEntityName]));
throw this.getInternalServerError(errorObj);
}
fieldMappingGr2 = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr2.addQuery(this.REFERENCED_SYS_RTE_EB_ENTITY, targetEntityId);
fieldMappingGr2.query();
if (fieldMappingGr2.next()) {
var childEntityTable = fieldMappingGr2.sys_rte_eb_entity_mapping.target_sys_rte_eb_entity.table + '';
var childEntityName = fieldMappingGr2.sys_rte_eb_entity_mapping.target_sys_rte_eb_entity.name + '';
if (childEntityTable == this.CMDB_REL_CI) {
var relClassName = '';
var relEntityMappingId = fieldMappingGr2.sys_rte_eb_entity_mapping;
var fieldMappingGr3 = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr3.addQuery(this.SYS_RTE_EB_ENTITY_MAPPING, relEntityMappingId);
fieldMappingGr3.addQuery(this.REFERENCED_SYS_RTE_EB_ENTITY, '!=', targetEntityId);
fieldMappingGr3.query();
if (fieldMappingGr3.next()) {
relClassName = fieldMappingGr3[this.REFERENCED_SYS_RTE_EB_ENTITY].name + '';
}
errorObj = this.buildErrorObject(gs.getMessage('{0} \'{1}\' has relationship with \'{2}\' class.', [prefixErrorMsg, targetEntityName, relClassName]));
throw this.getInternalServerError(errorObj);
} else {
errorObj = this.buildErrorObject(gs.getMessage('{0} \'{1}\' references class \'{2}\'', [prefixErrorMsg, childEntityName, targetEntityName]));
throw this.getInternalServerError(errorObj);
}
}
var currentEntityMappingLabel = entityMappingGr.getValue(this.NAME);
var currentEntityMappingLabelParts = currentEntityMappingLabel.split('To');
currentEntityMappingLabelParts[0] = targetTempPath;
var newEntityMappingLabel = currentEntityMappingLabelParts.join('To');
entityMappingGr.setValue(this.SOURCE_SYS_RTE_EB_ENTITY, targetTempEntityId);
entityMappingGr.setValue(this.NAME, newEntityMappingLabel);
entityMappingGr.update();
this.updateChildEntityPath(targetEntityId, targetEntitySelfPath + '.', '');
}
var updatePath = '';
var isSameLevelLookup = false;
if (targetEntityLookupEntityId) {
var targetEntityLookupEntityTempPath = '';
entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, targetEntityLookupEntityId);
entityMappingGr.query();
if (entityMappingGr.next()) {
targetEntityLookupEntityTempPath = entityMappingGr[this.SOURCE_SYS_RTE_EB_ENTITY].path + '';
if (targetEntityLookupEntityTempPath.split('.').length == targetTempPathParts.length) {
isSameLevelLookup = true;
}
}
}
if (isSameLevelLookup) {
updatePath = '';
} else if (targetTempSelfPath.indexOf('[*]') < 0 && targetTempPathParts.length > 1 && targetTempPath.indexOf('[*]') > -1 && targetEntityPathParts.length == 1 && targetEntitySelfPath.indexOf('[*]') < 0) {
updatePath = targetEntityPath + '[*]';
} else if (targetTempSelfPath.indexOf('[*]') > -1 && targetEntitySelfPath.indexOf('[*]') < 0) {
updatePath = targetEntityPath + '[*]';
} else if (targetTempSelfPath.indexOf('[*]') < 0 && targetEntitySelfPath.indexOf('[*]') > -1 && !(targetTempPathParts.length > 1 && targetTempPath.indexOf('[*]') > -1 && targetEntityPathParts.length == 1)) {
targetEntityPathParts[targetEntityPathParts.length - 1] = targetEntitySelfPath.substring(0, targetEntitySelfPath.length - 3);
updatePath = targetEntityPathParts.join('.');
}
if (updatePath) {
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, targetEntityId);
entityGr.query();
if (entityGr.next()) {
entityGr.setValue(this.PATH, updatePath);
entityGr.update();
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity with id {0}', targetEntityId));
throw this.getInternalServerError(errorObj);
}
}
}
}
fieldMappingGr = this.createMappingBetweenEntityFields(feedId, entityMappingId, source, cmdbFieldId, '100');
field_mapping_ids.push(fieldMappingGr.getValue(this.SYS_ID));
}
return {
field_id: cmdbFieldId,
field_mapping_id: field_mapping_ids.length === 1 ? field_mapping_ids[0] : '',
field_mapping_ids: field_mapping_ids
};
},
createUniqueEntityNameAndPath: function(feedId, label, table) {
var existingNames = [];
var existingPaths = [];
var entities = this.getEntitiesForApplicationFeed(feedId, 'table=' + table);
for (var i = 0; i < entities.length; i++) {
existingNames.push(entities[i].name);
existingPaths.push(entities[i].path);
}
var count = 1;
while (true) {
var potentialName = label + ' ' + count;
var potentialPath = table + '_' + count;
if (existingNames.indexOf(potentialName) < 0 && existingPaths.indexOf(potentialPath) < 0) {
return {
name: potentialName,
path: potentialPath
};
}
count++;
}
},
getSavedOperationsForFeed: function(feedId) {
var errorObj = {};
var allFieldsPerOperationType = {};
var operationTypesGr = new GlideRecord(this.SYS_RTE_EB_OPERATION_TYPE);
operationTypesGr.query();
while (operationTypesGr.next()) {
var table = operationTypesGr.getValue(this.TABLE);
allFieldsPerOperationType[table] = [];
}
var allTables = Object.keys(allFieldsPerOperationType);
// get the columns from sys dictionary
for (var i = 0; i < allTables.length; i++)
allFieldsPerOperationType[allTables[i]] = this.getTableColumns(allTables[i]);
var allOperations = {};
var operationGr = new GlideRecord(this.SYS_RTE_EB_OPERATION);
operationGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
operationGr.query();
while (operationGr.next()) {
var operationTypeTable = operationGr.getDisplayValue('type.table');
var operationSysId = operationGr.getUniqueValue();
var order = parseInt(operationGr.getValue(this.ORDER));
if (isNaN(order))
order = -1;
allOperations[operationSysId] = {
operationTypeSysId: operationGr.getValue(this.TYPE),
description: operationGr.getValue(this.NAME),
order: order,
sourceField: operationGr.getValue(this.SOURCE_SYS_RTE_EB_FIELD),
sourceFields: operationGr.getValue(this.SOURCE_SYS_RTE_EB_FIELDS),
targetField: operationGr.getValue(this.TARGET_SYS_RTE_EB_FIELD),
targetFields: operationGr.getValue(this.TARGET_SYS_RTE_EB_FIELDS),
operationSysId: operationSysId,
additionalParams: {}
};
// add the additional parameters specific to the each operation
if (allFieldsPerOperationType[operationTypeTable].length > 0) {
var correctOperationTableGr = new GlideRecord(operationTypeTable);
if (!correctOperationTableGr.get(operationSysId)) {
errorObj = this.buildErrorObject(gs.getMessage("Operation not found on the right table"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
for (var j = 0; j < allFieldsPerOperationType[operationTypeTable].length; j++) {
allOperations[operationSysId].additionalParams[allFieldsPerOperationType[operationTypeTable][j]] = {
value: correctOperationTableGr.getValue(allFieldsPerOperationType[operationTypeTable][j]),
displayValue: correctOperationTableGr.getDisplayValue(allFieldsPerOperationType[operationTypeTable][j])
};
}
}
}
return allOperations;
},
parseBooleanString: function(booleanString) {
if (booleanString)
return booleanString === 'true' ? true : false;
return false;
},
getCmdbRelationEntityMappings: function(feedId) {
var relEntities = this.getEntitiesForApplicationFeed(feedId, 'table=cmdb_rel_ci');
var sysIds = [];
for (var i = 0; i < relEntities.length; i++) {
sysIds.push(relEntities[i].sys_id);
}
// Now get mappings for these
var entityMappings = this.getEntityMappingsForApplicationFeed(feedId, 'target_sys_rte_eb_entityIN' + sysIds.join());
var entityMappingIds = {};
for (var j = 0; j < entityMappings.length; j++) {
entityMappingIds[entityMappings[j].sys_id] = entityMappings[j].target_sys_rte_eb_entity;
}
return entityMappingIds;
},
getSetOperationTypeSysId: function() {
var gr = new GlideRecord(this.SYS_RTE_EB_OPERATION_TYPE);
gr.addQuery(this.TABLE, 'sys_rte_eb_set_operation');
gr.setLimit(1);
gr.query();
if (gr.hasNext()) {
gr.next();
return gr.getUniqueValue();
}
return '';
},
getUpdatedSysIdsFromMap: function(currentString, sysIdMap) {
var existingSysIds = currentString.split(',');
return existingSysIds.map(function(sysId) {
return sysIdMap[sysId];
}).join();
},
canCopyFeed: function(sourceDataSourceGr, targetDataSourceGr) {
var errorObj = {};
// First, check that data sources given are unique
if (sourceDataSourceGr.getValue(this.SYS_ID) === targetDataSourceGr.getValue(this.SYS_ID))
return false;
if (!sourceDataSourceGr.import_set_table_name) {
errorObj = this.buildErrorObject(gs.getMessage("Invalid import set table name for selected data source '{0}'.", [sourceDataSourceGr.name]));
throw this.getInternalServerError(errorObj);
}
if (!targetDataSourceGr.import_set_table_name) {
errorObj = this.buildErrorObject(gs.getMessage("Invalid import set table name for data source '{0}' associated to this map.", [targetDataSourceGr.name]));
throw this.getInternalServerError(errorObj);
}
var sourceFields = this.getTableColumns(sourceDataSourceGr.import_set_table_name);
var destFields = this.getTableColumns(targetDataSourceGr.import_set_table_name);
if (sourceFields.length === 0) {
errorObj = this.buildErrorObject(gs.getMessage("Import set table columns are empty for selected data source '{0}'.", [sourceDataSourceGr.name]));
throw this.getInternalServerError(errorObj);
}
if (destFields.length === 0) {
errorObj = this.buildErrorObject(gs.getMessage("Import set table columns are empty for data source '{0}' associated to this map.", [targetDataSourceGr.name]));
throw this.getInternalServerError(errorObj);
}
// Check if field array lengths are not the same
if (sourceFields.length !== destFields.length)
return false;
else {
// If they have the same length, loop through and compare values from both arrays
for (var i = 0; i < sourceFields.length; i++) {
if (sourceFields[i] != destFields[i])
return false;
}
}
return true;
},
updateFeedMetadataWithNewImportSet: function(applicationFeedId) {
var isEmptyImportSet = false;
var isNestedPayload = this.isNestedPayload(applicationFeedId);
var forceMetadataReload = false;
var templateStateGr = new GlideRecord(this.CMDB_INST_TEMPLATE_STATE);
templateStateGr.addQuery('application_feed_id', applicationFeedId);
templateStateGr.query();
if (templateStateGr.next()) {
var importSetId = templateStateGr.getValue('import_set_id');
var impEntityGr = this.findImpCmdbEntity(applicationFeedId);
var impEntityId = '';
if (impEntityGr.getUniqueValue) {
impEntityId = impEntityGr.sys_id + '';
}
var importSetRunGr = new GlideRecord('sys_import_set_row');
importSetRunGr.addQuery('sys_import_state', '!=', 'test');
importSetRunGr.addQuery('sys_import_set', importSetId);
importSetRunGr.query();
if (!importSetRunGr.next()) {
isEmptyImportSet = true;
}
if (isNestedPayload && impEntityId && !isEmptyImportSet) {
var impTableColumns = [];
var returnedSchema = this.getNestedPayloadSchema(templateStateGr, false);
var rawSchemaStr = returnedSchema.rawSchemaStr;
var schema = returnedSchema.schemaJson;
var message = this.getNestedPayloadFields(schema, '', impTableColumns);
if (message) {
errorObj = this.buildErrorObject(message, '', '');
throw this.getInternalServerError(errorObj);
}
var existingImpFieldPaths = {};
var fieldGr = new GlideRecord(this.SYS_RTE_EB_FIELD);
fieldGr.addQuery(this.SYS_RTE_EB_ENTITY, impEntityId);
fieldGr.query();
while (fieldGr.next()) {
existingImpFieldPaths[fieldGr.getValue(this.FIELD)] = true;
}
var existingTempEntityPathToOrder = {};
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SOURCE_SYS_RTE_EB_ENTITY, impEntityId);
entityMappingGr.query();
while (entityMappingGr.next()) {
var path = entityMappingGr[this.TARGET_SYS_RTE_EB_ENTITY].path + '';
existingTempEntityPathToOrder[path] = Number(entityMappingGr.getValue(this.ORDER));
}
var tempEntitiesPaths = {};
for (var i = 0; i < impTableColumns.length; i++) {
var fieldParts = impTableColumns[i].split('.');
if (fieldParts.length > 1 && fieldParts[fieldParts.length - 2].indexOf('[*]') < 0) {
continue;
}
var path = 'temp';
for (var j = 0; j < fieldParts.length - 1; j++) {
path += '.' + fieldParts[j];
}
tempEntitiesPaths[path] = true;
}
var tempEntityKeys = Object.keys(tempEntitiesPaths);
tempEntityKeys.sort(function(a, b) {
var aLevelCount = a.split('.').length;
var bLevelCount = b.split('.').length;
if (aLevelCount - bLevelCount != 0) {
return aLevelCount - bLevelCount;
}
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
});
var tempEntities = {};
var tempEntityIdToMappingIdMap = {};
for (var i = 0; i < tempEntityKeys.length; i++) {
var path = tempEntityKeys[i];
var order = i * 10 + 100;
if (!existingTempEntityPathToOrder[path]) {
forceMetadataReload = true;
var tempEntityGr = this.createCmdbEntity(applicationFeedId, path, path, '', '');
if (!tempEntityGr.getUniqueValue()) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to create temp entity"), '', {pathParams: pathParams});
throw this.getInternalServerError(errorObj);
}
var tempEntity = {
name: tempEntityGr.getValue(this.NAME),
table: tempEntityGr.getValue(this.TABLE),
path: tempEntityGr.getValue(this.PATH),
lookup_for_entity: impEntityGr.getValue(this.LOOKUP_FOR_ENTITY),
related_for_entity: impEntityGr.getValue(this.RELATED_FOR_ENTITY),
relationship_type_string: impEntityGr.getValue(this.RELATIONSHIP_TYPE_STRING),
sys_id: tempEntityGr.getUniqueValue()
};
tempEntities[path] = tempEntity;
var impToTempMappingGr = this.createMappingBetweenEntities(applicationFeedId, 'impTo' + tempEntity.name, impEntityId, tempEntity.sys_id, '', order, '', '');
if (!impToTempMappingGr.getUniqueValue()) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to create imp to temp mapping"), '', {pathParams: pathParams});
throw this.getInternalServerError(errorObj);
}
tempEntityIdToMappingIdMap[tempEntity.sys_id] = impToTempMappingGr.getUniqueValue();
} else if (order != existingTempEntityPathToOrder[path] && !this.shouldDisableEntityMappingReorder(applicationFeedId)) {
forceMetadataReload = true;
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SOURCE_SYS_RTE_EB_ENTITY, impEntityId);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY + '.path', path);
entityMappingGr.query();
if (entityMappingGr.next()) {
entityMappingGr.setValue(this.ORDER, order);
entityMappingGr.update();
}
}
}
var order = 100;
if (impTableColumns && impTableColumns.length > 0) {
for (var i = 0; i < impTableColumns.length; i++) {
var impColumn = impTableColumns[i];
if (existingImpFieldPaths[impColumn]) {
continue;
}
var fieldParts = impColumn.split('.');
var lastPart = fieldParts[fieldParts.length - 1];
if (lastPart == this.NESTED_PAYLOAD_PLACEHOLDER_FIELD) {
continue;
}
var tempColumnParts = [];
for (var j = fieldParts.length - 1; j >= 0; j--) {
if (fieldParts[j].indexOf('[*]') < 0) {
tempColumnParts.push(fieldParts[j]);
} else {
break;
}
}
tempColumnParts.reverse();
var tempColumnSelfName = tempColumnParts[tempColumnParts.length - 1];
var tempColumn = tempColumnParts.join('.');
var impTableFieldGr = this.createEntityField(applicationFeedId, impEntityId, impColumn, impColumn);
var tempPath = 'temp';
var lastCollectionPath = 'temp';
for (var j = 0; j < fieldParts.length - 1; j++) {
tempPath += '.' + fieldParts[j];
if (fieldParts[j].indexOf('[*]') > -1) {
lastCollectionPath = tempPath;
}
}
var tempEntityId = '';
if (tempEntities[lastCollectionPath]) {
tempEntityId = tempEntities[lastCollectionPath].sys_id;
} else {
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.PATH, lastCollectionPath);
entityGr.addQuery(this.SYS_RTE_EB_DEFINITION, applicationFeedId);
entityGr.query();
if (entityGr.next()) {
tempEntityId = entityGr.getValue(this.SYS_ID);
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find temp entity with path \'{0}\'', [lastCollectionPath]));
throw this.getInternalServerError(errorObj);
}
}
var tempTableFieldGr = this.createEntityField(applicationFeedId, tempEntityId, tempColumn, tempColumnSelfName);
if (impTableFieldGr.getUniqueValue() && tempTableFieldGr.getUniqueValue()) {
var currentImpToTempMappingId = '';
if (tempEntityIdToMappingIdMap[tempEntityId]) {
currentImpToTempMappingId = tempEntityIdToMappingIdMap[tempEntityId];
} else {
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SOURCE_SYS_RTE_EB_ENTITY, impEntityId);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, tempEntityId);
entityMappingGr.query();
if (entityMappingGr.next()) {
currentImpToTempMappingId = entityMappingGr.getValue(this.SYS_ID);
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find temp entity mapping with path \'{0}\'', [tempPath]));
throw this.getInternalServerError(errorObj);
}
}
var impToTempFieldMappingGr = this.createMappingBetweenEntityFields(applicationFeedId, currentImpToTempMappingId, impTableFieldGr.getUniqueValue(), tempTableFieldGr.getUniqueValue(), order);
if (!impToTempFieldMappingGr.getUniqueValue()) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to create imp to temp field mapping"), '', {pathParams: pathParams});
throw this.getInternalServerError(errorObj);
}
}
}
}
} else {
if (impEntityGr.getUniqueValue) {
// We do have metadata setup, so check for diffs
var importSetTable = templateStateGr.getDisplayValue('import_set_id.table_name');
if (!importSetTable) {
errorObj = this.buildErrorObject(gs.getMessage("No import set table associated with this template state"), '', {pathParams: pathParams});
throw this.getInternalServerError(errorObj);
}
// Get all columns
var impTableColumns = this.getTableColumns(importSetTable);
// Get existing fields for imp entity
var impFields = this.getEntityFieldsForEntity(impEntityGr.getUniqueValue());
var encodedQuery = this.SOURCE_SYS_RTE_EB_ENTITY + '=' + impEntityGr.getUniqueValue();
var impToTempEntityMapping = this.getEntityMappingsForApplicationFeed(applicationFeedId, encodedQuery);
var order = 1000;
// Check for diff
for (var i = 0; i < impTableColumns.length; i++) {
// Check if record already exists
var impColumn = impTableColumns[i];
var isMapped = false;
for (var j = 0; j < impFields.length; j++) {
if (impFields[j].field === impColumn) {
isMapped = true;
break;
}
}
if (!isMapped) {
forceMetadataReload = true;
// Create imp field
var impTableFieldGr = this.createEntityField(applicationFeedId, impEntityGr.getUniqueValue(), impColumn, impColumn);
// Create temp field
var tempTableFieldGr = this.createEntityField(applicationFeedId, impToTempEntityMapping[0].target_sys_rte_eb_entity, impColumn, impColumn);
if (impTableFieldGr.getUniqueValue() && tempTableFieldGr.getUniqueValue()) {
this.createMappingBetweenEntityFields(applicationFeedId, impToTempEntityMapping[0].sys_id, impTableFieldGr.getUniqueValue(), tempTableFieldGr.getUniqueValue(), order);
order = order + 50;
}
}
}
}
}
}
return forceMetadataReload;
},
deepCopyFeed: function(sourceFeedId, targetFeedId) {
var errorObj = {};
var entities = {};
var entityMappings = {};
var fields = {};
var sourceFeedGr = new GlideRecord(this.CMDB_INST_APPLICATION_FEED);
if (!sourceFeedGr.get(sourceFeedId)) {
errorObj = this.buildErrorObject(gs.getMessage("Could not find record for given source Application Feed"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
var sourceDataSourceGr = new GlideRecord(this.SYS_DATA_SOURCE);
if (!sourceDataSourceGr.get(sourceFeedGr.getValue(this.SYS_DATA_SOURCE))) {
errorObj = this.buildErrorObject(gs.getMessage("Could not find record for Data Source associated with source Application Feed"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
var targetFeedGr = new GlideRecord(this.CMDB_INST_APPLICATION_FEED);
if (!targetFeedGr.get(targetFeedId)) {
errorObj = this.buildErrorObject(gs.getMessage("Could not find record for given target Application Feed"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
var targetDataSourceGr = new GlideRecord(this.SYS_DATA_SOURCE);
if (!targetDataSourceGr.get(targetFeedGr.getValue(this.SYS_DATA_SOURCE))) {
errorObj = this.buildErrorObject(gs.getMessage("Could not find record for Data Source associated with target Application Feed"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
var targetDataSourceTableName = targetDataSourceGr.getValue('import_set_table_name');
if (!this.canCopyFeed(sourceDataSourceGr, targetDataSourceGr)) {
errorObj = this.buildErrorObject(gs.getMessage("Cannot copy source feed to target feed"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_RTE_EB_DEFINITION, '=', sourceFeedId);
entityGr.orderBy('sys_created_on');
entityGr.query();
while (entityGr.next()) {
entityGr.setValue(this.SYS_RTE_EB_DEFINITION, targetFeedId);
if (entityGr.getValue(this.NAME) === this.IMPORT)
entityGr.setValue(this.TABLE, targetDataSourceTableName);
var originalId = entityGr.getValue(this.SYS_ID);
var entityId = entityGr.insert();
if (!entityId) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to create entity while copying"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
entities[originalId] = entityId;
var fieldGr = new GlideRecord(this.SYS_RTE_EB_FIELD);
fieldGr.addQuery(this.SYS_RTE_EB_DEFINITION, '=', sourceFeedId);
fieldGr.addQuery(this.SYS_RTE_EB_ENTITY, '=', originalId);
fieldGr.query();
while(fieldGr.next()) {
fieldGr.setValue(this.SYS_RTE_EB_DEFINITION, targetFeedId);
fieldGr.setValue(this.SYS_RTE_EB_ENTITY, entities[fieldGr.sys_rte_eb_entity]);
var originalFieldId = fieldGr.getValue(this.SYS_ID);
var fieldId = fieldGr.insert();
if (!fieldId) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to insert into entity field table while copying"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
fields[originalFieldId] = fieldId;
}
}
// Overwrite the lookup and related for values in the newly created entities with correct sys_id's
// Has to be done in a separate loop because there is no guarantee in original creation order
var newEntityGr = new GlideRecord(this.CMDB_INST_ENTITY);
newEntityGr.addQuery(this.SYS_RTE_EB_DEFINITION, '=', targetFeedId);
newEntityGr.orderBy('sys_created_on');
newEntityGr.query();
while (newEntityGr.next()) {
if (newEntityGr.lookup_for_entity)
newEntityGr.setValue(this.LOOKUP_FOR_ENTITY, entities[newEntityGr.lookup_for_entity]);
if (newEntityGr.related_for_entity)
newEntityGr.setValue(this.RELATED_FOR_ENTITY, entities[newEntityGr.related_for_entity]);
newEntityGr.update();
}
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, '=', sourceFeedId);
entityMappingGr.query();
while(entityMappingGr.next()) {
entityMappingGr.setValue(this.SYS_RTE_EB_DEFINITION, targetFeedId);
entityMappingGr.setValue(this.SOURCE_SYS_RTE_EB_ENTITY, entities[entityMappingGr.source_sys_rte_eb_entity]);
entityMappingGr.setValue(this.TARGET_SYS_RTE_EB_ENTITY, entities[entityMappingGr.target_sys_rte_eb_entity]);
var originalMappingId = entityMappingGr.getValue(this.SYS_ID);
var entityMappingId = entityMappingGr.insert();
if (!entityMappingId) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to insert into entity mapping table while copying"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
entityMappings[originalMappingId] = entityMappingId;
var fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, '=', sourceFeedId);
fieldMappingGr.addQuery(this.SYS_RTE_EB_ENTITY_MAPPING, '=', originalMappingId);
fieldMappingGr.query();
while (fieldMappingGr.next()) {
fieldMappingGr.setValue(this.SYS_RTE_EB_DEFINITION, targetFeedId);
fieldMappingGr.setValue(this.SYS_RTE_EB_ENTITY_MAPPING, entityMappings[fieldMappingGr.sys_rte_eb_entity_mapping]);
if (fieldMappingGr.referenced_sys_rte_eb_entity)
fieldMappingGr.setValue(this.REFERENCED_SYS_RTE_EB_ENTITY, entities[fieldMappingGr.referenced_sys_rte_eb_entity]);
if (fieldMappingGr.source_sys_rte_eb_field)
fieldMappingGr.setValue(this.SOURCE_SYS_RTE_EB_FIELD, fields[fieldMappingGr.source_sys_rte_eb_field]);
fieldMappingGr.setValue(this.TARGET_SYS_RTE_EB_FIELD, fields[fieldMappingGr.target_sys_rte_eb_field]);
if (!fieldMappingGr.insert()) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to insert into entity field mapping table while copying"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
}
}
var operationGr = new GlideRecord(this.SYS_RTE_EB_OPERATION);
operationGr.addQuery(this.SYS_RTE_EB_DEFINITION, '=', sourceFeedId);
operationGr.query();
while (operationGr.next()) {
var extendedOperationGr = new GlideRecord(operationGr.sys_class_name);
if (!extendedOperationGr.get(operationGr.getValue(this.SYS_ID))) {
errorObj = this.buildErrorObject(gs.getMessage("Could not find Operation record in extended table while copying"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
extendedOperationGr.setValue(this.SYS_RTE_EB_DEFINITION, targetFeedId);
extendedOperationGr.setValue(this.SYS_RTE_EB_ENTITY, entities[extendedOperationGr.sys_rte_eb_entity]);
if (extendedOperationGr.source_sys_rte_eb_field)
extendedOperationGr.setValue(this.SOURCE_SYS_RTE_EB_FIELD, fields[extendedOperationGr.source_sys_rte_eb_field]);
if (extendedOperationGr.target_sys_rte_eb_field)
extendedOperationGr.setValue(this.TARGET_SYS_RTE_EB_FIELD, fields[extendedOperationGr.target_sys_rte_eb_field]);
if (extendedOperationGr.source_sys_rte_eb_fields)
extendedOperationGr.setValue(this.SOURCE_SYS_RTE_EB_FIELDS, this.getUpdatedSysIdsFromMap(extendedOperationGr.getValue(this.SOURCE_SYS_RTE_EB_FIELDS), fields));
if (extendedOperationGr.target_sys_rte_eb_fields)
extendedOperationGr.setValue(this.TARGET_SYS_RTE_EB_FIELDS, this.getUpdatedSysIdsFromMap(extendedOperationGr.getValue(this.TARGET_SYS_RTE_EB_FIELDS), fields));
if (!extendedOperationGr.insert()) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to insert into extended operation table while copying"), '', {args: arguments});
throw this.getInternalServerError(errorObj);
}
}
var impEntityGr = this.findImpCmdbEntity(targetFeedId);
var metadata = this.loadAllMetadataForApplicationFeed(targetFeedId, impEntityGr);
var templateStateGr = new GlideRecord(this.CMDB_INST_TEMPLATE_STATE);
templateStateGr.addQuery(this.APPLICATION_FEED_ID, targetFeedId);
templateStateGr.query();
if (templateStateGr.next()) {
var importSetId = templateStateGr.import_set_id + '';
var dataInSingleColumn = templateStateGr.import_set_id.data_source.data_in_single_column.toString();
dataInSingleColumn = dataInSingleColumn === 'true' ? true : false;
metadata.isNestedPayload = dataInSingleColumn;
if (dataInSingleColumn) {
var returnedSchema = this.getNestedPayloadSchema(templateStateGr, false);
var rawSchemaStr = returnedSchema.rawSchemaStr;
var rawSchemaJson = returnedSchema.schemaJson;
metadata.rawSchema = rawSchemaJson;
}
}
var previewSize = this.getPreviewSize(templateStateGr);
metadata.batchSize = previewSize ? previewSize : this.DEFAULT_PREVIEW_SIZE;
if (metadata.batchSize > this.MAX_PREVIEW_SIZE) {
metadata.batchSize = this.MAX_PREVIEW_SIZE;
}
return metadata;
},
getServiceErrorObj: function(status, message, detail) {
var error = new sn_ws_err.ServiceError();
error.setStatus(status);
error.setMessage(message);
error.setDetail(detail);
return error;
},
deleteEntityByGroupId: function(groupId) {
var entitiesToDelete = [];
var deletedEntities = [];
var gr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
gr.addQuery(this.ENTITY_MAPPING_GROUP, groupId);
gr.query();
while (gr.next()) {
var relType = gr[this.TARGET_SYS_RTE_EB_ENTITY][this.RELATIONSHIP_TYPE][this.NAME] + '';
var entityId = gr.getValue(this.TARGET_SYS_RTE_EB_ENTITY);
entitiesToDelete.push(entityId);
deletedEntities.push({
'relType': relType,
'entityId': entityId
});
}
gr = new GlideRecord(this.SYS_RTE_EB_ENTITY);
gr.addQuery(this.SYS_ID, entitiesToDelete);
gr.query();
while (gr.next()) {
gr.deleteRecord();
}
return deletedEntities;
},
getNestedPayloadFields: function(schema, dotwalk, fields) {
var schemaKeys = Object.keys(schema);
var prefixErrorMsg = gs.getMessage('Unable to preview data because');
for (var i = 0; i < schemaKeys.length; i++) {
var currentField = schemaKeys[i];
if (!schema[currentField]) {
return gs.getMessage('{0} field \'{1}\' cannot be found.', [prefixErrorMsg, currentField]);
}
if (currentField == 'temp') {
return gs.getMessage('{0} field name cannot be \'temp\'.', prefixErrorMsg);
}
if (currentField == 'object') {
return gs.getMessage('{0} field name cannot be \'object\'.', prefixErrorMsg);
}
// Schema parser returns $ sign when encounter invalid field names
if (currentField == '$') {
return gs.getMessage('{0} one or more field names are invalid. Field names must start with a letter (between A-Z or a-z) or with \'_\', and must only contain letters (between A-Z or a-z), digits (0-9), or \'_\'.', prefixErrorMsg);
}
var nextDotwalk = [];
if (dotwalk) {
nextDotwalk = dotwalk.split(',');
}
if (Array.isArray(schema[currentField]) && typeof schema[currentField][0] != 'object') {
nextDotwalk.push(currentField);
fields.push(nextDotwalk.join('.'));
} else if (typeof schema[currentField] != 'string') {
var nextSchema = schema[currentField];
if (Array.isArray(nextSchema)) {
nextSchema = nextSchema[0];
currentField = currentField + '[*]';
}
nextDotwalk.push(currentField);
var message = this.getNestedPayloadFields(nextSchema, nextDotwalk.join(','), fields);
if (message) {
return message;
}
nextDotwalk.push(this.NESTED_PAYLOAD_PLACEHOLDER_FIELD);
fields.push(nextDotwalk.join('.'));
} else {
nextDotwalk.push(currentField);
fields.push(nextDotwalk.join('.'));
}
}
},
updateEntityPathRelation: function(currentEntityId, targetEntityId) {
var currentEntityPath = '';
var currentEntityName = '';
var targetEntityPath = '';
var targetEntityName = '';
var feedId = '';
var errorObj = {};
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, currentEntityId);
entityGr.query();
if (entityGr.next()) {
currentEntityPath = entityGr.getValue(this.PATH);
currentEntityName = entityGr.getValue(this.NAME);
feedId = entityGr.getValue(this.SYS_RTE_EB_DEFINITION);
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity with id {0}', currentEntityId));
throw this.getInternalServerError(errorObj);
}
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, targetEntityId);
entityGr.query();
if (entityGr.next()) {
targetEntityPath = entityGr.getValue(this.PATH);
targetEntityName = entityGr.getValue(this.NAME);
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity with id {0}', targetEntityId));
throw this.getInternalServerError(errorObj);
}
var currentEntityTempPath = '';
var targetEntityTempPath = '';
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, targetEntityId);
entityMappingGr.query();
if (entityMappingGr.next()) {
targetEntityTempPath = entityMappingGr.source_sys_rte_eb_entity.path + '';
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity mapping with target entity id {0}', targetEntityId));
throw this.getInternalServerError(errorObj);
}
entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, currentEntityId);
entityMappingGr.query();
if (entityMappingGr.next()) {
currentEntityTempPath = entityMappingGr.source_sys_rte_eb_entity.path + '';
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity mapping with target entity id {0}', currentEntityId));
throw this.getInternalServerError(errorObj);
}
var removedCurrentEntityPathPart = false;
var removedTargetEntityPathPart = false;
var currentEntityTempPathParts = currentEntityTempPath.split('.');
var targetEntityTempPathParts = targetEntityTempPath.split('.');
var currentEntityTempSelfPath = currentEntityTempPathParts[currentEntityTempPathParts.length - 1];
var targetEntityTempSelfPath = targetEntityTempPathParts[targetEntityTempPathParts.length - 1];
var currentEntityPathParts = currentEntityPath.split('.');
var currentEntitySelfPath = currentEntityPathParts[currentEntityPathParts.length - 1];
var targetEntityPathParts = targetEntityPath.split('.');
var targetEntitySelfPath = targetEntityPathParts[targetEntityPathParts.length - 1];
var oldCurrentEntityPath = currentEntityPath;
var oldTargetEntityPath = targetEntityPath;
try {
var updatePath = '';
if (currentEntityTempSelfPath.indexOf('[*]') < 0 && currentEntitySelfPath.indexOf('[*]') > -1) {
currentEntityPathParts[currentEntityPathParts.length - 1] = currentEntitySelfPath.substring(0, currentEntitySelfPath.length - 3);
updatePath = currentEntityPathParts.join('.');
this.updateEntityPath(currentEntityId, updatePath);
removedCurrentEntityPathPart = true;
currentEntitySelfPath = currentEntityPathParts[currentEntityPathParts.length - 1];
currentEntityPath = updatePath;
}
if (targetEntityTempSelfPath.indexOf('[*]') < 0 && targetEntitySelfPath.indexOf('[*]') > -1) {
targetEntityPathParts[targetEntityPathParts.length - 1] = targetEntitySelfPath.substring(0, targetEntitySelfPath.length - 3);
updatePath = targetEntityPathParts.join('.');
this.updateEntityPath(targetEntityId, updatePath);
removedTargetEntityPathPart = true;
targetEntitySelfPath = targetEntityPathParts[targetEntityPathParts.length - 1];
targetEntityPath = updatePath;
}
if (currentEntityPathParts.length == 1) {
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, currentEntityId);
entityGr.query();
if (entityGr.next()) {
var newPath = targetEntityPath + '.' + currentEntityPath;
entityGr.setValue(this.PATH, newPath);
entityGr.update();
}
this.orderSecondStageMapping(feedId);
return;
}
var currentEntityPrefixPath = [];
for (var i = 0; i < currentEntityPathParts.length - 1; i++) {
currentEntityPrefixPath.push(currentEntityPathParts[i]);
}
currentEntityPrefixPath = currentEntityPrefixPath.join('.');
if (currentEntityPrefixPath == targetEntityPath) {
this.orderSecondStageMapping(feedId);
return;
} else if (currentEntityPrefixPath.indexOf(targetEntityPath) > -1) {
this.orderSecondStageMapping(feedId);
return;
} else if (targetEntityPath.indexOf(currentEntityPrefixPath) > -1) {
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, currentEntityId);
entityGr.query();
if (entityGr.next()) {
var newPath = targetEntityPath + '.' + currentEntitySelfPath;
entityGr.setValue(this.PATH, newPath);
entityGr.update();
}
this.orderSecondStageMapping(feedId);
return;
}
var prefixEntityId = '';
var prefixEntityName = '';
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityGr.addQuery(this.PATH, currentEntityPrefixPath);
entityGr.query();
if (entityGr.next()) {
prefixEntityId = entityGr.getValue(this.SYS_ID);
prefixEntityName = entityGr.getValue(this.NAME);
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity with path {0}', currentEntityPrefixPath));
throw this.getInternalServerError(errorObj);
}
var prefixEntityTempPath = '';
entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, prefixEntityId);
entityMappingGr.query();
if (entityMappingGr.next()) {
prefixEntityTempPath = entityMappingGr.source_sys_rte_eb_entity.path + '';
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity mapping with target entity id {0}', prefixEntityId));
throw this.getInternalServerError(errorObj);
}
var childEntityId = '';
var childEntityPath = '';
var oldPath = '';
var prefixEntityTempPathParts = prefixEntityTempPath.split('.');
if (prefixEntityTempPath == targetEntityTempPath) {
errorObj = this.buildErrorObject(gs.getMessage('Class \'{0}\' is already associated with class \'{1}\'. Please duplicate or delete class \'{2}\', or delete its all downstream references to reset class.', [currentEntityName, prefixEntityName, currentEntityName]));
throw this.getInternalServerError(errorObj);
} else if (prefixEntityTempPathParts.length == targetEntityTempPathParts.length) {
errorObj = this.buildErrorObject(gs.getMessage('Cannot select this class \'{0}\' because mapped source columns are at a sibling level in nested data.', [targetEntityName]), this.NO_INCLUSIVE_REL_EXCEPTION);
throw this.getInternalServerError(errorObj);
} else if (targetEntityTempPath.indexOf(prefixEntityTempPath) > -1) {
childEntityId = targetEntityId;
childEntityPath = currentEntityPrefixPath + '.' + targetEntityPath;
} else if (prefixEntityTempPath.indexOf(targetEntityTempPath) > -1) {
childEntityId = prefixEntityId;
childEntityPath = targetEntityPath + '.' + currentEntityPrefixPath;
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot select this class \'{0}\' because mapped source columns are at a sibling level in nested data.', [targetEntityName]), this.NO_INCLUSIVE_REL_EXCEPTION);
throw this.getInternalServerError(errorObj);
}
var nextPrefixPath = currentEntityPrefixPath.substring(0, currentEntityPrefixPath.lastIndexOf('.'));
this.validatePrefixEntityTempPath(nextPrefixPath, targetEntityTempPath, targetEntityName, currentEntityName, feedId);
nextPrefixPath = targetEntityPath.substring(0, targetEntityPath.lastIndexOf('.'));
this.validatePrefixEntityTempPath(nextPrefixPath, prefixEntityTempPath, prefixEntityName, targetEntityName, feedId);
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, childEntityId);
entityGr.query();
if (entityGr.next()) {
oldPath = entityGr.getValue(this.PATH);
entityGr.setValue(this.PATH, childEntityPath);
entityGr.update();
}
this.updateChildEntityPath(childEntityId, oldPath, childEntityPath);
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, currentEntityId);
entityGr.query();
if (entityGr.next()) {
var newPath = childEntityPath + '.' + currentEntitySelfPath;
entityGr.setValue(this.PATH, newPath);
entityGr.update();
}
} catch (error) {
if (removedCurrentEntityPathPart) {
this.updateEntityPath(currentEntityId, oldCurrentEntityPath);
}
if (removedTargetEntityPathPart) {
this.updateEntityPath(targetEntityId, oldTargetEntityPath);
}
throw error;
}
},
updateEntityPath: function(entityId, path) {
var errorObj = {};
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, entityId);
entityGr.query();
if (entityGr.next()) {
entityGr.setValue(this.PATH, path);
if (!entityGr.update()) {
errorObj = this.buildErrorObject(gs.getMessage('Fail to update entity with entity id {0}', entityId));
throw this.getInternalServerError(errorObj);
}
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity with entity id {0}', entityId));
throw this.getInternalServerError(errorObj);
}
},
validatePrefixEntityTempPath: function(prefixPath, targetEntityTempPath, targetEntityName, currentEntityName, feedId) {
if (!prefixPath) {
return;
}
var prefixEntityId = '';
var prefixEntityName = '';
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityGr.addQuery(this.PATH, prefixPath);
entityGr.query();
if (entityGr.next()) {
prefixEntityId = entityGr.getValue(this.SYS_ID);
prefixEntityName = entityGr.getValue(this.NAME);
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity with path {0}', prefixPath));
throw this.getInternalServerError(errorObj);
}
var prefixEntityTempPath = '';
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, prefixEntityId);
entityMappingGr.query();
if (entityMappingGr.next()) {
prefixEntityTempPath = entityMappingGr.source_sys_rte_eb_entity.path + '';
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity mapping with target entity id {0}', prefixEntityId));
throw this.getInternalServerError(errorObj);
}
var prefixEntityTempPathParts = prefixEntityTempPath.split('.');
var targetEntityTempPathParts = targetEntityTempPath.split('.');
if (prefixEntityTempPath == targetEntityTempPath) {
errorObj = this.buildErrorObject(gs.getMessage('Class \'{0}\' is already associated with class \'{1}\'. Please duplicate or delete class \'{2}\', or delete its all downstream references to reset class.', [currentEntityName, prefixEntityName, currentEntityName]));
throw this.getInternalServerError(errorObj);
} else if (prefixEntityTempPathParts.length == targetEntityTempPathParts.length) {
errorObj = this.buildErrorObject(gs.getMessage('Cannot select this class \'{0}\' because mapped source columns are at a sibling level in nested data.', [targetEntityName]), this.NO_INCLUSIVE_REL_EXCEPTION);
throw this.getInternalServerError(errorObj);
}
var nextPrefixPath = prefixPath.substring(0, prefixPath.lastIndexOf('.'));
this.validatePrefixEntityTempPath(nextPrefixPath, targetEntityTempPath, targetEntityName, currentEntityName, feedId);
},
updateChildEntityPath: function(parentEntityId, oldPath, newPath) {
var feedId = '';
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, parentEntityId);
entityGr.query();
if (entityGr.next()) {
feedId = entityGr.getValue(this.SYS_RTE_EB_DEFINITION);
}
var targetEntityIds = {};
var impEntityId = this.findImpCmdbEntity(feedId).sys_id + '';
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityMappingGr.addQuery(this.SOURCE_SYS_RTE_EB_ENTITY, '!=', impEntityId);
entityMappingGr.query();
while (entityMappingGr.next()) {
var targetEntityId = entityMappingGr.getValue(this.TARGET_SYS_RTE_EB_ENTITY);
targetEntityIds[targetEntityId] = true;
}
targetEntityIds = Object.keys(targetEntityIds);
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, targetEntityIds);
entityGr.query();
while (entityGr.next()) {
var currentPath = entityGr.getValue(this.PATH);
var currentEntityId = entityGr.getValue(this.SYS_ID);
if (currentEntityId != parentEntityId && currentPath.indexOf(oldPath) > -1) {
var updatePath = currentPath.replace(oldPath, newPath);
if (updatePath != currentPath) {
entityGr.setValue(this.PATH, updatePath);
entityGr.update();
var updatePathParts = updatePath.split('.');
if (updatePathParts.length == 1 && updatePath.indexOf('[*]') < 0) {
var entityMappingGr2 = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr2.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, currentEntityId);
entityMappingGr2.query();
if (entityMappingGr2.next()) {
var currentEntityTempPath = entityMappingGr2[this.SOURCE_SYS_RTE_EB_ENTITY][this.PATH] + '';
var currentEntityTempPathParts = currentEntityTempPath.split('.');
var currentEntityTempSelfPath = currentEntityTempPathParts[currentEntityTempPathParts.length - 1];
if (currentEntityTempSelfPath.indexOf('[*]') < 0) {
this.updateEntityPath(currentEntityId, updatePath + '[*]');
}
}
}
}
}
}
this.orderSecondStageMapping(feedId);
},
orderSecondStageMapping: function(feedId) {
if (!feedId) {
return;
}
var errorObj = {};
var tempMappingMaxOrder = '';
var impEntityId = this.findImpCmdbEntity(feedId).sys_id + '';
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityMappingGr.addQuery(this.SOURCE_SYS_RTE_EB_ENTITY, impEntityId);
entityMappingGr.orderByDesc(this.ORDER);
entityMappingGr.setLimit(1);
entityMappingGr.query();
if (entityMappingGr.next()) {
tempMappingMaxOrder = Number(entityMappingGr.getValue(this.ORDER));
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity mapping with import entity id {0}', impEntityId));
throw this.getInternalServerError(errorObj);
}
var currentOrder = tempMappingMaxOrder + 10;
var pathToOrderMap = {};
entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityMappingGr.addQuery(this.SOURCE_SYS_RTE_EB_ENTITY, '!=', impEntityId);
entityMappingGr.query();
while (entityMappingGr.next()) {
var targetEntityPath = entityMappingGr.target_sys_rte_eb_entity.path + '';
pathToOrderMap[targetEntityPath] = true;
}
var paths = Object.keys(pathToOrderMap);
paths.sort(function(a, b) {
var lengthDiff = a.split('.').length - b.split('.').length;
if (lengthDiff != 0) {
return lengthDiff;
}
return (a > b) ? 1 : -1;;
});
for (var i = 0; i < paths.length; i++) {
var path = paths[i];
pathToOrderMap[path] = currentOrder;
currentOrder = currentOrder + 10;
}
entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityMappingGr.addQuery(this.SOURCE_SYS_RTE_EB_ENTITY, '!=', impEntityId);
entityMappingGr.query();
while (entityMappingGr.next()) {
var targetEntityPath = entityMappingGr.target_sys_rte_eb_entity.path + '';
var targetEntityOrder = Number(entityMappingGr.getValue(this.ORDER));
var updateOrder = pathToOrderMap[targetEntityPath];
if (updateOrder != targetEntityOrder) {
entityMappingGr.setValue(this.ORDER, updateOrder);
entityMappingGr.update();
}
}
},
isNestedPayload: function(feedId) {
var isNestedPayload = false;
var feedGr = new GlideRecord(this.CMDB_INST_APPLICATION_FEED);
if (feedGr.get(feedId)) {
var dataInSingleColumn = feedGr.sys_data_source.data_in_single_column.toString();
dataInSingleColumn = dataInSingleColumn === 'true' ? true : false;
isNestedPayload = dataInSingleColumn;
}
return isNestedPayload;
},
checkIsDifferentDataBranch: function(firstEntityId, secondEntityId, firstEntityTempPath, secondEntityTempPath) {
var isDifferentBranch = false;
if (firstEntityTempPath != secondEntityTempPath) {
if (firstEntityTempPath.split('.').length == secondEntityTempPath.split('.').length) {
isDifferentBranch = true;
} else if (firstEntityTempPath.indexOf(secondEntityTempPath) < 0 && secondEntityTempPath.indexOf(firstEntityTempPath) < 0) {
isDifferentBranch = true;
}
if (isDifferentBranch) {
if (secondEntityId == this.LOOKDOWN_CLASS) {
var allowedTempPath = '';
var allowedTempPathParts = firstEntityTempPath.split('.');
allowedTempPathParts[0] = this.NESTED_PAYLOAD_TOP_NODE_NAME;
allowedTempPath = allowedTempPathParts.join('.');
allowedTempPath = allowedTempPath.replace(/\[\*\]/g, '');
errorObj = this.buildErrorObject(
gs.getMessage(
'Columns mapped to lookup must be within the same data branch as the class currently being mapped, \'{0}\'. Selected column is at a sibling level in nested data.',
[allowedTempPath]
)
);
throw this.getInternalServerError(errorObj);
}
var firstEntityName = '';
var secondEntityName = '';
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, firstEntityId);
entityGr.query();
if (entityGr.next()) {
firstEntityName = entityGr.getValue(this.NAME);
}
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, secondEntityId);
entityGr.query();
if (entityGr.next()) {
secondEntityName = entityGr.getValue(this.NAME);
}
if (!firstEntityName) {
firstEntityName = firstEntityId;
}
if (!secondEntityName) {
secondEntityName = secondEntityId;
}
errorObj = this.buildErrorObject(gs.getMessage('Cannot select this class \'{0}\' because mapped source columns are at a sibling level in nested data.', [secondEntityName]), this.NO_INCLUSIVE_REL_EXCEPTION);
throw this.getInternalServerError(errorObj);
}
}
},
determineAndUpdateEntityPathRelation: function(currentEntityId, targetEntityId, currentEntityTempPath, targetEntityTempPath) {
if (currentEntityTempPath != targetEntityTempPath) {
var parentEntityId = '';
var childEntityId = '';
if (currentEntityTempPath.indexOf(targetEntityTempPath) > -1) {
childEntityId = currentEntityId;
parentEntityId = targetEntityId;
} else if (targetEntityTempPath.indexOf(currentEntityTempPath) > -1) {
childEntityId = targetEntityId;
parentEntityId = currentEntityId;
}
this.updateEntityPathRelation(childEntityId, parentEntityId);
} else {
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, currentEntityId);
entityGr.query();
if (entityGr.next()) {
var tableName = entityGr.getValue(this.TABLE);
var relatedGr = new GlideRecord('cmdb_related_entry');
relatedGr.addQuery(this.TABLE, tableName);
relatedGr.query();
if (!relatedGr.next()) {
return;
}
}
this.updateEntityPathRelation(currentEntityId, targetEntityId);
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, currentEntityId);
entityGr.query();
if (entityGr.next()) {
var currentEntityPath = entityGr.getValue(this.PATH);
var currentEntityPathParts = currentEntityPath.split('.');
if (currentEntityPathParts.length >= 2) {
var selfPath = currentEntityPathParts[currentEntityPathParts.length - 1];
selfPath = selfPath.replace('[*]', '');
currentEntityPathParts[currentEntityPathParts.length - 1] = selfPath;
var newPath = currentEntityPathParts.join('.');
entityGr.setValue(this.PATH, newPath);
entityGr.update();
}
}
}
},
isReferencedByOtherEntity: function(entityId, throwError, errorMessagePrefix) {
var errorObj = {};
var additionalMessagePrefix = '';
if (errorMessagePrefix) {
additionalMessagePrefix = errorMessagePrefix + ' ';
}
var entityName = '';
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, entityId);
entityGr.query();
if (entityGr.next()) {
entityName = entityGr.getValue(this.NAME);
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity with id {0}', entityId));
throw this.getInternalServerError(errorObj);
}
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.LOOKUP_FOR_ENTITY, entityId);
entityGr.query();
if (entityGr.next()) {
if (throwError) {
var lookdownName = entityGr.getValue(this.NAME);
errorObj = this.buildErrorObject(gs.getMessage('{0}Class \'{2}\' class is a lookup class for the \'{1}\' class .', [additionalMessagePrefix, entityName, lookdownName]));
throw this.getInternalServerError(errorObj);
}
return true;
}
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.RELATED_FOR_ENTITY, entityId);
entityGr.query();
if (entityGr.next()) {
if (throwError) {
var associateName = entityGr.getValue(this.NAME);
errorObj = this.buildErrorObject(gs.getMessage('{0}Class \'{1}\' is associated with class \'{2}\'.', [additionalMessagePrefix, entityName, associateName]));
throw this.getInternalServerError(errorObj);
}
return true;
}
var fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.REFERENCED_SYS_RTE_EB_ENTITY, entityId);
fieldMappingGr.query();
if (fieldMappingGr.next()) {
var table = fieldMappingGr.sys_rte_eb_entity_mapping.target_sys_rte_eb_entity.table + '';
if (table == this.CMDB_REL_CI) {
if (throwError) {
var relClassName = '';
var relEntityMappingId = fieldMappingGr.sys_rte_eb_entity_mapping;
var fieldMappingGr2 = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr2.addQuery(this.SYS_RTE_EB_ENTITY_MAPPING, relEntityMappingId);
fieldMappingGr2.query();
while (fieldMappingGr2.next()) {
var refId = fieldMappingGr2.getValue(this.REFERENCED_SYS_RTE_EB_ENTITY);
if (refId != entityId) {
relClassName = fieldMappingGr2[this.REFERENCED_SYS_RTE_EB_ENTITY].name + '';
break;
}
}
errorObj = this.buildErrorObject(gs.getMessage('Cannot add class \'{1}\' as Reference Source to the \'{0}\' class because \'{0}\' class has a relationship with the \'{1}\' class.', [entityName, relClassName]));
throw this.getInternalServerError(errorObj);
}
} else {
if (throwError) {
var targetEntityName = fieldMappingGr.sys_rte_eb_entity_mapping.target_sys_rte_eb_entity.name + '';
errorObj = this.buildErrorObject(gs.getMessage('{0}Class \'{1}\' is referenced by class \'{2}\'.', [additionalMessagePrefix, entityName, targetEntityName]));
throw this.getInternalServerError(errorObj);
}
}
return true;
}
return false;
},
hasReferenceEntity: function(entityId, throwError, excludeFieldMappingId, excludeAssociatedEntityId) {
var entityName = '';
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, entityId);
entityGr.query();
if (entityGr.next()) {
entityName = entityGr.getValue(this.NAME);
var lookupEntityName = entityGr[this.LOOKUP_FOR_ENTITY].name + '';
if (lookupEntityName) {
if (throwError) {
errorObj = this.buildErrorObject(gs.getMessage('Class \'{0}\' has lookup class \'{1}\'.', [entityName, lookupEntityName]));
throw this.getInternalServerError(errorObj);
}
return true;
}
var associateEntityName = entityGr[this.RELATED_FOR_ENTITY].name + '';
var associateEntityId = entityGr[this.RELATED_FOR_ENTITY] + '';
if (associateEntityName && associateEntityId && associateEntityId != excludeAssociatedEntityId) {
if (throwError) {
errorObj = this.buildErrorObject(gs.getMessage('Class \'{0}\' is associated with class \'{1}\'.', [entityName, associateEntityName]));
throw this.getInternalServerError(errorObj);
}
return true;
}
}
var entityMappingId = '';
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, entityId);
entityMappingGr.query();
if (entityMappingGr.next()) {
entityMappingId = entityMappingGr.getValue(this.SYS_ID);
}
fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.SYS_RTE_EB_ENTITY_MAPPING, entityMappingId);
fieldMappingGr.addNotNullQuery(this.REFERENCED_SYS_RTE_EB_ENTITY);
fieldMappingGr.query();
while (fieldMappingGr.next()) {
var fieldMappingId = fieldMappingGr.getValue(this.SYS_ID);
if (fieldMappingId == excludeFieldMappingId) {
continue;
}
var referenceEntityName = fieldMappingGr[this.REFERENCED_SYS_RTE_EB_ENTITY].name + '';
if (throwError) {
errorObj = this.buildErrorObject(gs.getMessage('Class \'{0}\' references class \'{1}\'.', [entityName, referenceEntityName]));
throw this.getInternalServerError(errorObj);
}
return true;
}
return false;
},
resetEntityPath: function(entityId) {
var errorObj = {};
var isTempCollection = false;
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, entityId);
entityMappingGr.query();
if (entityMappingGr.next()) {
var tempPath = entityMappingGr.source_sys_rte_eb_entity.path + '';
var tempPathParts = tempPath.split('.');
var tempSelfPath = tempPathParts[tempPathParts.length - 1];
if (tempSelfPath.indexOf('[*]') >= 0) {
isTempCollection = true;
}
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity mapping with entity id {0}', entityId));
throw this.getInternalServerError(errorObj);
}
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, entityId);
entityGr.query();
if (entityGr.next()) {
var entityPath = entityGr.getValue(this.PATH);
var entityPathParts = entityPath.split('.');
var entitySelfPath = entityPathParts[entityPathParts.length - 1];
entitySelfPath = entitySelfPath.replace('[*]', '');
if (isTempCollection || (!isTempCollection && tempPathParts.length > 1)) {
entitySelfPath = entitySelfPath + '[*]';
}
entityGr.setValue(this.PATH, entitySelfPath);
entityGr.update();
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity id {0}', entityId));
throw this.getInternalServerError(errorObj);
}
},
getPreviewSize: function(templateStateGr) {
var maxRows = this.DEFAULT_PREVIEW_SIZE;
var previewSize;
if(templateStateGr){
var appPreviewSize = Number(templateStateGr.getValue(this.PREVIEW_SIZE_OVERRIDE));
if(appPreviewSize)
maxRows = appPreviewSize;
else{
previewSize = Number(gs.getProperty(this.PREVIEW_SIZE_PROPERTY_NAME));
if (previewSize) {
maxRows = previewSize;
}
}
}else{
previewSize = Number(gs.getProperty(this.PREVIEW_SIZE_PROPERTY_NAME));
if (previewSize) {
maxRows = previewSize;
}
}
var hasPreviewSizeWarning = false;
if (maxRows > this.MAX_PREVIEW_SIZE) {
maxRows = this.MAX_PREVIEW_SIZE;
}
return maxRows;
},
hasPreviewSizeWarning: function(importSetId, previewSize) {
if (previewSize >= this.MAX_PREVIEW_SIZE) {
var importSetRowCount = this.getImportSetRowCount(importSetId);
if (importSetRowCount >= this.MAX_PREVIEW_SIZE) {
return true;
}
}
return false;
},
getImportSetRowCount: function(importSetId) {
var ga = new GlideAggregate('sys_import_set_row');
ga.addQuery('sys_import_set', importSetId);
ga.addAggregate('COUNT');
ga.query();
if (ga.next()) {
return Number(ga.getAggregate('COUNT'));
}
return null;
},
buildUACustomPayload: function(action, feedId, stepNumber, recordValue, recordId) {
var feedName = '';
if (feedId) {
var feedGr = new GlideRecord(this.CMDB_INST_APPLICATION_FEED);
feedGr.addQuery(this.SYS_ID, feedId);
feedGr.query();
if (feedGr.next()) {
feedName = feedGr.getValue(this.NAME);
} else {
errorObj = this.buildErrorObject(gs.getMessage('UA Error - Cannot find feed with ID \'{0}\'', [feedId]));
throw this.getInternalServerError(errorObj);
}
}
var uaPayload = new GCFSampleMap();
uaPayload.put(this.ACTION, action);
uaPayload.put(this.FEED_NAME, feedName);
uaPayload.put(this.STEP_NUMBER, stepNumber);
uaPayload.put(this.RECORD_VALUE, recordValue);
uaPayload.put(this.RECORD_ID, recordId);
return uaPayload;
},
setIgnoreForGivenEntityMapping: function(entityMappingSysId, activate) {
var errorObj = {};
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_ID, entityMappingSysId);
entityMappingGr.query();
if (entityMappingGr.next()) {
entityMappingGr.setValue(this.IGNORE, !activate);
if (!entityMappingGr.update()) {
errorObj = this.buildErrorObject(gs.getMessage("Failed to update entity mapping record '{0}'", [entityMappingSysId]));
throw this.getInternalServerError(errorObj);
}
}
},
findRelEntityMappingsAndSetIgnore: function(targetEntitySysId, toActivate) {
var fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.REFERENCED_SYS_RTE_EB_ENTITY, targetEntitySysId);
fieldMappingGr.query();
while (fieldMappingGr.next()) {
var table = fieldMappingGr.sys_rte_eb_entity_mapping.target_sys_rte_eb_entity.table + '';
if (table == this.CMDB_REL_CI) {
var relEntityMappingId = fieldMappingGr.sys_rte_eb_entity_mapping;
var fieldMappingGr1 = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr1.addQuery(this.SYS_RTE_EB_ENTITY_MAPPING, relEntityMappingId);
fieldMappingGr1.addQuery(this.REFERENCED_SYS_RTE_EB_ENTITY, '!=', targetEntitySysId);
fieldMappingGr1.query();
if (fieldMappingGr1.next()) {
var otherRefEntityId = fieldMappingGr1.referenced_sys_rte_eb_entity;
var otherRefEntityMapping = this.getEntityMappingByEntityId(otherRefEntityId);
var otherEntityIgnored = otherRefEntityMapping.ignore;
if (otherEntityIgnored && toActivate)
continue;
var relEntityMappingSysId = fieldMappingGr.sys_rte_eb_entity_mapping;
this.setIgnoreForGivenEntityMapping(relEntityMappingSysId, toActivate);
}
}
}
},
hasPreviewSizeWarning: function(importSetId, previewSize) {
if (previewSize >= this.MAX_PREVIEW_SIZE) {
var importSetRowCount = this.getImportSetRowCount(importSetId);
if (importSetRowCount >= this.MAX_PREVIEW_SIZE) {
return true;
}
}
return false;
},
getImportSetRowCount: function(importSetId) {
var ga = new GlideAggregate('sys_import_set_row');
ga.addQuery('sys_import_set', importSetId);
ga.addAggregate('COUNT');
ga.query();
if (ga.next()) {
return Number(ga.getAggregate('COUNT'));
}
return null;
},
getEntitiesAffectedByToggle: function(feedId, toggleEntities, dependentRelMap, tableDependencyMap, ignoreCurrentActiveState) {
var affectedEntities = {};
var parentToChildrenMap = {};
var childToParentsMap = {};
var relEntityIdToTypeMap = {};
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityGr.addQuery(this.TABLE, this.CMDB_REL_CI);
entityGr.query();
while (entityGr.next()) {
relEntityIdToTypeMap[entityGr.getValue(this.SYS_ID)] = entityGr.getValue(this.RELATIONSHIP_TYPE);
}
var relEntityIds = Object.keys(relEntityIdToTypeMap);
var relEntityMappingIdToType = [];
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, relEntityIds);
entityMappingGr.query();
while (entityMappingGr.next()) {
var relEntityId = entityMappingGr.getValue(this.TARGET_SYS_RTE_EB_ENTITY);
var relEntityType = relEntityIdToTypeMap[relEntityId];
relEntityMappingIdToType[entityMappingGr.getValue(this.SYS_ID)] = relEntityType;
}
var relEntityMappingIds = Object.keys(relEntityMappingIdToType);
var fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.SYS_RTE_EB_ENTITY_MAPPING, relEntityMappingIds);
fieldMappingGr.orderBy(this.SYS_RTE_EB_ENTITY_MAPPING);
fieldMappingGr.query();
while (fieldMappingGr.next()) {
var currentRel = {};
var role = fieldMappingGr.target_sys_rte_eb_field.field + '';
var roleEntityId = fieldMappingGr.getValue(this.REFERENCED_SYS_RTE_EB_ENTITY);
var roleEntityTable = fieldMappingGr[this.REFERENCED_SYS_RTE_EB_ENTITY].table + '';
currentRel[role] = {
'id': roleEntityId,
'table': roleEntityTable
};
// Relationship field mappings always come with a pair. One for parent reference and one for child reference.
if (fieldMappingGr.next()) {
role = fieldMappingGr.target_sys_rte_eb_field.field + '';
roleEntityId = fieldMappingGr.getValue(this.REFERENCED_SYS_RTE_EB_ENTITY);
roleEntityTable = fieldMappingGr[this.REFERENCED_SYS_RTE_EB_ENTITY].table + '';
currentRel[role] = {
'id': roleEntityId,
'table': roleEntityTable
};
} else {
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("Cannot find relationship reference")));
}
var relEntityMappingId = fieldMappingGr.getValue(this.SYS_RTE_EB_ENTITY_MAPPING);
var relTypeId = relEntityMappingIdToType[relEntityMappingId];
var parentEntityId = currentRel[this.PARENT].id;
var parentEntityTable = currentRel[this.PARENT].table;
var childEntityId = currentRel[this.CHILD].id;
var childEntityTable = currentRel[this.CHILD].table;
var relDependencyHash = parentEntityTable + childEntityTable + relTypeId;
var isDependentRel = dependentRelMap[relDependencyHash];
if (!isDependentRel) {
continue;
}
var tableHierarchyMap = {};
var actualParentEntityId = parentEntityId;
var actualChildEntityId = childEntityId;
if (!tableDependencyMap[childEntityTable] || tableDependencyMap[childEntityTable].length == 0) {
actualParentEntityId = childEntityId;
actualChildEntityId = parentEntityId;
} else {
var dependencies = tableDependencyMap[childEntityTable];
var foundDependentParent = false;
for (var i = 0; i < dependencies.length; i++) {
var dependentTable = dependencies[i];
var dependentTableHierarchy = tableHierarchyMap[dependentTable];
if (!dependentTableHierarchy) {
dependentTableHierarchy = new GlideTableHierarchy(dependentTable).getHierarchy();
tableHierarchyMap[dependentTable] = dependentTableHierarchy;
}
if (dependentTableHierarchy.indexOf(parentEntityTable) >= 0) {
foundDependentParent = true;
break;
}
}
if (!foundDependentParent) {
actualParentEntityId = childEntityId;
actualChildEntityId = parentEntityId;
}
}
if (!parentToChildrenMap[actualParentEntityId]) {
parentToChildrenMap[actualParentEntityId] = {};
}
if (!childToParentsMap[actualChildEntityId]) {
childToParentsMap[actualChildEntityId] = {};
}
parentToChildrenMap[actualParentEntityId][actualChildEntityId] = true;
childToParentsMap[actualChildEntityId][actualParentEntityId] = true;
}
var deactivateEntityState = {};
for (var i = 0; i < toggleEntities.length; i++) {
deactivateEntityState[toggleEntities[i].id] = toggleEntities[i].toActivate ? false : true;
}
toggleEntities.sort(function(entityA, entityB) {
if (entityA.toActivate && !entityB.toActivate) {
return -1;
} else if (!entityA.toActivate && entityB.toActivate) {
return 1;
} else {
return 0;
}
});
var entityIgnoreMap = {};
for (var i = 0; i < toggleEntities.length; i++) {
var toCheckEntityId = toggleEntities[i].id;
var toActivate = toggleEntities[i].toActivate;
this.checkEntityAffectedByToggle(toCheckEntityId, deactivateEntityState, affectedEntities, parentToChildrenMap, childToParentsMap, toActivate, entityIgnoreMap, ignoreCurrentActiveState);
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.RELATED_FOR_ENTITY, toCheckEntityId);
entityGr.query();
while (entityGr.next()) {
var associatedEntityId = entityGr.getValue(this.SYS_ID);
if (!ignoreCurrentActiveState && toActivate !== this.isClassIgnored(associatedEntityId)) {
continue;
}
var associatedEntityName = entityGr.getValue(this.NAME);
var associatedEntityMappingGr = this.getEntityMappingByEntityId(associatedEntityId);
var associatedEntityMappingId = associatedEntityMappingGr.getValue(this.SYS_ID);
affectedEntities[associatedEntityId] = {
'entityName': associatedEntityName,
'entityMappingId': associatedEntityMappingId,
'isLookdownEntity': false,
'toActivate': toActivate
};
}
}
return affectedEntities;
},
checkEntityAffectedByToggle: function(toggleEntityId, deactivateEntityState, affectedEntities, parentToChildrenMap, childToParentsMap, toActivate, entityIgnoreMap, ignoreCurrentActiveState) {
if (affectedEntities[toggleEntityId]) {
return;
}
var dependentChildrenEntityIds = [];
if (parentToChildrenMap[toggleEntityId]) {
dependentChildrenEntityIds = Object.keys(parentToChildrenMap[toggleEntityId]);
}
for (var i = 0; i < dependentChildrenEntityIds.length; i++) {
var dependentChildEntityId = dependentChildrenEntityIds[i];
if (!ignoreCurrentActiveState && toActivate !== this.isClassIgnored(dependentChildEntityId)) {
deactivateEntityState[dependentChildEntityId] = toActivate ? false : true;
this.checkEntityAffectedByToggle(dependentChildEntityId, deactivateEntityState, affectedEntities, parentToChildrenMap, childToParentsMap, toActivate, entityIgnoreMap, ignoreCurrentActiveState);
continue;
}
var parentEntityIds = [];
if (childToParentsMap[dependentChildEntityId]) {
parentEntityIds = Object.keys(childToParentsMap[dependentChildEntityId]);
}
var hasBackupDependentRel = false;
if (!toActivate) {
for (var j = 0; j < parentEntityIds.length; j++) {
var parentEntityId = parentEntityIds[j];
var isClassIgnored = entityIgnoreMap[parentEntityId];
if (typeof isClassIgnored != 'boolean') {
isClassIgnored = this.isClassIgnored(parentEntityId);
entityIgnoreMap[parentEntityId] = isClassIgnored;
}
if (deactivateEntityState[parentEntityId] === false || (!deactivateEntityState[parentEntityId] && !isClassIgnored)) {
hasBackupDependentRel = true;
break;
}
}
}
var isLookdownEntity = false;
var hasValidLookupEntity = false;
var dependentChildEntityName = '';
entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_ID, dependentChildEntityId);
entityGr.query();
if (entityGr.next()) {
dependentChildEntityName = entityGr.getValue(this.NAME);
var lookupEntityId = entityGr.getValue(this.LOOKUP_FOR_ENTITY);
if (lookupEntityId) {
isLookdownEntity = true;
if (!toActivate && !deactivateEntityState[lookupEntityId]) {
var isClassIgnored = entityIgnoreMap[lookupEntityId];
if (typeof isClassIgnored != 'boolean') {
isClassIgnored = this.isClassIgnored(lookupEntityId);
entityIgnoreMap[lookupEntityId] = isClassIgnored;
}
if (deactivateEntityState[lookupEntityId] === false || (!deactivateEntityState[lookupEntityId] && !isClassIgnored)) {
hasValidLookupEntity = true;
}
}
}
}
if (toActivate || (!hasBackupDependentRel && !hasValidLookupEntity)) {
deactivateEntityState[dependentChildEntityId] = toActivate ? false : true;
this.checkEntityAffectedByToggle(dependentChildEntityId, deactivateEntityState, affectedEntities, parentToChildrenMap, childToParentsMap, toActivate, entityIgnoreMap, ignoreCurrentActiveState);
var dependentChildEntityMappingGr = this.getEntityMappingByEntityId(dependentChildEntityId);
var dependentChildEntityMappingId = dependentChildEntityMappingGr.getValue(this.SYS_ID);
affectedEntities[dependentChildEntityId] = {
'entityName': dependentChildEntityName,
'entityMappingId': dependentChildEntityMappingId,
'isLookdownEntity': isLookdownEntity,
'toActivate': toActivate
};
}
}
},
isClassIgnored: function(entityId) {
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, entityId);
entityMappingGr.query();
if (entityMappingGr.next()) {
var ignore = entityMappingGr.getDisplayValue(this.IGNORE);
return this.parseBooleanString(ignore);
} else {
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("Cannot find entity mapping with entity ID '{0}'", entityId)));
}
},
getEntityMappingByEntityId: function(entityId) {
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, entityId);
entityMappingGr.query();
if (entityMappingGr.next()) {
return entityMappingGr;
} else {
throw this.getInternalServerError(this.buildErrorObject(gs.getMessage("Cannot find entity mapping with entity id '{0}'", entityId)));
}
},
validateIntStudioPluginIsActive: function() {
var gpm = new GlidePluginManager();
var isActive = gpm.isActive(this.INTEGRATION_STUDIO_API_PLUGIN);
if (!isActive) {
var errMessage = gs.getMessage('Integration Studio API plugin is not activated. Activate the plugin or contact your CMDB Admin for help.');
var errDetail = gs.getMessage('Integration Studio API plugin is required for IntegrationHub ETL.');
throw this.getInternalServerError(this.buildErrorObject(errMessage, errDetail));
}
return true;
},
validateIfFileAttachedToDatasource: function(dataSourceId) {
var gr = new GlideRecord(this.SYS_DATA_SOURCE);
gr.addQuery('sys_id', dataSourceId);
gr.query();
if (gr.next()) {
var dsType = gr.getValue('type');
var fileRetrievalMethod = gr.getValue('file_retrieval_method');
if (
dsType && dsType.toLowerCase() === 'file'
&& fileRetrievalMethod && fileRetrievalMethod.toLowerCase() === 'attachment'
) {
var attachmentGA = new GlideAggregate('sys_attachment');
attachmentGA.addQuery('table_sys_id', dataSourceId);
attachmentGA.addAggregate('COUNT');
attachmentGA.query();
if (attachmentGA.next()) {
var count = Number(attachmentGA.getAggregate('COUNT'));
if (count === 0) {
var errMessage = gs.getMessage('Data Source does not have any file attached. Verify Data Source configuration is correct or contact your CMDB Admin for help.');
var errDetail = gs.getMessage('Data Source of type File and file retrieval method of attachment must have at least one file attached to it.');
throw this.getInternalServerError(this.buildErrorObject(errMessage, errDetail));
}
}
}
} else {
errMessage = gs.getMessage('Invalid Data Source. Verify Data Source configuration is correct or contact your CMDB Admin for help.');
errDetail = gs.getMessage('Invalid Data Source. Verify Data Source configuration is correct or contact your CMDB Admin for help.');
throw this.getInternalServerError(this.buildErrorObject(errMessage, errDetail));
}
return true;
},
handleSchemaLoadError: function(err) {
var errorObj;
if (err.toString().indexOf('IllegalArgumentException') > -1) {
var errorMessage = err.getMessage();
errorObj = this.buildErrorObject(gs.getMessage('{0}. Verify Data Source configuration is correct or contact your CMDB Admin for help.', errorMessage), err.toString());
throw this.getInternalServerError(errorObj);
} else {
errorObj = this.buildErrorObject(gs.getMessage('Unable to retrieve schema from import set possibly due to invalid field names. Field names must start with a letter (between A-Z or a-z) or with \'_\', and must only contain letters (between A-Z or a-z), digits (0-9), or \'_\'. Verify Data Source configuration is correct or contact your CMDB Admin for help.'), err.toString());
throw this.getInternalServerError(errorObj);
}
},
getEntityMappingWithEmptySourceOrTargetEntity: function(feedId, result, doDelete) {
// Invalid records
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityMappingGr.addEncodedQuery('source_sys_rte_eb_entityISEMPTY^ORtarget_sys_rte_eb_entityISEMPTY');
entityMappingGr.query();
while (entityMappingGr.next()) {
var id = entityMappingGr.getValue(this.SYS_ID);
var mappingName = entityMappingGr.getValue(this.NAME);
if (!doDelete) {
result.invalidRecords.push({
message: gs.getMessage('Entity mapping \'{0}\' can be deleted because the source or the target entity is missing.', mappingName),
recordTable: this.SYS_RTE_EB_ENTITY_MAPPING,
recordId: id
});
} else if (entityMappingGr.deleteRecord()) {
result.deletedRecords.push({
message: gs.getMessage('Entity mapping \'{0}\' has been internally deleted because the source or the target entity is missing.', mappingName)
});
}
}
},
getFieldMappingWithEmptyTargetField: function(feedId, result, doDelete) {
var fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
fieldMappingGr.addEncodedQuery('target_sys_rte_eb_fieldISEMPTY');
fieldMappingGr.query();
while (fieldMappingGr.next()) {
var id = fieldMappingGr.getValue(this.SYS_ID);
var sourceFieldName = fieldMappingGr.source_sys_rte_eb_field.name + '';
var entityMappingName = fieldMappingGr.sys_rte_eb_entity_mapping.name + '';
if (!doDelete) {
result.invalidRecords.push({
message: gs.getMessage('Field mapping with the source field \'{0}\' in the class mapping of \'{1}\' can be deleted because the target field is missing.', [sourceFieldName, entityMappingName]),
recordTable: this.SYS_RTE_EB_FIELD_MAPPING,
recordId: id
});
} else if (fieldMappingGr.deleteRecord()) {
result.deletedRecords.push({
message: gs.getMessage('Field mapping with the source field \'{0}\' in the class mapping of \'{1}\' has been deleted because the target field is missing.', [sourceFieldName, entityMappingName])
});
}
}
},
getFieldMappingWithEmptyEntityMapping: function(feedId, result, doDelete) {
var fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
fieldMappingGr.addEncodedQuery('sys_rte_eb_entity_mappingISEMPTY');
fieldMappingGr.query();
while (fieldMappingGr.next()) {
id = fieldMappingGr.getValue(this.SYS_ID);
sourceFieldName = fieldMappingGr.source_sys_rte_eb_field.name + '';
var targetFieldName = fieldMappingGr.target_sys_rte_eb_field.name + '';
if (!doDelete) {
result.invalidRecords.push({
message: gs.getMessage('Field mapping with the source field \'{0}\' to target field \'{1}\' can be deleted because the class mapping record is missing.', [sourceFieldName, targetFieldName]),
recordTable: this.SYS_RTE_EB_FIELD_MAPPING,
recordId: id
});
} else if (fieldMappingGr.deleteRecord()) {
result.deletedRecords.push({
message: gs.getMessage('Field mapping with the source field \'{0}\' to target field \'{1}\' has been deleted because the class mapping record is missing.', [sourceFieldName, targetFieldName])
});
}
}
},
getLookupEntityAndRelationWithoutIRERule: function(feedId, rules, result, doDelete) {
var lookupTableMap = {};
var cmdbTables = Object.keys(rules);
for (var i = 0; i < cmdbTables.length; i++) {
var cmdbTable = cmdbTables[i];
if (!lookupTableMap[cmdbTable]) {
lookupTableMap[cmdbTable] = {};
}
var classRules = rules[cmdbTable].rules;
for (var j = 0; j < classRules.length; j++) {
var rule = classRules[j];
if (rule.lookupTable) {
lookupTableMap[cmdbTable][rule.lookupTable] = true;
}
}
}
var lookupEntityToDelete = {};
var relEntity = [];
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityGr.query();
while (entityGr.next()) {
var entityId = entityGr.getValue(this.SYS_ID);
var entityName = entityGr.getValue(this.NAME);
var table = entityGr.getValue(this.TABLE);
if (table == this.CMDB_REL_CI) {
relEntity.push(entityId);
continue;
}
var lookupTable = entityGr.lookup_for_entity.table + '';
if (lookupTable && lookupTableMap[lookupTable] && !lookupTableMap[lookupTable][table]) {
if (!doDelete) {
lookupEntityToDelete[entityId] = gs.getMessage('Class \'{0}\' can be deleted because it is a lookup item and there is no corresponding IRE lookup rule.', entityName);
} else {
lookupEntityToDelete[entityId] = gs.getMessage('Class \'{0}\' has been deleted because it is a lookup item and there is no corresponding IRE lookup rule.', entityName);
}
} else if (lookupTable) { // Lookup entities without field mappings
var fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
fieldMappingGr.addQuery('sys_rte_eb_entity_mapping.target_sys_rte_eb_entity', entityId);
fieldMappingGr.query();
if (!fieldMappingGr.next() && !(entityId in lookupEntityToDelete)) {
if (!doDelete) {
lookupEntityToDelete[entityId] = gs.getMessage('Class \'{0}\' can be deleted because it is a lookup item which has no corresponding field mappings.', entityName);
} else {
lookupEntityToDelete[entityId] = gs.getMessage('Class \'{0}\' has been deleted because it is a lookup item which has no corresponding field mappings.', entityName);
}
}
}
}
var relMappingToEntity = {};
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, relEntity);
entityMappingGr.query();
while (entityMappingGr.next()) {
var mappingId = entityMappingGr.getValue(this.SYS_ID);
relMappingToEntity[mappingId] = entityMappingGr.getValue(this.TARGET_SYS_RTE_EB_ENTITY);
}
var relEntityToDelete = {};
fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
fieldMappingGr.addQuery(this.SYS_RTE_EB_ENTITY_MAPPING, Object.keys(relMappingToEntity));
fieldMappingGr.query();
while (fieldMappingGr.next()) {
var referenceEntityId = fieldMappingGr.getValue(this.REFERENCED_SYS_RTE_EB_ENTITY);
var referenceEntityName = fieldMappingGr.referenced_sys_rte_eb_entity.name + '';
if (lookupEntityToDelete[referenceEntityId]) {
var mappingId = fieldMappingGr.getValue(this.SYS_RTE_EB_ENTITY_MAPPING);
var relEntityId = relMappingToEntity[mappingId];
var innerGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
innerGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
innerGr.addQuery(this.SYS_RTE_EB_ENTITY_MAPPING, mappingId);
innerGr.query();
var referenceNames = {};
while (innerGr.next()) {
var fieldName = innerGr.target_sys_rte_eb_field.field + '';
referenceNames[fieldName] = innerGr.referenced_sys_rte_eb_entity.name + '';
}
if (!doDelete) {
relEntityToDelete[relEntityId] = gs.getMessage('Relationship mapping between the \'{0}\' and the \'{1}\' classes can be deleted because \'{2}\' is a lookup item and there is no corresponding IRE lookup rule.', [referenceNames['parent'], referenceNames['child'], referenceEntityName]);
} else {
relEntityToDelete[relEntityId] = gs.getMessage('Relationship mapping between the \'{0}\' and the \'{1}\' classes has been deleted because \'{2}\' is a lookup item and there is no corresponding IRE lookup rule.', [referenceNames['parent'], referenceNames['child'], referenceEntityName]);
}
}
}
var entityToDelete = Object.keys(relEntityToDelete);
for (var i = 0; i < entityToDelete.length; i++) {
var id = entityToDelete[i];
var message = relEntityToDelete[id];
if (!doDelete) {
result.invalidRecords.push({
message: message,
recordTable: this.CMDB_INST_ENTITY,
recordId: id
})
} else if (this.deleteEntity(id)) {
result.deletedRecords.push({
message: message
});
}
}
entityToDelete = Object.keys(lookupEntityToDelete);
for (var i = 0; i < entityToDelete.length; i++) {
var id = entityToDelete[i];
var message = lookupEntityToDelete[id];
if (!doDelete) {
result.invalidRecords.push({
message: message,
recordTable: this.CMDB_INST_ENTITY,
recordId: id
});
} else if (this.deleteEntity(id)) {
result.deletedRecords.push({
message: message
});
}
}
},
hasMetadata: function(cmdbInstApplicationFeedSysId) {
var impEntityGr = this.findImpCmdbEntity(cmdbInstApplicationFeedSysId);
if (impEntityGr.getUniqueValue) {
var tempEntities = this.findTempCmdbEntity(cmdbInstApplicationFeedSysId, impEntityGr.getUniqueValue());
if (tempEntities && Object.keys(tempEntities).indexOf('temp') >= 0)
return true;
return false;
}
},
getNestedPayloadSchema: function(templateStateGr, forceLoad, forceCompleteSchema) {
var rowLimit = this.getPreviewSize(templateStateGr);
var importSetSysId = templateStateGr.import_set_id + '';
var loadCompleteSchema = this.parseBooleanString(templateStateGr.getDisplayValue(this.LOAD_COMPLETE_SCHEMA));
if (loadCompleteSchema || forceCompleteSchema) {
rowLimit = '';
}
try {
var rawSchemaStr = forceLoad ? '' : templateStateGr.getValue(this.NESTED_PAYLOAD_SCHEMA);
if (!rawSchemaStr) {
rawSchemaStr = sn_integration_studio.IntegrationStudioScriptableApi.schemaFromSampleData(importSetSysId, '', rowLimit);
gs.debug('IH-ETL schema reloaded for ' + importSetSysId);
var isCompleteSchema = loadCompleteSchema || forceCompleteSchema;
templateStateGr.setValue(this.IS_COMPLETE_SCHEMA, isCompleteSchema);
templateStateGr.setValue(this.NESTED_PAYLOAD_SCHEMA, rawSchemaStr);
templateStateGr.update();
}
// If there is no schema to validate against, just log and return
if (!rawSchemaStr) {
throw 'Empty schema string returned from ' + importSetSysId;
}
var schema = JSON.parse(rawSchemaStr);
return {
rawSchemaStr: rawSchemaStr,
schemaJson: schema
};
} catch (e) {
templateStateGr.setValue(this.IS_COMPLETE_SCHEMA, false);
templateStateGr.setValue(this.NESTED_PAYLOAD_SCHEMA, '');
templateStateGr.update();
this.handleSchemaLoadError(e);
}
},
getAllMappingRecordsOfMissingImportTableColumns: function(feedId, result, doDelete) {
var isNestedPayload = this.isNestedPayload(feedId);
var fieldsToDelete = [];
var feedGr = new GlideRecord(this.CMDB_INST_APPLICATION_FEED);
feedGr.addQuery(this.SYS_ID, feedId);
feedGr.query();
if (feedGr.next()) {
var importTable = feedGr.sys_data_source.import_set_table_name + '';
var currentImpColumns = [];
if (!isNestedPayload) {
currentImpColumns = this.getTableColumns(importTable);
} else {
var templateStateGr = new GlideRecord(this.CMDB_INST_TEMPLATE_STATE);
templateStateGr.addQuery(this.APPLICATION_FEED_ID, feedId);
templateStateGr.query();
if (templateStateGr.next()) {
var importSetSysId = templateStateGr.import_set_id + '';
var returnedSchema = this.getNestedPayloadSchema(templateStateGr, false);
var rawSchemaStr = returnedSchema.rawSchemaStr;
var schema = returnedSchema.schemaJson;
var message = this.getNestedPayloadFields(schema, '', currentImpColumns);
if (message) {
errorObj = this.buildErrorObject(message, '', '');
throw this.getInternalServerError(errorObj);
}
}
}
if (currentImpColumns.length > 0) {
var currentImpColumnMap = {};
for (var i = 0; i < currentImpColumns.length; i++) {
currentImpColumnMap[currentImpColumns[i]] = true;
}
var importEntityId = '';
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityGr.addQuery(this.NAME, this.IMPORT);
entityGr.query();
if (entityGr.next()) {
importEntityId = entityGr.getValue(this.SYS_ID);
} else {
result.error = gs.getMessage('Import entity record missing for this ETL transform map');
return result;
}
var entityIdToGraphMap = {};
var fieldGr = new GlideRecord(this.SYS_RTE_EB_FIELD);
fieldGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
fieldGr.addQuery(this.SYS_RTE_EB_ENTITY, importEntityId);
fieldGr.query();
while (fieldGr.next()) {
var impFieldName = fieldGr.getValue(this.FIELD);
if (!currentImpColumnMap[impFieldName]) {
var impFieldId = fieldGr.getValue(this.SYS_ID);
var tempFieldId = '';
fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
fieldMappingGr.addQuery(this.SOURCE_SYS_RTE_EB_FIELD, impFieldId);
fieldMappingGr.query();
if (fieldMappingGr.next()) {
tempFieldId = fieldMappingGr.getValue(this.TARGET_SYS_RTE_EB_FIELD);
if (!tempFieldId) {
result.error = gs.getMessage('Import to temp field mapping is missing for import field \'{0}\'', impFieldName);
return result;
}
var tempEntityId = fieldMappingGr.target_sys_rte_eb_field.sys_rte_eb_entity + '';
var graph = entityIdToGraphMap[tempEntityId];
if (!graph) {
graph = this.getOperationGraph(tempEntityId);
entityIdToGraphMap[tempEntityId] = graph;
}
this.getOperationRecursive(tempFieldId, graph, feedId, result, doDelete);
}
if (!doDelete) {
result.invalidRecords.push({
message: gs.getMessage('Import field \'{0}\' can be deleted because the corresponding import table column is missing.', [impFieldName]),
recordTable: this.SYS_RTE_EB_FIELD,
recordId: impFieldId
});
} else if (fieldGr.deleteRecord()) {
result.deletedRecords.push({
message: gs.getMessage('Import field \'{0}\' has been deleted because the corresponding import table column is missing.', [impFieldName])
});
}
}
}
}
}
},
getOperationRecursive: function(fieldId, graph, feedId, result, doDelete) {
var deleteOperations = [];
var deleteFields = [];
if (!fieldId) {
return;
}
var queue = [];
var visited = [];
var parents = Object.keys(graph.edges);
for (var i = 0; i < parents.length; i++) {
if (Object.keys(graph.edges[parents[i]]).indexOf(fieldId) >= 0)
deleteOperations.push(graph.edges[parents[i]][fieldId].operationId);
}
queue.push(fieldId);
visited.push(fieldId);
deleteFields.push(fieldId);
while (queue.length != 0) {
var node = queue[0];
queue.splice(0, 1);
if (!graph.edges[node])
continue;
else {
var children = Object.keys(graph.edges[node]);
for (var j = 0; j < children.length; j++) {
if (visited.indexOf(children[j]) >= 0)
continue;
else {
deleteOperations.push(graph.edges[node][children[j]].operationId);
deleteFields.push(children[j]);
queue.push(children[j]);
visited.push(children[j]);
}
}
}
}
var operationGr = new GlideRecord(this.SYS_RTE_EB_OPERATION);
operationGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
operationGr.addQuery(this.SYS_ID, 'IN', deleteOperations);
operationGr.query();
while (operationGr.next()) {
var operationName = operationGr.getValue(this.NAME);
var operationId = operationGr.getValue(this.SYS_ID);
if (!doDelete) {
result.invalidRecords.push({
message: gs.getMessage('Operation \'{0}\' can be deleted because its Import field is missing.', [operationName]),
recordTable: this.SYS_RTE_EB_OPERATION,
recordId: operationId
});
} else if (operationGr.deleteRecord()) {
result.deletedRecords.push({
message: gs.getMessage('Operation \'{0}\' has been deleted because its Import field is missing.', [operationName])
});
}
}
var fieldsToDeleteMapping = deleteFields.join();
var fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
fieldMappingGr.addQuery(this.SOURCE_SYS_RTE_EB_FIELD, 'IN', fieldsToDeleteMapping);
fieldMappingGr.query();
while (fieldMappingGr.next()) {
// add the target fields to the fields to be deleted
deleteFields.push(fieldMappingGr.getValue(this.TARGET_SYS_RTE_EB_FIELD));
var id = fieldMappingGr.getValue(this.SYS_ID);
var sourceFieldName = fieldMappingGr.source_sys_rte_eb_field.name + '';
var targetFieldName = fieldMappingGr.target_sys_rte_eb_field.name + '';
if (!doDelete) {
result.invalidRecords.push({
message: gs.getMessage('Field mapping with the source field \'{0}\' to target field \'{1}\' can be deleted because the corresponding import table column is missing.', [sourceFieldName, targetFieldName]),
recordTable: this.SYS_RTE_EB_FIELD_MAPPING,
recordId: id
});
} else if (fieldMappingGr.deleteRecord()) {
result.deletedRecords.push({
message: gs.getMessage('Field mapping with the source field \'{0}\' to target field \'{1}\' has been deleted because the corresponding import table column is missing.', [sourceFieldName, targetFieldName])
});
}
}
var fieldGr = new GlideRecord(this.SYS_RTE_EB_FIELD);
fieldGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
fieldGr.addQuery(this.SYS_ID, deleteFields);
fieldGr.query();
while (fieldGr.next()) {
var id = fieldGr.getValue(this.SYS_ID);
var fieldName = fieldGr.getValue(this.NAME);
if (!doDelete) {
result.invalidRecords.push({
message: gs.getMessage('Field \'{0}\' can be deleted because the corresponding import table column is missing.', [fieldName]),
recordTable: this.SYS_RTE_EB_FIELD,
recordId: id
})
} else if (fieldGr.deleteRecord()) {
result.deletedRecords.push({
message: gs.getMessage('Field \'{0}\' has been internally deleted because the corresponding import table column is missing.', [fieldName])
});
}
}
},
getNonReferenceFieldMappingWithEmptySourceField: function(feedId, result, doDelete) {
var fieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
fieldMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
fieldMappingGr.addEncodedQuery('source_sys_rte_eb_fieldISEMPTY^referenced_sys_rte_eb_entityISEMPTY');
fieldMappingGr.query();
while (fieldMappingGr.next()) {
var id = fieldMappingGr.getValue(this.SYS_ID);
var targetFieldName = fieldMappingGr.target_sys_rte_eb_field.name + '';
var entityMappingName = fieldMappingGr.sys_rte_eb_entity_mapping.name + '';
var resultMessage = '';
if (!doDelete) {
if (targetFieldName) {
resultMessage = gs.getMessage('Field mapping with the target field \'{0}\' in the class mapping of \'{1}\' can be deleted because the source field is missing.', [targetFieldName, entityMappingName]);
} else {
resultMessage = gs.getMessage('Field mapping in the class mapping of \'{0}\' can be deleted because the source and target fields are missing.', [entityMappingName]);
}
result.invalidRecords.push({
message: resultMessage,
recordTable: this.SYS_RTE_EB_FIELD_MAPPING,
recordId: id
});
} else if (fieldMappingGr.deleteRecord()) {
if (targetFieldName) {
resultMessage = gs.getMessage('Field mapping with the target field \'{0}\' in the class mapping of \'{1}\' has been deleted because the source field is missing.', [targetFieldName, entityMappingName]);
} else {
resultMessage = gs.getMessage('Field mapping in the class mapping of \'{0}\' has been deleted because the source and target fields are missing.', [entityMappingName]);
}
result.deletedRecords.push({
message: resultMessage
});
}
}
},
getOperationsWithoutSourceOrTargetField: function(feedId, result, doDelete) {
var operationGr = new GlideRecord(this.SYS_RTE_EB_OPERATION);
operationGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
operationGr.query();
while (operationGr.next()) {
var isSetOperation = false;
var sys_id = operationGr.getUniqueValue();
var type = operationGr.getValue(this.TYPE);
isSetOperation = (type === this.getSetOperationTypeSysId());
var sourceIds = operationGr.getValue(this.SOURCE_SYS_RTE_EB_FIELD);
if (!sourceIds)
sourceIds = operationGr.getValue(this.SOURCE_SYS_RTE_EB_FIELDS);
var targetIds = operationGr.getValue(this.TARGET_SYS_RTE_EB_FIELD);
if (!targetIds)
targetIds = operationGr.getValue(this.TARGET_SYS_RTE_EB_FIELDS);
if ((!sourceIds && !isSetOperation) || !targetIds) {
var operationName = operationGr.getValue(this.NAME);
var operationId = operationGr.getValue(this.SYS_ID);
if (!doDelete) {
result.invalidRecords.push({
message: gs.getMessage('Operation \'{0}\' can be deleted because its source or target field is missing.', [operationName]),
recordTable: this.SYS_RTE_EB_OPERATION,
recordId: operationId
});
} else if (operationGr.deleteRecord()) {
result.deletedRecords.push({
message: gs.getMessage('Operation \'{0}\' has been deleted because its source or target field is missing.', [operationName])
});
}
}
}
},
getRollbackRunRecord: function(rollbackContextId) {
var rollbackRunGr = new GlideRecord(this.SYS_ROLLBACK_RUN);
rollbackRunGr.addQuery(this.ROLLBACK_CONTEXT_FIELD, rollbackContextId);
rollbackRunGr.orderByDesc(this.SYS_CREATED_ON);
rollbackRunGr.query();
if (rollbackRunGr.next()) {
return rollbackRunGr;
}
return;
},
validateIfRollbackCompleted: function(rollbackContextId) {
var rollbackRunGr, rollbackRunSysId, rollbackState;
rollbackRunGr = this.getRollbackRunRecord(rollbackContextId);
if (rollbackRunGr) {
rollbackRunSysId = rollbackRunGr.getValue(this.SYS_ID);
rollbackState = rollbackRunGr.getValue(this.ROLLBACK_STATE_FIELD);
if (rollbackState !== this.ROLLBACK_FINISHED_STATE) {
gs.error("Rollback error. Rollback context id: " + rollbackContextId + " Rollback run id: " + rollbackRunSysId + " Rollback state: " + rollbackState);
throw new Error(gs.getMessage("Rollback did not complete successfully. Rollback run record '{0}' has '{1}' status.", [rollbackRunSysId, rollbackState]));
}
} else {
gs.error("Cannot find rollback run history with context id '{0}'" + rollbackContextId);
throw new Error(gs.getMessage("Cannot find rollback run history with context id '{0}'", rollbackContextId));
}
return true;
},
checkIfApplicationScopeIsSame: function(dataSourceRec) {
// Need to verify couple of things
// Check if currently in the correct scope
var currentApplicationId = gs.getCurrentApplicationId();
var dataSourceApplicationId = dataSourceRec.sys_scope;
if (currentApplicationId != dataSourceApplicationId) {
var dataSourceName = dataSourceRec.getValue(this.NAME);
var dataSourceApplication = dataSourceRec.getDisplayValue('sys_scope');
var currentApplicationGr = new GlideRecord('sys_scope');
if(currentApplicationGr.get(currentApplicationId)) {
var errorMessage = gs.getMessage("The data source, '{0}', is in the {1} application, but {2} is the current application. An ETL Map needs to be created from the same application scope as its data source.",
[dataSourceName, dataSourceApplication, currentApplicationGr.name]);
var errorObj = this.buildErrorObject(errorMessage);
throw this.getInternalServerError(errorObj);
}
}
},
checkIfDSAssociatedWithETLMap: function(dataSourceRec, payload) {
// Make sure data source is not already associated with another ETL map
var robustTransformer = new GlideRecord('sys_robust_import_set_transformer');
robustTransformer.addQuery('source_table', dataSourceRec.import_set_table_name);
robustTransformer.addActiveQuery();
robustTransformer.query();
if (robustTransformer.next()) {
var robustTransformerName = robustTransformer.getValue(this.NAME);
var errorMessage = gs.getMessage("Data source table already associated with '{0}' ETL Map", [robustTransformerName]);
var errorObj = this.buildErrorObject(errorMessage, '', {requestPayload: payload});
throw this.getInternalServerError(errorObj);
}
},
checkIfDSAssociatedWithTableTransformMap: function(dataSourceRec, payload) {
var transformMap = new GlideRecord('sys_transform_map');
transformMap.addQuery('source_table', dataSourceRec.import_set_table_name);
transformMap.addActiveQuery();
transformMap.query();
if (transformMap.next()) {
var transformMapName = transformMap.getValue(this.NAME);
var errorMessage = gs.getMessage("Data source table already associated with '{0}' Table Transform Map", transformMapName);
var errorObj = this.buildErrorObject(errorMessage, '', {requestPayload: payload});
throw this.getInternalServerError(errorObj);
}
},
shouldDisableEntityMappingReorder: function(feedId) {
var disabledFeedIds = gs.getProperty(this.DISABLE_ENTITY_MAPPING_REORDER_PROPERTY_NAME);
var feedIdList = disabledFeedIds.split(',');
return feedIdList.indexOf(feedId) > -1;
},
updateEntity: function(feedId, entityId, group) {
var errorObj = {};
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityGr.addQuery(this.SYS_ID, entityId);
entityGr.query();
if (entityGr.next()) {
entityGr.setValue(this.NAME, group.name);
entityGr.setValue(this.PATH, group.path);
entityGr.setValue(this.TABLE, group.table);
entityGr.update();
} else {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity with id {0}', originalId));
throw this.getInternalServerError(errorObj);
}
return this.SUCCESS;
},
updateEntityMapping: function(feedId, entityId, entityName, order, conditionScript, condition) {
var errorObj = {};
var entityMappingGr = new GlideRecord(this.SYS_RTE_EB_ENTITY_MAPPING);
entityMappingGr.addQuery(this.SYS_RTE_EB_DEFINITION, feedId);
entityMappingGr.addQuery(this.TARGET_SYS_RTE_EB_ENTITY, entityId);
entityMappingGr.query();
if (!entityMappingGr.hasNext()) {
errorObj = this.buildErrorObject(gs.getMessage('Cannot find entity mapping with target entity id {0}', entityMappingGroupId));
throw this.getInternalServerError(errorObj);
} else {
entityMappingGr.next();
entityMappingGr.setValue(this.NAME, 'TempTo' + entityName);
if (order) {
entityMappingGr.setValue(this.ORDER, order);
}
if (conditionScript) {
entityMappingGr.setValue(this.CONDITION_SCRIPT, conditionScript);
}
if (condition) {
entityMappingGr.setValue(this.ENCODED_QUERY, condition);
}
entityMappingGr.update();
}
return this.SUCCESS;
},
getEntityMappingsAffectedByClassUpdate: function(feedId, oldEntityId, newClassFieldsList) {
var affectedMappingsList = {};
var encodedQuery = this.TARGET_SYS_RTE_EB_ENTITY + '=' + oldEntityId;
var entityMappingIds = this.getEntityMappingsForApplicationFeed(feedId, encodedQuery);
var fieldMappings = this.getFieldMappingsForEntityMapping(entityMappingIds[0].sys_id);
affectedMappingsList["fieldMappings"] = [];
for (var i = 0; i < fieldMappings.length; i++) {
if (newClassFieldsList.attributes.indexOf(fieldMappings[i].target_sys_rte_eb_field_display_value) === -1) {
affectedMappingsList["fieldMappings"].push({
'targetField': fieldMappings[i].target_sys_rte_eb_field_display_value,
'targetEntityTableName': fieldMappings[i].target_sys_rte_eb_entity_table_name,
'fieldMappingSysId': fieldMappings[i].sys_id,
'is_lookup': "false"
});
}
}
var lookupEntityGr = new GlideRecord(this.CMDB_INST_ENTITY);
lookupEntityGr.addQuery(this.LOOKUP_FOR_ENTITY, oldEntityId);
lookupEntityGr.query();
while (lookupEntityGr.next()) {
var sysId = lookupEntityGr.getUniqueValue();
encodedQuery = this.TARGET_SYS_RTE_EB_ENTITY + '=' + sysId;
entityMappingIds = this.getEntityMappingsForApplicationFeed(feedId, encodedQuery);
if (entityMappingIds.length > 0) {
fieldMappings = this.getFieldMappingsForEntityMapping(entityMappingIds[0].sys_id);
for (var j = 0; j < fieldMappings.length; j++) {
if (newClassFieldsList.lookUpRules && Object.keys(newClassFieldsList.lookUpRules).length > 0) {
var targetTableName = fieldMappings[j].target_sys_rte_eb_entity_table_name;
if (newClassFieldsList.lookUpRules[targetTableName] && newClassFieldsList.lookUpRules[targetTableName].indexOf(fieldMappings[j].target_sys_rte_eb_field_display_value) === -1) {
affectedMappingsList["fieldMappings"].push({
'targetField': fieldMappings[j].target_sys_rte_eb_field_display_value,
'targetEntityTableName': fieldMappings[j].target_sys_rte_eb_entity_table_name,
'targetEntityName': fieldMappings[j].target_sys_rte_eb_entity_name,
'fieldMappingSysId': fieldMappings[j].sys_id,
'is_lookup': "true"
});
}
} else {
affectedMappingsList["fieldMappings"].push({
'targetField': fieldMappings[j].target_sys_rte_eb_field_display_value,
'targetEntityTableName': fieldMappings[j].target_sys_rte_eb_entity_table_name,
'targetEntityName': fieldMappings[j].target_sys_rte_eb_entity_name,
'fieldMappingSysId': fieldMappings[j].sys_id,
'is_lookup': "true"
});
}
}
}
}
affectedMappingsList["relMappings"] = [];
affectedMappingsList["referenceMappings"] = [];
var entityFieldMappingGr = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
entityFieldMappingGr.addQuery(this.REFERENCED_SYS_RTE_EB_ENTITY, oldEntityId);
entityFieldMappingGr.query();
while (entityFieldMappingGr.next()) {
var entityTable = entityFieldMappingGr.sys_rte_eb_entity_mapping.target_sys_rte_eb_entity.table + '';
if (entityTable === this.CMDB_REL_CI) {
var parentEntityName = "";
var childEntityName = "";
var lookupEntityName = entityFieldMappingGr.referenced_sys_rte_eb_entity.lookup_for_entity.name;
if (entityFieldMappingGr.getDisplayValue(this.TARGET_SYS_RTE_EB_FIELD + '.field') === this.PARENT) {
parentEntityName = lookupEntityName ? lookupEntityName + ' - ' + entityFieldMappingGr.referenced_sys_rte_eb_entity.name : entityFieldMappingGr.referenced_sys_rte_eb_entity.name;
} else if (entityFieldMappingGr.getDisplayValue(this.TARGET_SYS_RTE_EB_FIELD + '.field') === this.CHILD) {
childEntityName = lookupEntityName ? lookupEntityName + ' - ' + entityFieldMappingGr.referenced_sys_rte_eb_entity.name : entityFieldMappingGr.referenced_sys_rte_eb_entity.name;
}
encodedQuery = '';
encodedQuery += 'referenced_sys_rte_eb_entity!=' + oldEntityId;
encodedQuery += '^sys_rte_eb_entity_mapping=' + entityFieldMappingGr.sys_rte_eb_entity_mapping;
lookupEntityName = '';
var entityFieldMappingGr2 = new GlideRecord(this.SYS_RTE_EB_FIELD_MAPPING);
entityFieldMappingGr2.addEncodedQuery(encodedQuery);
entityFieldMappingGr2.query();
if(entityFieldMappingGr2.next()) {
lookupEntityName = entityFieldMappingGr2.referenced_sys_rte_eb_entity.lookup_for_entity.name;
if (entityFieldMappingGr2.getDisplayValue(this.TARGET_SYS_RTE_EB_FIELD + '.field') === this.PARENT) {
parentEntityName = lookupEntityName ? lookupEntityName + ' - ' + entityFieldMappingGr2.referenced_sys_rte_eb_entity.name : entityFieldMappingGr2.referenced_sys_rte_eb_entity.name;
} else if (entityFieldMappingGr2.getDisplayValue(this.TARGET_SYS_RTE_EB_FIELD + '.field') === this.CHILD) {
childEntityName = lookupEntityName ? lookupEntityName + ' - ' + entityFieldMappingGr2.referenced_sys_rte_eb_entity.name : entityFieldMappingGr2.referenced_sys_rte_eb_entity.name;
}
affectedMappingsList["relMappings"].push({
'relMapping': gs.getMessage('\'{0}\' (Parent) :: \'{1}\' (Child)', [parentEntityName, childEntityName]),
'relType': entityFieldMappingGr.sys_rte_eb_entity_mapping.target_sys_rte_eb_entity.relationship_type.name
});
}
} else {
affectedMappingsList["referenceMappings"].push({
'targetField': entityFieldMappingGr.getDisplayValue(this.TARGET_SYS_RTE_EB_FIELD),
'entityTableName': entityFieldMappingGr.sys_rte_eb_entity_mapping.target_sys_rte_eb_entity.table,
'entityName': entityFieldMappingGr.sys_rte_eb_entity_mapping.target_sys_rte_eb_entity.name
});
}
}
affectedMappingsList["associatedMappings"] = [];
var entityGr = new GlideRecord(this.CMDB_INST_ENTITY);
entityGr.addQuery(this.RELATED_FOR_ENTITY, oldEntityId);
entityGr.query();
while (entityGr.next()) {
var associateName = entityGr.getValue(this.NAME);
affectedMappingsList["associatedMappings"].push({
'associatedEntityName': associateName
});
}
return affectedMappingsList;
},
calculateFurthestStep: function(appFeedGr) {
// Check if a scheduled exists for the data source, if so all steps are complete
var scheduleGr = new GlideRecord(this.SCHEDULED_IMPORT_SET);
scheduleGr.addQuery('data_source', appFeedGr.getValue(this.SYS_DATA_SOURCE));
scheduleGr.query();
if (scheduleGr.hasNext()) {
return this.MAX_STATE;
}
// If metadata exists, open up all of the mapping steps
if (this.hasMetadata(appFeedGr.getUniqueValue())) {
return this.RELATIONSHIP_MAPPING_STEP_NUMBER;
}
return "0";
},
type: 'CMDBIntegrationStudioUtility'
};
Sys ID
dc2ef8337324001008f8dca09ff6a7b1