Getting Started with ServiceNow: Server-side Glide, Performance common issues, Business Rules and Client Scripts

Hi guys,

It’s time for ServiceNow go on air, all lights pointed at him now please.

The topics for today’s post are scripting (Server-side Glide, Business Rules, Client Scripting) and how to troubleshoot some performance issues. This are basic key points for any SN admin.

If you know how to answer the questions below, probably you should jump straight away to my next post I am going to post regarding this category.

Review questions:

  • How can I obtain a list of distinct incidents?
  • How can I measure performance of a request?
  • What’s the difference between client script and server-side script?
  • What is a business rule?
  • What is a client script?

Scripting

The ServiceNow Glide classes expose JavaScript APIs that enable you to conveniently work with tables using scripts.

Using the Glide APIs, you can perform database operations without writing SQL queries, display UI pages, and define UI actions. The following tables provide brief descriptions of the Glide classes and links to detailed information.

Server-side Glide classes
Class Description
GlideRecord Use this class for database operations instead of writing SQL queries. GlideRecord is a special Java class that can be used in JavaScript exactly as if it were a native JavaScript class. A GlideRecord is an object that contains records from a single table. See GlideRecord.
GlideElement Use this class to operate on the fields of the current GlideRecord. See GlideElement.
GlideSystem Use this class to get information about the system. See GlideSystem.
GlideAggregate Use this class to perform database aggregation queries, such COUNT, SUM, MIN, MAX, and AVG, for creating customized reports or calculations in calculated fields. See GlideAggregate.
GlideDateTime Use this class to perform date-time operations, such as date-time calculations, formatting a date-time, or converting between date-time formats. See GlideDateTime.
Client-side Glide Classes
Class Description
GlideAjax Use this class to execute server-side code from the client. See GlideAjax.
GlideDialogWindow Use this class to display a dialog window. See GlideDialogWindow.
GlideForm Use this class to customize forms. See GlideForm.
GlideList2 Use this class to customize (v2) lists, including normal lists and related lists. See GlideList2.
GlideMenu Use this class to customize UI Context Menu items. See GlideMenu.
GlideUser Use this class to get session information about the current user and current user roles. See GlideUser.

I will focus in server-side scripting at this moment because 70% of the cases is what you need.

Scoped GlideRecord is used for database operations.

A GlideRecord contains both records and fields. For information about GlideRecordSecure, which is a class inherited from GlideRecord that performs the same functions as GlideRecord, and also enforces ACLs, see the GlideRecordSecure documentation.

Always test queries on a sub-production instance prior to deploying them on a production instance. An incorrectly constructed encoded query, such as including an invalid field name, produces an invalid query. When the invalid query is run, the invalid part of the query condition is dropped, and the results are based on the valid part of the query, which may return all records from the table. Using an insert(), update(), deleteRecord(), or deleteMultiple() method on bad query results can result in data loss.

Imagine the following scenario, you want to retrieve the incidents with priority 1.

Example:

var gr = new GlideRecord('incident');
gr.addQuery('priority','1');
gr.query();
while (gr.next()) {
  gs.addInfoMessage(gr.number);
}

Honestly for large queries I prefer to use addEncodedQuery(String query) instead of addQuery(String name, Object value). Much easier and safe.

Example:

var queryString = "priority=1^ORpriority=2";
var gr = new GlideRecord('incident');
gr.addEncodedQuery(queryString);
gr.query();
while (gr.next()) {
  gs.addInfoMessage(gr.number);
}

If for example, you want to look for Problem records that have associated Incident records

Example:

var gr = new GlideRecord('problem');
var grSQ = gr.addJoinQuery('incident');
 
// Where the Problem records are "active=false"
gr.addQuery('active', 'false');
 
// And the Incident records are "active=true"
grSQ.addCondition('active', 'true');
 
gr.query();
 
// Iterate and output results
while (gr.next()) {
    gs.info(gr.getValue('number'));
}

To do queries that group by something you’ll need to use GlideAggregate instead of GlideRecord. The GlideAggregate class is an extension of GlideRecord and allows database aggregation (COUNT, SUM, MIN, MAX, AVG) queries to be done. This can be helpful in creating customized reports or in calculations for calculated fields.

