The Zurich release has arrived! Interested in new features and functionalities? Click here for more

edwajs
ServiceNow Employee
ServiceNow Employee

When working with Service Level Agreements, you may run into situations where you have a business requirement which is not met by the base functionality of the 2011 SLA Engine.   In this blog post I will show you how to achieve a desired functionality that is not possible with the base code. We'll satisfy a specific use case with a targeted/focused manner which will allow you to receive fixes and improvements to the base code, while at the same time, protecting your modifications.

Here are your options to proceed:

  1. Change the requirements so they can be met with the base functionality.
  2. Use bolt-on business rules and other scripts to manipulate the data outside the engine to get the desired results
  3. Modify the base code so it provides the desired functionality

The problem with the third option is you will no longer get updates to the base code, because our upgrade process protects your customizations.   The correct method for implementing these changes is to create a script include to extend a base class, and create override functions only where needed to alter the functionality.   This allows you to receive updates to the base code, but protects your changes.

In this post I am going to review a possible set of business requirements, discuss some design considerations, review the pros and cons for the using the base code, and provide an example of changing SLA function by providing overrides to base code, specifically TaskSLAController.

Design Considerations:

Let's address the following business requirements:

  1. An organization has a number of groups for incident assignment.
  2. Any incident may be assigned or re-assigned back and forth between groups while it is being worked.
  3. The organization needs to track the amount of time the incident is assigned to each group.

If the requirement is only to measure the time spent in each different assignment group, the most efficient way to gather the data is going to be with metrics. The Metric plugin provides an easy way of defining metrics. When the metrics are defined, the data will be gathered, and instances of the metric will be calculated and stored to give you a better idea of incident handling.

Assume your organization is determined to implement these requirements as Service Level Agreements.   One possible way to implement this is using the base 2011 SLA engine without any modifications:

  • Create an SLA definition for each assignment group.
  • The Start condition needs to include each assignment_group.
  • Whenever the assignment_group changes, the existing SLA will be cancelled and a new SLA will be attached.

Advantages of this approach are:

  • It does not require modifications to the SLA Engine.
  • Reporting is based on the SLA Definitions referenced in the task_sla data.

Some drawbacks of this approach are:

  • There are multiple task_sla records for the same assignment group if the incident is reassigned back and forth frequently in its life cycle.
  • The more groups you have, the more SLA Definitions you need.
    • A large number of SLA definitions is a maintenance issue.
    • A large number of SLA definitions on any particular table can have an adverse impact on performance.   Every associated insert/update of an incident requires the evaluation of each SLA definition, even though most of them do not apply.
  • It is not possible to pause the task_sla records for a group if the assignment changes to a different group, and then unpause them and continue if the assignment changes back.   This is because of the need to code the assignment group in the Start condition.   The SLA will always be cancelled when the assignment group changes, as documented here.

With a relatively minor set of customizations (a few simple business rules, a custom field on task_sla, a custom field on task) you can meet the above reporting requirements with a single SLA definition using a Reset condition.   This approach avoids the drawbacks due to large numbers of SLA definitions, but again, you cannot do the pause/unpause operation.   The individual SLAs will not be cancelled, however, because a Reset will cause the running SLA to be completed instead.

Refined Requirements:

Because of the disadvantages listed above, the requirements can be further refined.

  1. One task_sla record needs to be created for each assignment_group ever assigned to the incident.
  2. The task_sla record should be paused whenever the current task is not assigned to that group.
  3. No other SLA Definitions are impacted by the special processing required for these task_sla records.

These requirements cannot be met by the base 2011 SLA Engine, because changes of the assignment group will result in records being cancelled (or completed), not paused.   Also, it is not possible to have one SLA definition associated to more than one active task_sla record because the base code detects the active record and prevents another from being attached.

