Applies to Infiniti v8.1 or later
 
 
The escalations functionality is disabled by default. To enable this functionality, the Infiniti Scheduler needs to be installed on the web server which hosts your Infiniti instance.
Please setup the following before continuing with this article:
  1. Install the Infiniti Scheduler and
  2. Setup the project definition (A scheduled task that you setup in manage for your project).
This article will help provide further info on the initial setup: http://ixsupport.intelledox.com/kb/a404/scheduler-install-and-uninstall-commands.aspx
 

Introduction

 
There may be occasions where actions need to occur if an in-progress Infiniti workflow has been left idle for too long. For example, if a particular form hasn’t been completed within a week, then an email might be sent to the person who initiated the process. These “actions that occur at a later time” are referred to as Escalations.
 
Infiniti includes some Escalation Providers by default: emailing a notification to a relevant party, reassigning the item to someone more appropriate, or push notifications (for the Infiniti apps).
In the case that a different system needs to be notified or a more customised approach used, then an Escalation Provider can be built to handle the situation.
 
The Infiniti Scheduler must be configured and running in order to use Escalations.

Escalation Features and Characteristics

 
Escalations are summarised in the points below
  • Escalations are defined on the workflow page in Design. Add them to the workflow state for which an Escalation should occur after a given amount of time.
  • An Escalation can first execute a certain time after the workflow reaches the particular state, or it may execute on a specified date.
  • Multiple Escalations of the same type may be added to a workflow state. For example, an email may be sent to the person who needs to do the work, and also another email to their manager.
  • Escalations can be conditioned so that they are only run when appropriate, for example, send an email earlier if the details on the form deem it more urgent.
  • Escalations can source attribute and settings dynamically from the question set, for example, retrieve an email address from a data source.
  • Once an Escalation has executed for the first time, it may be configured to execute over and over again for a defined period. For example, send an email every day for two weeks.
See the appropriate guides or articles for information on how to configure in-built Escalations.

Escalation Provider Development Walkthrough

 
Escalation Providers can be developed in house or by a third party to handle custom or unique situations when necessary. Custom Escalations are developed as a module that is deployed to an existing Infiniti environment.
This walkthrough will show how to create a “Hello World” Escalation Provider – in this case it will write a line in a text file on the server whenever the Escalation triggers.
 
The walkthroughs below have been created using Microsoft’s Visual Studio 2015. All sample code is based version 5.0 of the C# language and version 4.5.1 of the .NET Framework.

 

How to Develop a ‘Hello World’ Escalation Provider

1 Open Visual Studio and create a new Class Library Project and give it a meaningful name. For this example, we will use ‘HelloWorldEscalation’. Ensure that the .NET Framework 4.5.1 is selected.
 
 
2 Rename Class1 to something more meaningful such as ‘HelloWorld’.
 
 
3 Click ‘Yes’ to the rename all references prompt.
 
 
 
4 Add the following references to the project
 
.NET References:
  • System.Configuration
Infiniti References (usually located C:\inetpub\wwwroot\Infiniti\Produce\bin)
  • Intelledox.Escalation.dll
  • Intelledox.InfinitiProviderBase.dll
  • Intelledox.Model.dll
  • Intelledox.QAWizard.dll
 
 
5. Inherit the Intelledox.Escalation.EscalationProvider and override necessary EscalationProvider methods, as per the sample below. using System;
 
namespace HelloWorldEscalationProvider
{
    public class HelloWorld : Intelledox.Escalation.EscalationProvider
    {
        public override Guid EscalationTypeID()
        {
            throw new NotImplementedException();
        }

        public override void Run(Intelledox.QAWizard.EscalationProperties properties)
        {
            throw new NotImplementedException();
        }

        public override bool SupportsRecurring()
        {
            throw new NotImplementedException();
        }
    }
}
 
The project should build at this point without error.
 
If you are building an Escalation for a version of Infiniti earlier than 9.6.8, you may need to override a SupportsUI function as well. Simply return false from that function and everything will run as expected.
 
6. Code the EscalationTypeID() method so that it returns a GUID to identify the Escalation.
 
public override Guid EscalationTypeID()
{
    return new Guid("B320D67B-9DA5-4D67-84F8-ACFC6BB3BD3D");
}
7. The SupportsRecurring() method defines whether or not this Escalation can run multiple times for a particular project. As we’re just writing a line in a file, there’s no reason why this can’t run repeatedly, so return true.
 
