How to remove duplicate relationships on each affected CI ?

Community Alums
Not applicable

Hi Everyone,

How can we restrict duplicate relationships on each affected CI and also  Prevention the creation of new duplicate relationships (Patches::Patched by).

Script Include has been written for this, still its effecting with duplicate CI's

Script Include :

var FA_CMDB_DupRelationshipHelper = Class.create();
FA_CMDB_DupRelationshipHelper.prototype = {
   

    validateCIRelationships: function(appNumber,ciSysID,ciDisplayName,trigger) {
        var errorReason = '';
        var grInserOrUpdRel = new GlideRecord('cmdb_rel_ci');
        var relType = gs.getProperty('cmdb.rel.runs_on_runs_type'); // Runs on relationship sys id
        var grApp = new GlideRecord("cmdb_ci_service_discovered");
        grApp.addEncodedQuery("number=" + appNumber);
        grApp.setLimit(1);
        grApp.query();
        if (grApp.next()) {
            var gaRel = new GlideAggregate('cmdb_rel_ci');
            gaRel.addEncodedQuery("child=" + ciSysID + "^type=" + relType + "^parent.sys_class_name=cmdb_ci_service_discovered"); // Query to check any relationships existed with provided appNumber, ciSysID & cmdb_ci_service_discovered table as parent 
            gaRel.addAggregate('COUNT');
            gaRel.query();
            if (gaRel.next()) {
                if (gaRel.getAggregate('COUNT') == 0) { // No records Create a new relationship
                    grInserOrUpdRel.initialize();
                    grInserOrUpdRel.setValue('child', ciSysID);
                    grInserOrUpdRel.setValue("type", relType); // setting Runs on :Runs relationship type
                    grInserOrUpdRel.setValue('parent', grApp.getUniqueValue());
                    grInserOrUpdRel.insert();
                    if (ciDisplayName) {
                        this.checkOSIRel(ciDisplayName, grApp.getUniqueValue(), relType, appNumber, trigger);
                    }
                } else if (gaRel.getAggregate('COUNT') > 1) { // if we have more than one record need to delete all and create one relationship
                    this.delDuplicateRecords(ciSysID, relType);
                    grInserOrUpdRel.initialize();
                    grInserOrUpdRel.setValue('child', ciSysID);
                    grInserOrUpdRel.setValue("type", relType); // setting Runs on :Runs relationship type
                    grInserOrUpdRel.setValue('parent', grApp.getUniqueValue());
                    grInserOrUpdRel.insert();
                    if (ciDisplayName) {
                        this.checkOSIRel(ciDisplayName, grApp.getUniqueValue(), relType, appNumber, trigger);
                    }
                } else if (gaRel.getAggregate('COUNT') == 1) { // if we have one record need to verify any changes based on that update
                    grInserOrUpdRel.initialize();
                    grInserOrUpdRel.addEncodedQuery("child=" + ciSysID + "^type=" + relType + "^parent.sys_class_name=cmdb_ci_service_discovered"); 
                    grInserOrUpdRel.setLimit(1);
                    grInserOrUpdRel.query();
                    if (grInserOrUpdRel.next()) {
                        if (grInserOrUpdRel.getValue('parent') != grApp.getUniqueValue()) {
                            grInserOrUpdRel.parent = grApp.getUniqueValue();
                            grInserOrUpdRel.update();
                        }
                        if (ciDisplayName) {
                            this.checkOSIRel(ciDisplayName, grApp.getUniqueValue(), relType, appNumber, trigger);
                        }
                    }
                }
            }
        } else {
            errorReason = 'Cannot find matching Application Service with the number in Key Value "ApplicationServiceNumber" entry from the VMI: <strong>' + ciDisplayName + '</strong>';
            gs.eventQueue('fa.cmdb.relationship.failed', null, errorReason, trigger);
        }
    },
    
    delDuplicateRecords: function(CI, relType) {
        var grRel = new GlideRecord('cmdb_rel_ci');
        grRel.addEncodedQuery("child=" + CI + "^type=" + relType + "^parent.sys_class_name=cmdb_ci_service_discovered");
        grRel.query();
        while (grRel.next()) {
            grRel.setWorkflow(false);
            grRel.deleteRecord();
        }
    },

    checkOSIRel: function(displayName, appSerID, relType, appNumber, trigger) {
        // Check on Cmdb server table
        var ciClass = '';
        var ciSysID = '';
        var errorReason= '';
        var gtServerNme = new GlideRecord('cmdb_ci_server');
        gtServerNme.addQuery('name', displayName);
        gtServerNme.addQuery('install_status', '!=', '7');
        gtServerNme.setLimit(1);
        gtServerNme.query();
        if (gtServerNme.next()) {
            ciClass = gtServerNme.getValue('sys_class_name');
            ciSysID = gtServerNme.getUniqueValue();
        } else {
            errorReason = 'Cannot find matching OS Server with same name as the VMI: ' + displayName +' server with the inserted/updated Key Value: <strong>' + appNumber + '</strong>';
            gs.eventQueue('fa.cmdb.relationship.failed', null, errorReason, trigger);
        }
        if (ciSysID) {
            var qry = "typeLIKERuns on::Runs^child.sys_class_name!=cmdb_ci_vm_instance^parent.sys_class_name=cmdb_ci_service_discovered^child.sys_id=" + ciSysID;
            var getOSrel = new GlideRecord('cmdb_rel_ci');
            getOSrel.addEncodedQuery(qry);
            getOSrel.query();
            if (getOSrel.hasNext()) {
                while (getOSrel.next()) {
                    getOSrel.setWorkflow(false);
                    getOSrel.deleteRecord();
                }
                getOSrel.initialize();
                getOSrel.setValue('child', ciSysID);
                getOSrel.setValue("type", relType); // setting Runs on :Runs relationship type
                getOSrel.setValue('parent', appSerID);
                getOSrel.insert();
            } else {
                getOSrel.initialize();
                getOSrel.setValue('child', ciSysID);
                getOSrel.setValue("type", relType); // setting Runs on :Runs relationship type
                getOSrel.setValue('parent', appSerID);
                getOSrel.insert();
            }
        }
    },
    type: 'FA_CMDB_DupRelationshipHelper'
}

 

Thanks and Regards @Ankur Bawiskar , @Mohith Devatte 

Venugopal S

1 ACCEPTED SOLUTION

A before insert business rule on cmdb_rel_ci table with below script would do the job for you

 

var rel = new GlideRecord('cmdb_rel_ci');

rel.addQuery('parent', current.parent);

rel.addQuery('child', current.child);

rel.addQuery('type', <sys_id of Patches::Patched by >);

rel.query();

 

if (rel.next()){

gs.addInfoMessage("relationship already exists");

current.setAbortAction(true);

}

View solution in original post

7 REPLIES 7

suvro
Mega Sage
Mega Sage

when this script include is called ?

It should be called in before insert business rule on cmdb_rel_ci

Community Alums
Not applicable

There are 3 business rules are written before insert. which doesn't have the relation for duplicates.

Thanks

A before insert business rule on cmdb_rel_ci table with below script would do the job for you

 

var rel = new GlideRecord('cmdb_rel_ci');

rel.addQuery('parent', current.parent);

rel.addQuery('child', current.child);

rel.addQuery('type', <sys_id of Patches::Patched by >);

rel.query();

 

if (rel.next()){

gs.addInfoMessage("relationship already exists");

current.setAbortAction(true);

}