At this point, we can look at using bolt-on business rules and other scripts to manipulate the data outside the engine.   It would make the most sense to look into the possibility of doing the minor customization described above so you could have a single SLA definition, and then combine it with business rules on task_sla.   At any given time, only one of the records for any assignment group would be active, all the others would be marked Completed.   If it was assigned back to a group, the custom logic would need to find the existing Completed task_sla for that group, and find a way to merge it into the new record.   There are several complexities to this merge, and it still is not possible to have the records Paused.

With these refined requirements, it becomes necessary to create changes to apply to base processing.   Here is an example of implementing these requirements using script includes to extend the base TaskSLAController script include and providing overrides to specific functions.

Example:

1.   Add a custom string field to contract_sla, called u_special_processing_type, and provide a choice for it with value 'special' and label 'Special'.

dictionary entry SLA.jpg

2.   Add a custom reference field for sys_user_group to task_sla, called u_assignment_group, to track the assignment_group for the task_sla record.

dictionary entry assignment sla.jpg

3.   Add a 'before-insert' business rule to task_sla called 'Populate Assignment Group'

  • For Filter Conditions, make it SLA definition.Special processing type is Special.
  • For the script, make it:

function onBefore(current, previous) {

  current.u_assignment_group = current.task.assignment_group;

}

SLA override task.jpg

4.   Create a custom script include to extend TaskSLAController called TaskSLAControllerMagic containing:

  • One new function, queryMostTaskSLAs(), used as an alternative when building a filter of already-attached SLA Definitions, so we do not exclude our special processing SLA definitions.   Note: queryTaskSLAs() needs to be present and unmodified for proper evaluation of task_sla records once they are attached.
  • A modified version of function _processNewSLAs_criticalSection(), with one line of code changed so the query of active SLAs uses queryMostTaskSLAs() instead of queryTaskSLAs().
  • A modified version of function _checkNewSLA(), with a block of code after attach() condition processing to determine if one of these task_sla records already exists for the assignment group; if it was not attached yet, it will attach another task_sla for this contract_sla but for this assignment_group.
  • A modified version of function _pauseUnpause(), which includes an additional check after pause() condition processing to see if this is a special processing SLA and if the task assignment_group does not match the task_sla assignment_group, to ensure the pause.

Screen Shot 2016-04-12 at 3.14.45 PM.png

Screen Shot 2016-04-12 at 3.23.37 PM.png

Screen Shot 2016-04-12 at 3.26.39 PM.png

Screen Shot 2016-04-12 at 3.28.57 PM.png

5.   Change the 'Run SLAs' business rule script to call TaskSLAControllerMagic(), instead of TaskSLAController().

run sla business script.jpg

6.   Finally, create a new SLA Definition for Table is Incident:

  • Name:   Test Assignment
  • Process type:   Special
  • Start Condition:   Active is true
  • Stop Condition:   Active is false
  • Pause Condition:   Incident State is one of Awaiting Problem/Awaiting User Info/Awaiting Evidence/Resolved.
  • User Duration:   1 (24 hour) day

After you complete the example set-up, you can test it and verify it produces the task_sla records as expected by following these steps:

  1. Create a new P1 incident, but leave the assignment_group empty; you will get one P1 task_sla.
  2. Set the assignment_group to Network and Save; you will get one of the new Test Assignment SLAs for Network.
  3. Change the assignment_group to Service Desk and Save; the Test Assignment SLA for Network will be Paused, and you will get a new Test Assignment SLA for Service Desk.
  4. Clear out the assignment_group and Save; both of the Test Assignment SLAs will be Paused.
  5. Change the assignment_group to Software and Save; you will get one more In Progress Test Assignment SLA for Software.
  6. Now resolve the incident and save it; all of the Test Assignment SLAs will be Paused.
  7. Close the incident, and all of the SLAs will be Completed.

If you follow these recommendations, you will be able to satisfy Service Level Agreement requirements that could not be met using base functionality.   We discussed different methods of achieving the requirements and I provided you with an example of one method of achieving these requirements.   The advantage of this method is you achieve the desired functionality not possible with the base code.   However, it is done in a targeted/focused manner which allows you to receive fixes and improvements to the base code while at the same time protecting your modifications.

1 Comment