public override bool SupportsRecurring()
{
    return true;
}
 
The Reassignment Escalation is an example of an Escalation which doesn’t support recurring – once the project has been assigned to somebody else, it can’t be reassigned to them again.
 
8. Add a constructor method to the class and call the ‘RegisterEscalationType()’ method to register the Escalation with Infiniti after it has been deployed.
 
public HelloWorld()
{
  base.RegisterEscalationType(EscalationTypeID(), "Hello World Escalation");
}
 
9. The Run() method defines what happens when the Escalation executes.
 
For this example, the method is going to write “Hello World” and a timestamp to a file on the server.
 
public override void Run(Intelledox.QAWizard.EscalationProperties properties)
{
    using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\HelloWorld.txt", true))
    {
        file.WriteLine(DateTime.Now);
    }
}
 
The directory the file is located in may need to change depending on the permissions on your server. The Infiniti Scheduler must have permission to write to the location specified, otherwise the Escalation will fail.
 
10. Build your Escalation to ensure it compiles without error.
 
The Escalation can now be deployed and tested.

Deploying an Escalation

Escalations are deployed to an Infiniti environment by copying the Escalation Provider .dll file to the Produce bin directory, the scheduler’s directory and referencing it within Produce’s web.config file.
 
1. Locate your ‘HelloWorldEscalation.dll’ file and copy it to the Produce bin directory
(usually located C:\inetpub\wwwroot\Infiniti\Produce\bin)

and the scheduler directory
(usually located C:\inetpub\wwwroot\Infiniti\IntelledoxScheduler).
 
2. Open the Produce web.config file and locate the section of the file. It will most likely contain references to other Escalations already.
 
3. Add a new Escalation provider element using the following syntax to the web.config.
 
<add name="name" type="namespace,class AssemblyName">
<escalation> 
    <providers> 
        <add name="Email" type="Intelledox.Escalation.EmailEscalation, Intelledox.Escalation"> 
        <add name="Reassignment" type="Intelledox.Escalation.ReassignmentEscalation, Intelledox.Escalation"> 
        <add name="Hello World" type="HelloWorldEscalationProvider.HelloWorld, HelloWorldEscalation"> 
    </providers> 
</escalation> 
 
4. Save the web.config file.
 
5. Navigate to Produce in your browser, an absence of error messages suggests the Escalation has installed correctly.
 
6. Open the config file for the scheduler (IntelledoxScheduler.exe.config) and add the same line to the section there too.
 
7. Open an existing project in Infiniti Design and add the new Escalation to a workflow state.
 
8. Escalations are a little tricky to test as they are designed to run at a later date. The suggested method for testing is as follows.
  • Run the project up to the state that has the Escalation.
  • Open the Workflow_Escalation table in the Infiniti database. This table contains all the escalations for current workflow states in your system.
  • Find the particular row that represents the Escalation to be tested (either use the EscalateOnUtc date or match it via ActionListStateId to the ActionListState table).
  • Edit the EscalateOnUtc date for the appropriate row in the table and set it to be in the past.
  • Run the scheduler. This can be done by using the RunImmediate command found in the scheduler’s folder.

Debugging Escalations

After deploying an Escalation it can be debugged by setting your project to execute the scheduler on debug.
 
9. Open the Properties window for the HelloWorldEscalation project. One way this can be done by right clicking on the project file in the Solution Explorer and selecting properties.
 
10. Select “Debug”.
 
11. Set “Start Action” to “Start external program”
 
12. In the external program box, enter IntelledoxScheduler.exe found in the scheduler directory.
 
13. In the “Command line arguments”, put “- console”
 
 
 
14. Start debugging and any breakpoints you set should be hit.
 

Using Escalation Attributes

Most Escalations will require some sort of input to behave as intended each time it is run. For example, if an email is to be sent the recipient would most likely be sourced from the web form or a data source. Escalation attributes allow the configuration of such values in Design, so that they can be referenced by the Provider.
 
Using our example above we will add a ‘file path’ attribute to the Escalation that will replace the hardcoded c:\ in the code.
 
1. Attributes are identified by a GUID; it is best practice to declare this GUID as a global variable.
 
public class HelloWorld : Intelledox.Escalation.EscalationProvider
{
    Guid m_Attribute_Path = new Guid("FEBF59AD-5873-4D57-8BA2-A3751F7FB127");  
  …
  …
}
2. Register the Attribute in the constructor class
 
