19l04-roberts-advanced scripting and debugging

Upload: antonio-vegue

Post on 06-Apr-2018

221 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    1/56

    Advanced Scripting &

    Debugging Lab

    John RobertsApplication Developer

    ServiceNow

    Jerrod BennettSenior Technical Consultant

    ServiceNow

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    2/56

    Place holder for instanceinformation

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    3/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    4/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    5/56

    Overview

    Setup Lab instance Script source - http://wiki.service-now.com/index.php?

    title=Script_Lab

    Optional Install Firefox and Firebug

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    6/56

    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

    var myName = john;

    function doThis() {var myName = roberts;

    }

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    7/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    8/56

    Scripting Concepts (quick review)

    Try/Catch blocks for proper error handling Errors will halt script unless handled

    try {

    //something

    }

    catch (err) {

    gs.log(ERROR: + err);

    }

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    9/56

    Debugging Concepts

    Know what should happen

    Identify what is happening

    Did my script run, were there errors

    Do I have the expected results

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    10/56

    Debugging Tools

    Application System Diagnostics / Session Debug modules Information output options

    Browser Developer Tools Add-ons such as Firebug

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    11/56

    Debugging Examples

    Exercise 1Business Rule Debug

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    12/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    13/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    14/56

    Exercise 1 Debug Business Rule

    Identifying whether a business rule was executed Run the Debug Business Rules module to enable business rule

    debugging

    Just the Debug Business Rule, no jumping ahead to (Details) yet

    Open anotherexisting incident and set incident state to closed,save

    Scroll down to see debug output and notice the followingSkipping 'k11 Exercise 1 - Incident Close Comment' on table incident; condition not satisfied:

    current.incident_state.changesTo("Closed")

    From the debug output click on the business rule name to open it

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    15/56

    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 infogs.addInfoMessage("(InfoMessage) Incident state = "+ current.incident_state);//output to appgs.log("(Log) Incident state = "+ current.incident_state);//output to system loggs.print("(debug print) Incident state = "+ current.incident_state);//output to debug console

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    16/56

    Exercise 1 Debug Business Rule

    Open anotherexisting 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 = 7

    13:50:23.718: : (debug print) Incident state = 7

    13:50:23.719:

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    17/56

    Exercise 1 Debug Business Rule

    Perform one more test to verify If we suspected the field value was wrong we could have taken a

    shortcut

    From a closed incident form, use the header context menu Show XML to displayall fields and values

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    18/56

    Debugging Examples

    Exercise 2Debug Business Rule Changes

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    19/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    20/56

    Debugging Examples

    Exercise 3Try Catch

    Line by line evaluation

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    21/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    22/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    23/56

    Exercise 3 Error Handling

    Enable both Debug Business Rule and Debug Log modules Create another software incident and view the debug output Notice that we have a script exception because we have an extra r

    in current

    ==> 'k11 Exercise 3 - Display Info' on table incident

    Evaluator: org.mozilla.javascript.EcmaError: "currrent" is not defined. Caused by error in Business Rule: 'k11Exercise 3 - Display Info' at line 5 2: gs.addInfoMessage("Current number: " + current.number); 3: 4: //output

    current short_description ==> 5: gs.addInfoMessage("Current Short Description: " +currrent.short_description); 6: 7: //output current category 8: gs.addInfoMessage("Current Category: " +current.category);

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    24/56

    Exercise 3 Error Handling

    Add a try catch block around our statements and save the businessrule

    try {//output current numbergs.addInfoMessage("Current number: "+ current.number);

    //output current short_descriptiongs.addInfoMessage("Current Short Description: "+ currrent.short_description);//output current categorygs.addInfoMessage("Current Category: "+ current.category);

    }catch(err) {

    //catch only runs on exception in try block//err object is passed from the try handler and includesgs.log("Error in k11 Exercise 3 business rule: "+ err);

    }

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    25/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    26/56

    Debugging Examples

    Exercise 4Client Script

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    27/56

    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 low

    for 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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    28/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    29/56

    Exercise 4 Client Script

    Change the category to request to execute the script again Firebug breakpoints can be funny at times, refresh the form script

    does not stop at breakpoint

    Review all the information available during the break You can also step through code using the yellow arrows

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    30/56

    Debugging Examples

    Exercise 5Javascript Executor

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    31/56

    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 thejavascript 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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    32/56

    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 executorand 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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    33/56

    Debugging Examples

    Exercise 6Background Scripts

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    34/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    35/56

    Exercise 6 Background Scripts

    Try it Lets build a script to disable some users Launch the background script module Enter the following script

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    36/56

    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 upload

    module

    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 it

    does anything harmful

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    37/56

    Debugging Examples

    Exercise 7Extending Script Includes

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    38/56

    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 listfor (var i=0; i < tables.size(); i++) {gs.print(tables.get(i));}//enumerate javascript arrayfor (var i=0; i < tableArray.length; i++) {gs.print(tableArray[i]);}

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    39/56

    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 arrayvar tables = util.getTables();gs.print("Java list: "+ tables);//what is the tables object

    JSUtil.logObject(tables, "tables");//enumerate java array listfor (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

    *** Script: Java list: [cmdb_ci_server,cmdb_ci_computer, cmdb_ci_hardware,

    cmdb_ci]*** Script: Log Object: tables

    Java Object:com.glide.util.ImmutableArrayList*** Script: cmdb_ci_server

    *** Script: cmdb_ci_computer*** Script: cmdb_ci_hardware

    *** Script: cmdb_ci

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    40/56

    Exercise 7 Extending Script Includes

    Try it Lets first look at the TableUtils script includeinitialize: function(tableName){

    this.tableName = tableName;},,getTables: function(){

    var tables = Packages.com.glide.db.DBObjectManager.get().getTables(this.tableName); return tables;},

    Theres another script include we can use to convert java objects tojavascript, thats j2js

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    41/56

    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 we

    can 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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    42/56

    Exercise 7 Extending Script Includes

    Return to background scripts and call the new classvar util =new MyTableUtils("cmdb_ci_server");//call our new methodvar 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 objectJSUtil.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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    43/56

    Debugging Examples

    Exercise 8AJAX Debugging

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    44/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    45/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    46/56

    Exercise 8 AJAX

    Try it From the development laptop catalog item page start the javascript executor

    Run the following script to make an AJAX requestvar gajax =new GlideAjax("CapacityCheckAjax");gajax.addParam("sysparm_name", "checkDevCapacity");gajax.getXML(ajaxResponse);function ajaxResponse(serverResponse) {

    alert(serverResponse.responseText);}

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    47/56

    Debugging Examples

    Exercise 9Jelly

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    48/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    49/56

    Exercise 9 Jelly

    Try it Review UI page k11_test Notice thej: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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    50/56

    Debugging Examples

    Exercise 10Display Business Rules

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    51/56

    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 ruleand getting values on the client

    Display rules can also change field data, similar to calculated fieldssince they display the new value but its not written to the database

    until you save the record

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    52/56

    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 scratchpadg_scratchpad.created_by = current.sys_created_by;//calculate the age of this recordvar 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 tablefunction onLoad() {

    //get data from display rule scratchpadvar 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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    53/56

    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/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    54/56

    Q & A

    j_roberts

    #know11

    #servicenow

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    55/56

    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/

  • 8/3/2019 19L04-Roberts-Advanced Scripting and Debugging

    56/56

    SESSION EVALUATION

    Complete the session

    evaluation on the

    Knowledge11 Portal

    Text us at 22333 with

    19L04 A text

    19L04 B text

    19L04 C text

    space is

    important

    comments

    are optional

    take survey

    Case is not

    important