Here is an example to get distinct count of a field on a group query.

var agg = new GlideAggregate('incident');
agg.addAggregate('count');
agg.addAggregate('count(distinct','category');
agg.addQuery('opened_at', '>=', 'javascript:gs.monthsAgoStart(2)');
agg.addQuery('opened_at', '<=', 'javascript:gs.monthsAgoEnd(2)');
//
agg.groupBy('priority');
agg.query();
while (agg.next()) {
// Expected count of incidents and count of categories within each priority value (group)
  gs.info('Incidents in priority ' + agg.priority + ' = ' + agg.getAggregate('count') + 
            ' (' + agg.getAggregate('count(distinct','category') + ' categories)');
}

How to face and troubleshoot your performance issues

Diagnosing Service Now performance issues can be challenging sometimes. I still have a lot to learn about troubleshooting when things go wrong but I will share some of the things I have commonly seen cause performance issues in the Service Now so that if you run into performance issues, you’ll know where to look in order to start diagnosing the problem and figuring out how to deal with it.

Ensure system optimization through performance monitoring and diagnostics.

  • Application server response: Time for the application server to process a request and render the resultant page.
  • Network latency and throughput: Time for the network to pass your request to the server and the response back.
  • Browser rendering and parsing: Time for your browser to render the HTML and parse/execute Javascript.
  • Instance Cache: The amount of system resources available for processing.

Instance cache effects on performance

There is a performance degradation whenever you purge and rebuild the instance cache. During core business hours, avoid or minimize any of the following actions that cause a purge and rebuild of the instance cache.

  • Adding or updating system properties
  • Adding or updating dictionary entries
  • Committing update sets
  • Adding or updating translations

Business rules vs Client Script

A business rule is a server-side script that runs when a record is displayed, inserted, updated, or deleted, or when a table is queried.Use business rules to accomplish tasks like automatically changing values in form fields when certain conditions are met, or to create events for email notifications and script actions. Business rules can make use of scripts to take actions on records in the database. However, there are several other scripting options available on the platform, such as client scripts and UI actions.

Clients scripts allow the system to run JavaScript on the client (web browser) when client-based events occur such as when a form loads, after form submission, or when a field changes value.

The system can run client scripts for these client-based events.

 
Type and required function name Description
onLoad() An onLoad() client script runs when the system first renders the form and before users can enter data. Typically, onLoad() client scripts perform client-side-manipulation of the current form or set default record values.
onSubmit() An onSubmit() client script runs when a form is submitted. Typically, onSubmit() scripts validate things on the form and ensure that the submission makes sense. An onSubmit() client script can cancel form submission by returning a value of false.
onChange() An onChange() client script runs when a particular field value changes on the form. The onChange() client script must specify these parameters.

  • control: the DHTML widget whose value changed.
  • oldValue: the value the widget had when the record was loaded.
  • newValue: the value the widget has after the change.
  • isLoading: identifies whether the change occurs as part of a form load.
  • isTemplate: identifies whether the change occurs as part of a template load.
onCellEdit() An onCellEdit() client script runs when the list editor changes a cell value. The onCellEdit() client script must specify these parameters.

  • sysIDs: an array of the sys_ids for all items being edited.
  • table: the table of the items being edited.
  • oldValues: the old values of the cells being edited.
  • newValue: the new value for the cells being edited.
  • callback: a callback that continues the execution of any other related cell edit scripts. If true is passed as a parameter, the other scripts are executed or the change is committed if there are no more scripts. Iffalse is passed as a parameter, any further scripts are not executed and the change is not committed.
Note: onCellEdit() client scripts do not apply to dashboard list widgets.

With the exception of onCellEdit() client scripts, client scripts only apply to forms and search pages. If you create a client script to control field values on a form, you must use one of these other methods to control field values when on a list.

  • Create an access control to restrict who can edit field values.
  • Create a business rule to validate content.
  • Create a data policy to validate content.
  • Create an onCellEdit() client script to validate content.
  • Disable list editing for the table.

 

Hope this can you help you to do a proper push up on your ServiceNow skills.

 

Thank you,

Kind regards.
Rafael

5/5 - (1 vote)