- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Wednesday
I am trying to create 3 reports,
1. To show servers that are in scope (Operational status = operation AND install status = installed, Environment=Production) (Count 1424)
2. Servers that are in scope mapped to a application , (used sysId is one of and called a Script include) - 559 seems realistic
3. Servers that are in Scope and not mapped to a application (used sysId is one of and called a Script include) -Number is more than servers that are in Scope
unMappedSrvr: function() {
var unMapdServer = [];
var inScopeQuery = gs.getProperty('inscope.server.app.mapping');// Used same property for Mapped servers too
var grSer2 = new GlideRecord('cmdb_ci_server');
//grSer2.addEncodedQuery(inScopeQuery ); //Seems like this failing , return count shows more thanCIs as per below scope , returns 9000~
grSer2.addEncodedQuery('install_status=1^environment=Production^operational_status=1'); //This is same filter as property, count is within scope, returns 751
grSer2.query();
while (grSer2.next()) {
var grCrel = new GlideRecord('cmdb_rel_ci');
grCrel.addQuery('child', grSer2.sys_id);
grCrel.addQuery('parent.sys_class_name', 'INSTANCEOF', 'cmdb_ci_service_discovered');
grCrel.query();
if (!grCrel.next()) {
unMapdServer.push(grSer2.sys_id.toString());
}
while (grCrel.next()) {
var grDrel = new GlideRecord('cmdb_rel_ci');
grDrel.addQuery('child', grCrel.parent);
grDrel.addQuery('parent.sys_class_name', 'cmdb_ci_business_app');
grDrel.query();
if (!grDrel.next()) {
unMapdServer.push(grSer2.sys_id.toString());
}
}
}
return unMapdServer.join(',');
},
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thursday
Hi @pardhiv ,
I can see that there is some logic issues in the code, which may cause the mismatching in count
First One: You are using two grCrel.next() function along with if and while here
" if (!grCrel.next()) { ...
while (grCrel.next()) {" which is wrong because consider below scenarios
Scenario 1: When Server has NO relations, it will work fine
| grCrel.next() | returns FALSE |
| IF block | runs → push server |
| while(grCrel.next()) | returns FALSE → loop skipped |
BUT
Scenario 2:Server HAS relations (example: 2 relations) Rel1, Rel2
IFCondition: !grCrel.next()here our rel1 is checked and cursor is moved to rel2.
while(grCrel.next()) here in the while loop rel2 is checked, so rel1 will always be skipped
Second One: You are pushing server inside the loop which is causing the duplicates
in this code portion:
while(..){
{if (!grDrel.next())
{ unMapdServer.push(grSer2.sys_id.toString()); }}
Consider: If server 1 has 3 discovered service, none of these services are linked to business application means the same server will be pushed 3 times in the array
So the corrected code is...
unMappedSrvr: function() {
var unMapdServer = [];
var inScopeQuery = gs.getProperty('inscope.server.app.mapping');
var grSer2 = new GlideRecord('cmdb_ci_server');
grSer2.addEncodedQuery('install_status=1^environment=Production^operational_status=1');
grSer2.query();
while (grSer2.next()) {
var isUnmapped = false;
var grCrel = new GlideRecord('cmdb_rel_ci');
grCrel.addQuery('child', grSer2.sys_id);
grCrel.addQuery('parent.sys_class_name', 'INSTANCEOF', 'cmdb_ci_service_discovered');
grCrel.query();
// 1 If NO discovered service relation
if (!grCrel.hasNext()) {
isUnmapped = true;
}
// 2 If discovered services exist, check business app mapping
while (!isUnmapped && grCrel.next()) {
var grDrel = new GlideRecord('cmdb_rel_ci');
grDrel.addQuery('child', grCrel.parent);
grDrel.addQuery('parent.sys_class_name', 'cmdb_ci_business_app');
grDrel.query();
// If service NOT linked to business app
if (!grDrel.hasNext()) {
isUnmapped = true;
break; // stop checking further services
}
}
// 3 Push only once
if (isUnmapped) {
unMapdServer.push(grSer2.sys_id.toString());
}
}
return unMapdServer.join(',');
}
Fix I applied
1) hasNext() ==> if (!grCrel.hasNext()) { ... } -> only checks if record exists, will not move the cursor to next record.
2)Handled duplicates ==> I avoided pushing the server inside the loop. Instead, I used a flag to mark the server as unmapped and immediately broke out of the loop when the condition was met. After exiting the loop, I pushed the server only once, which prevents duplicate entries.
I have made lot of efforts for this , if you find these useful please mark it as helpful and please accept my solution...
Best Regards,
SIVASANKARI S
ITOM Engineer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thursday
Hi @pardhiv ,
I can see that there is some logic issues in the code, which may cause the mismatching in count
First One: You are using two grCrel.next() function along with if and while here
" if (!grCrel.next()) { ...
while (grCrel.next()) {" which is wrong because consider below scenarios
Scenario 1: When Server has NO relations, it will work fine
| grCrel.next() | returns FALSE |
| IF block | runs → push server |
| while(grCrel.next()) | returns FALSE → loop skipped |
BUT
Scenario 2:Server HAS relations (example: 2 relations) Rel1, Rel2
IFCondition: !grCrel.next()here our rel1 is checked and cursor is moved to rel2.
while(grCrel.next()) here in the while loop rel2 is checked, so rel1 will always be skipped
Second One: You are pushing server inside the loop which is causing the duplicates
in this code portion:
while(..){
{if (!grDrel.next())
{ unMapdServer.push(grSer2.sys_id.toString()); }}
Consider: If server 1 has 3 discovered service, none of these services are linked to business application means the same server will be pushed 3 times in the array
So the corrected code is...
unMappedSrvr: function() {
var unMapdServer = [];
var inScopeQuery = gs.getProperty('inscope.server.app.mapping');
var grSer2 = new GlideRecord('cmdb_ci_server');
grSer2.addEncodedQuery('install_status=1^environment=Production^operational_status=1');
grSer2.query();
while (grSer2.next()) {
var isUnmapped = false;
var grCrel = new GlideRecord('cmdb_rel_ci');
grCrel.addQuery('child', grSer2.sys_id);
grCrel.addQuery('parent.sys_class_name', 'INSTANCEOF', 'cmdb_ci_service_discovered');
grCrel.query();
// 1 If NO discovered service relation
if (!grCrel.hasNext()) {
isUnmapped = true;
}
// 2 If discovered services exist, check business app mapping
while (!isUnmapped && grCrel.next()) {
var grDrel = new GlideRecord('cmdb_rel_ci');
grDrel.addQuery('child', grCrel.parent);
grDrel.addQuery('parent.sys_class_name', 'cmdb_ci_business_app');
grDrel.query();
// If service NOT linked to business app
if (!grDrel.hasNext()) {
isUnmapped = true;
break; // stop checking further services
}
}
// 3 Push only once
if (isUnmapped) {
unMapdServer.push(grSer2.sys_id.toString());
}
}
return unMapdServer.join(',');
}
Fix I applied
1) hasNext() ==> if (!grCrel.hasNext()) { ... } -> only checks if record exists, will not move the cursor to next record.
2)Handled duplicates ==> I avoided pushing the server inside the loop. Instead, I used a flag to mark the server as unmapped and immediately broke out of the loop when the condition was met. After exiting the loop, I pushed the server only once, which prevents duplicate entries.
I have made lot of efforts for this , if you find these useful please mark it as helpful and please accept my solution...
Best Regards,
SIVASANKARI S
ITOM Engineer
