k11advancedscriptinglabfinal-110519110956-phpapp02
TRANSCRIPT
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
1/54
Advanced Scripting &Debugging Lab
John Roberts Application DeveloperServiceNow
Jerrod BennettSenior Technical ConsultantServiceNow
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
2/54
Overview Scripting & Debugging Concepts Debugging Tools
Client and Server Debugging Examples Extending Script Includes AJAX Debugging Basic Jelly Debugging Display Business Rules
Lab Agenda
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
3/54
Overview
Disclaimer Advanced topics and quick pace Assumes some scripting experience and knowledge of
Service-now.com concepts
Objectives Improve scripting and troubleshooting abilities Learn some new tricks
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
4/54
Overview
Setup Lab instance Script source - http://wiki.service-now.com/index.php?
title=Script_Lab
Optional Install Firefox and Firebug
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
5/54
Scripting Concepts (quick review)
Case SenSitiviTy All commands, functions, variables,
Variable Scope Session global risk of duplication
Classes limited to class
Function limited to function, best protection
!"# %&'"%( ) *+,-./0 12.34,. 5,6-789: ;
!"# %&'"%( ) *#,
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
6/54
Scripting Concepts (quick review)
Reference vs Value values Reference var myId = gr.sys_id;
myId will change as gr changes
Value var myId = gr.sys_id.toString(); myId will only change if explicitly changed
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
7/54
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
8/54
Debugging Concepts
Know what should happen
Identify what is happening
Did my script run, were there errors
Do I have the expected results
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
9/54
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
10/54
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
11/54
Exercise 1 Debug Business Rule
Scenario: business rule adds comments when incident state changesto closed
Problem: no comments are being added Business rule: k11 Exercise 1 Incident Close Comment
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
12/54
Exercise 1 Debug Business Rule
Try it Open an existing incident Set incident state to Closed Using header context menu, save the record
Result No comment or info message
Troubleshooting Did the rule execute
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
13/54
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
14/54
Exercise 1 Debug Business Rule
For some reason our condition is not being satisfied current.incident_state.changesTo("Closed")
Lets remove the condition and find out what the field value ischanging to
Delete the condition so the rule will execute Comment out the comment set statement so it doesnt run on all incidents Add some debugging statements
//add comment when closing
//current.comments = "Closed by " + gs.getUserName() + " at " + gs.nowDateTime(); //gs.addInfoMessage("Close comment added");
// Debug info gs.addInfoMessage( "(InfoMessage) Incident state = " + current.incident_state) ; //output to app
gs.log( "(Log) Incident state = " + current.incident_state) ; //output to system log
gs.print( "(debug print) Incident state = " + current.incident_state) ; //output to debug console
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
15/54
Exercise 1 Debug Business Rule
Open another existing incident and set incident state to closed ,save
Scroll down to see debug output and notice the following3:50:23.714: ==> ' k11 Exercise 1 - Incident Close Comment ' on table incident 13:50:23.718: : (Log) Incident state = 713:50:23.718: : (debug print) Incident state = 713:50:23.719:
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
16/54
Exercise 1 Debug Business Rule
Perform one more test to verify
If we suspected the field value was wrong we could have taken ashortcut From a closed incident form, use the header context menu Show XML to display
all fields and values
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
17/54
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
18/54
Exercise 2 Business Rule Changes
Scenario: whenever we create a hardware incident the priority is setto 1, we suspect it might be a business rule
Try it Create a new incident and set category to Hardware
Save the incident, and notice the priority value has changed to 1
Debugging Enable the Debug Business Rule (Details) to add detail to the debug output Create another hardware incident , save View debug output
==> ' k11 Exercise 2 - Incident Priority Change ' on table incidentpriority: 4 => 1
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
19/54
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
20/54
Exercise 3 Error Handling
Scenario: simple business rule should add message when saving asoftware incident
Problem: we are only getting one of the three messages we expect
Try it Create a incident with software category Add a short description and save Notice we are getting one message at the top of the form
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
21/54
Exercise 3 Error Handling
Following the javascript processor line by line Run the JS Debug Activate module to enable the Rhino debugger Create another software incident and view the debug output Search the page for Exercise 3 to find the related script processing
==> ' k11 Exercise 3 - Display Info ' on table incident evaluate://output current number gs.addInfoMessage("Current number: " + current.number); //output current
short_description gs.addInfoMessage("Current Short Description: " + currrent.short_description); //outputcurrent category gs.addInfoMessage("Current Category: " + current.category);>>> line(2) gs.addInfoMessage("Current number: " + current.number);>>> line(5) gs.addInfoMessage("Current Short Description: " + currrent.short_description);
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
22/54
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
23/54
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
24/54
Exercise 3 Error Handling
Create one more software incident and see how the catchstatement provides information
==> ' k11 Exercise 3 - Display Info ' on table incident : : Error in k11 Exercise 3 business rule: ReferenceError: "currrent" is not defined.
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
25/54
Debugging ExamplesExercise 4
Client Script
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
26/54
Exercise 4 Client Script
Scenario: incident table has an on-change client script for categoryfunction onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue == '' )
return ;
if (newValue == request ) { g_form.setValue( "urgency" , 3) ;
jslog( "k11 Exercise 5 Request Category client script: Setting urgency to lowfor requests" ) ; }
}
Try it Lets review options for client-side debug output Enable client javascript debugger console by clicking the green bug in the top
banner Create a new incident , change category to request Script will log to debug console and change urgency to low Review debug console
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
27/54
Exercise 4 Client Script
Using browser debuggers ( Firebug )
From a new incident form , open Firebug and make sure its active
Go to the script tab and search for g_form.setValue("urgency ,
so we can locate our script
Set a break point by clicking in the gray area left of the line numbers
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
28/54
Exercise 4 Client Script
Change the category to request to execute the script again
Firebug breakpoints can be funny at times, refresh the form scriptdoes not stop at breakpoint
Review all the information available during the break
You can also step through code using the yellow arrows
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
29/54
Debugging ExamplesExercise 5
Javascript Executor
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
30/54
Exercise 5 Javascript Executor
Scenario: it would be nice to have a fast way to test client scriptswithout actually creating them first
Solution: Javascript executor has access to the same clientenvironment as client scripts
Try it: From a change request form , press to launch the javascript executor
See that the description field is mandatory, lets test a script to change that g_form.setMandatory("description", false); Click Run My Code button Notice the mandatory flag has been removed, lets add it back and add a short
description g_form.setMandatory("description", true); g_form.setValue(short_description, Testing);
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
31/54
Exercise 5 Javascript Executor
Now for a cool admin trick Close the executor and verify that you cannot save the form with a
blank description field Re-open the executor and run
g_form.checkMandatory = false; Run My Code
Close executor Try to save the form again with a blank description You just temporarily bypassed the mandatory check on the form Use it wisely and keep it a secret
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
32/54
Debugging ExamplesExercise 6
Background Scripts
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
33/54
Exercise 6 Background Scripts
Scenario: admin needs a way to test server side scripts or performsome maintenance that requires a script
Solution: background scripts are the server side version of Javascriptexecutor
Warning: this can really be dangerous , and even crash an entireinstance if you get something wrong
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
34/54
Exercise 6 Background Scripts
Try it Lets build a script to disable some users Launch the background script module Enter the following script
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
35/54
Exercise 6 Background Scripts
Notice that we have commented out the update line Its always best to see the possible results before you actually do
anything Run the script to see the results
If this is a script you need frequently you can also save it to theserver
Upload a script file with .js extension using the file uploadmodule
It will be available in the customer scripts for future reference andexecution
To be safe you can leave the function call commented when youupload so you purposely have to view and change it before itdoes anything harmful
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
36/54
Debugging ExamplesExercise 7
Extending Script Includes
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
37/54
Exercise 7 Extending Script Includes
Scenario: I like the functionality provided by the TableUtils scriptinclude but want to change it a bit
The getTables method in TableUtils class returns the parent list oftable hierarchy, but it returns it in a java array list not an array
For example you cant enumerate a java array list like you would witha Javascript array
//enumerate java array list for ( var i =0; i < tables.size() ; i ++) {
gs.print(tables.get(i)) ; }
//enumerate javascript array for ( var i =0; i < tableArray.length ; i ++) { gs.print(tableArray[i]) ; }
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
38/54
Exercise 7 Extending Script Includes
Try it From background scripts get the tables hierarchy for cmdb_ci_win_server
var util = new TableUtils( cmdb_ci_server ) ; //getTables returns a java array list object, not array
var tables = util.getTables() ; gs.print( "Java list: " + tables) ;
//what is the tables object
JSUtil.logObject(tables, "tables" ) ;
//enumerate java array list for ( var i =0; i < tables.size() ; i ++) {
gs.print(tables.get(i)) ; }
We could convert the array list to an array whenever we need it but it would benice to change the getTables method to return an array Modifying an out-of-box script include is never recommended
!!! #$%&'() *+,+ -&.() /$0123$&3.4%,4%5$0123$&3$60'7(4%5 $0123$&38+%19+%45$0123$&:!!! #$%&'() ;6< =2>4$() (+2-4.
*+,+ =2>4$() $60?
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
39/54
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
40/54
Exercise 7 Extending Script Includes
Since we dont want to modify the system script include well create ourown . We could make a full copy but that would be a waste, when wecan extend the class and leverage everything thats already in place.
Create a new script include for the MyTableUtils class Extending can add to or replace methods from the parent class
var MyTableUtils = Class.create() ;
MyTableUtils.prototype = Object.extendsObject(TableUtils, { getTablesArray: function () {
var tables = this.getTables() ; return j2js(tables) ;
},
type: "MyTableUtils" }) ;
Save the record so we can test it
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
41/54
Exercise 7 Extending Script Includes
Return to background scripts and call the new class
var util = new MyTableUtils( "cmdb_ci_server" ) ; //call our new method var tables = util.getTables() ;
gs.print( "Java list: " + tables) ; JSUtil.logObject(tables, "tables" ) ;
gs.print( "" ) ;
var tablesArray = util.getTablesArray() ;
gs.print(tablesArray) ; JSUtil.logObject(tablesArray, "tablesArray" ) ; //what is util object
JSUtil.logObject(util, "util" ) ;
Notice that we didnt need an initialize of getTables method in our class,we inherited those from the parent (this) object
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
42/54
Debugging ExamplesExercise 8
AJAX Debugging
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
43/54
Exercise 8 AJAX
Scenario: Use AJAX to lookup the number of available developmentlaptops when someone attempts to request one through the catalog
Components Catalog client script to submit AJAX request to server AJAX processor script include to perform the check and return the result to client Catalog client script to process the AJAX response and inform the user
Try it Go to the catalog and load the Development Laptop item Script runs on load to check inventory and alerts user with status from server
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
44/54
Exercise 8 AJAX
Review scripts Review catalog client script k11 Capacity Check Review script include k11 CatalogCapacityCheck
Debugging options Log statements in script include Firebug to inspect payload to/from server Manual client script testing from javascript executor
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
45/54
Exercise 8 AJAX
Try it From the development laptop catalog item page start the javascript executor
Run the following script to make an AJAX request
var gajax = new GlideAjax( CapacityCheckAjax ) ;
gajax.addParam( "sysparm_name" , "checkDevCapacity" ) ; gajax.getXML(ajaxResponse) ;
function ajaxResponse(serverResponse) {
alert(serverResponse.responseText) ; }
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
46/54
Debugging Examples
Exercise 9Jelly
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
47/54
Exercise 9 Jelly
Scenario: In a jelly script such as a UI Page, I would like to knowwhich jelly variables are available and what the values are
Options For known variables you can write values to HTML output Use breakpoint tag to view all available variables in a given phase
Jelly in 30 seconds XML files executed on server and output as HTML to client Evaluated in two phases, {phase 1} is cached (content), [phase 2] for data Nested structures with variables typically being passed down (UI Page calls a UI
Macro)
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
48/54
Exercise 9 Jelly
Try it Review UI page k11_test Notice the j:set and j2:set lines setting values for jvar_p1_test and jvar_p2_test
Review UI macro k11_macro_test called from the UI page Notice the references to the variables defined in the j:set and j2:set lines in the
UI page
Enable Debug Log so we can view of out of the macro breakpoints Navigate browser to /k11_test.do Examine the debug information Notice how our jvar_p1_test and jvar_p2_test only have value in their respective
phases
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
49/54
Debugging Examples
Exercise 10Display Business Rules
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
50/54
Exercise 10 Display Business Rules
Scenario: a client script needs to access data from a field that is notdisplayed on the form
Options Add the field to the form view and hide it using a UI policy Use a client GlideRecord query using AJAX Use a display business rule to preload an object that is passed to the client
Display business rules are processed on the server before the recorddata is passed to the client
The g_scratchpad object is available for setting values in the rule
and getting values on the client Display rules can also change field data , similar to calculated fields
since they display the new value but its not written to the databaseuntil you save the record
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
51/54
Exercise 10 Display Business Rules
Review business rule k11 Exercise 10 Send data to the clienton the problem table//get the record sys_created_by value and add to the client scratchpad g_scratchpad.created_by = current.sys_created_by ;
//calculate the age of this record var age = gs.dateDiff(current.sys_created_on, gs.nowDateTime(), true ) ; var daysOld = Math.round(age / 3600 / 24 ) ;
g_scratchpad.days_old = daysOld ;
Review the client script k11 Exercise 10 - notify on oldproblems on problem table
function onLoad() { //get data from display rule scratchpad var createdBy = g_scratchpad.created_by ;
var daysOld = g_scratchpad.days_old ;
if (parseInt(daysOld) > 30 ) { alert( "This is an old record created by " + createdBy) ;
} }
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
52/54
Exercise 10 Display Business Rules
Try it Open the list of problems and find one that was created more than 30 days ago Notice the alert from the client script
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
53/54
-
8/11/2019 k11advancedscriptinglabfinal-110519110956-phpapp02
54/54
Additional Resources
SlightlyLoony blog (Service-now.com developer) http://community.service-now.com/blog/slightlyloony
Wiki Script Portal http://wiki.service-now.com/index.php?title=Scripting_and_APIs
JavaScript book JavaScript The Definitive Guide (OReilly)
W3Schools script and HTML reference http://www.w3schools.com
Firebug http://getfirebug.com/