public class HelloWorld : Intelledox.Escalation.EscalationProvider
{
    Guid m_Attribute_Path = new Guid("FEBF59AD-5873-4D57-8BA2-A3751F7FB127");

    public HelloWorld()
    {
        base.RegisterEscalationType(EscalationTypeID(), "Hello World Escalation");
        base.RegisterEscalationAttribute(EscalationTypeID(), m_Attribute_Path, "Log Path", 1, true);
    }
…
…
}
 
3. The attribute value can now be specified in Design, when the project has been reopened.
 
4. The attribute value is passed to the Provider via the EscalationProperties parameter of the Run() method. Any attribute values for an instance of the Escalation will be found in the EscalationInputs property of that parameter.
 
To get a value, loop through the EscalationInputs and check for one with an ElementTypeId equal to the Guid defined for this attribute. The OutputValue of that object is the value of that attribute in your current Escalation.
 
It will almost always look similar to the following code snippet.
 
public override void Run(Intelledox.QAWizard.EscalationProperties properties)
{
    string path = null;
    foreach (Intelledox.Model.RoutingOption option in properties.EscalationInputs)
    {
        if (option.ElementTypeId == m_Attribute_Path)
        {
            path = option.OutputValue;
        }
        //else if (option.ElementTypeId == m_Attribute_NextAttribute)
        //{
        //    blah = option.OutputValue;
        //}
    }
  …
  …
5. Once read from the EscalationInputs collection, the attribute can be used as intended.
 
public override void Run(Intelledox.QAWizard.EscalationProperties properties)
{
    string path = null;
    foreach (Intelledox.Model.RoutingOption option in properties.EscalationInputs)
    {
        if (option.ElementTypeId == m_Attribute_Path)
        {
            path = option.OutputValue;
        }
        //else if (option.ElementTypeId == m_Attribute_NextAttribute)
        //{
        //    blah = option.OutputValue;
        //}
    }

    if (String.IsNullOrEmpty(path))
    {
        throw new ApplicationException("No output folder. Check escalation properties in Design.");
    }

    //Check if we should create the folder
    if (!System.IO.Directory.Exists(path))
    {
        System.IO.Directory.CreateDirectory(path);
    }

    using (System.IO.StreamWriter file = new System.IO.StreamWriter(System.IO.Path.Combine(path, "HelloWorld.txt"), true))
    {
        file.WriteLine(DateTime.Now);
    }
}

 

Handling Concurrency

It is important to note Infiniti creates a single Escalation object at runtime and only local variables or global variables with constant values should be implemented. If multiple Escalations are sharing a single global variable at runtime conflicts can occur.
 
Code Sample: ‘Hello World’ Escalation Provider Sample Code
 
using System;

namespace HelloWorldEscalationProvider
{
    public class HelloWorld : Intelledox.Escalation.EscalationProvider
    {
        Guid m_Attribute_Path = new Guid("FEBF59AD-5873-4D57-8BA2-A3751F7FB127");

        public HelloWorld()
        {
            base.RegisterEscalationType(EscalationTypeID(), "Hello World Escalation");
            base.RegisterEscalationAttribute(EscalationTypeID(), m_Attribute_Path, "Log Path", 1, true);
        }

        public override Guid EscalationTypeID()
        {
            return new Guid("B320D67B-9DA5-4D67-84F8-ACFC6BB3BD3D");
        }

        public override void Run(Intelledox.QAWizard.EscalationProperties properties)
        {
            string path = null;
            foreach (Intelledox.Model.RoutingOption option in properties.EscalationInputs)
            {
                if (option.ElementTypeId == m_Attribute_Path)
                {
                    path = option.OutputValue;
                }
                //else if (option.ElementTypeId == m_Attribute_NextAttribute)
                //{
                //    blah = option.OutputValue;
                //}
            }

            if (String.IsNullOrEmpty(path))
            {
                throw new ApplicationException("No output folder. Check escalation properties in Design.");
            }

            //Check if we should create the folder
            if (!System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }

            using (System.IO.StreamWriter file = new System.IO.StreamWriter(System.IO.Path.Combine(path, "HelloWorld.txt"), true))
            {
                file.WriteLine(DateTime.Now);
            }
        }

        public override bool SupportsRecurring()
        {
            return true;
        }
    }
}

 

Types of escalations

 

Related Articles

 

Keywords

escalate