Applies to Infiniti v8.0 or later

 

Introduction

 
It is rare that Infiniti output is discarded or delivered via a manual process. Thus, at the core of Infiniti functionality is the ability to pass eForm data and generated documents to third party systems and data stores. In Infiniti Version 8 this concept has been taken to a new level with the development of Action Providers, replacing the Delivery and Submission Providers of earlier releases.
 
An Action Provider (generally referred to as an Action) supports an event such as: storing web form data in a database, delivering to a document management system (DMS), displaying an on screen message or sending an alert (e.g. email or SMS). Actions can be trigged at virtually any point along the web form/document generation process.
 
Infiniti is packaged with several Actions to handle the majority of common tasks. But for situations where Infiniti is to integrate with custom systems or support unique circumstances customized Actions can be developed to suit the business.
 
This document outlines characteristics and use of Actions together with how to develop and deploy custom Actions.
 
 

Actions, Features, and Characteristics

 
Actions are summarised in the points below
  • Actions are added and removed to Infiniti projects by dragging and dropping them onto a project’s question set in Design.
  • Individual Actions can process the data output by Infiniti and display customized user interfaces on screen, however an Action usually targets one or the other.
  • Actions are most commonly triggered upon the completion of a web form or document generation but can be called during a workflow process as well.
  • Multiple Actions of the same type can be added to a project, for example send two emails.
  • Actions can be conditioned so that they are only run when appropriate, for example send an email only if the user has indicated.
  • Actions can source attribute and settings dynamically from the question set, for example retrieve an email address from a data source.
  • Actions can be configured to handle error conditions, for example save to temporary store if a database is down.
  • Multiple actions run in a specific order.
  • Actions can output results to pending Actions, for example a ‘ticket number’ created by the first Action could be sent via email in another Action
 
 

Packaged Infiniti Actions

 
Infiniti is packaged with several Actions to cater for common scenarios listed below:
 
  • eMail
  • Maintenance of SQL Server and Oracle data stores
  • Delivery to the SharePoint and TRIM DMS’s
  • Delivery to network folders and Printers
  • On screen messaging, redirection and forwarding.
 
See the appropriate guides or articles for information on how to configure the individual Actions.
Action Provider Development Walkthrough
 
Action Providers, can be developed in house or by a third party to handle custom or unique situations when necessary. Custom Actions are developed as a module that is deployed to an existing Infiniti environment.
 
The walkthroughs below have been created using Microsoft’s Visual Studio 2010. All sample code is based version 4.0 of the C# language and version 4.0 of the .NET Framework.
 

How to Develop a ‘Hello World’ Action Provider

 
1.         Open Visual Studio and create a new Class Library Project and give it a meaningful name. For this example we will use ‘HelloWorldAction’. 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
  • System.Web
Infiniti References (usually located C:\inetpub\wwwroot\Infiniti\Produce\bin)
  • Intelledox.Action.dll
  • Intelledox.InfinitiProviderBase.dll
  • Intelledox.QAWizard.dll
  • Intelledox.QAWizard.Design.dll
  • Intelledox.Model.dll
 
5.         Inherit the Intelledox.Action.Provider and override necessary ActionProvider methods, as per the sample below.
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
​using System.IO;

namespace HelloWorldAction
{
    public class HelloWorld : Intelledox.Action.ActionProvider
    {
        public override Guid ActionTypeID()
        {
            throw new NotImplementedException();
        }
        public override bool SupportsRun()
        {
            throw new NotImplementedException();
        }
        public override bool SupportsUI()
        {
            throw new NotImplementedException();
        }
        public override Intelledox.QAWizard.ActionResult
            Run(Intelledox.QAWizard.ActionProperties properties)
        {
            throw new NotImplementedException();
        }
        public override System.Web.UI.WebControls.WebControl
            CustomUI(Intelledox.QAWizard.ActionProperties properties)
        {
            throw new NotImplementedException();
        }
    }
}
 
 
The project should build at this point without error.
 
6.         Code the ActionTypeID() method so that it returns a GUID to identify the Action.
public override Guid ActionTypeID()

{
    return new Guid("AA8CB0E3-71D9-4F52-9816-37E9EBE538B2");
}
 
 
7.         An individual Action can process the data it receives from Infiniti and/or return a UI. For this walkthough, the Action will concentrate on web form and generated document binary and not return a UI. Code the SupportsRun() and SupportsUI() as to behave as such.
 
public override bool SupportsRun()
{
    return true;
}
public override bool SupportsUI()
{
    return false;
}
 
It is best practice to code Action Providers so that they target the processing of the data provided by Infiniti or return a User Interface but not both.
 
8.         Add a constructor method to the class and call the ‘RegisterActionType()’ method to register the Action after it has been deployed.
 
public HelloWorld()
{
  base.RegisterActionType(ActionTypeID(), "Hello World Action", false);
}
 
9.         For this ‘HelloWorld’ Action we will use the Run() method to save the document binaries from the ‘properties’ input parameter and to disk. The ‘properties’ parameter is an ‘ActionProperties’ object and contains virtually all of the web form data and document binary.
 
The Run() method’s return type is an ‘ActionResult’ object containing success flags and messages and information to include in the Infiniti management logs.
Code the Run() method to perform a save to disk as follows.
 
public override Intelledox.QAWizard.ActionResult Run(Intelledox.QAWizard.ActionProperties properties)
        {
            {
                Intelledox.QAWizard.ActionResult result = new
                Intelledox.QAWizard.ActionResult();
                result.Result =
                    Intelledox.QAWizard.Design.ActionResultType.NotRun;

                try
                {
                    foreach (Intelledox.Model.Document doc in
                       properties.Documents)
                    {
                        string fileName = properties.JobGuid.ToString() + " - " +
                        doc.DisplayName + doc.Extension;

                        properties.GetDocumentStream(doc).CopyTo(new
                          FileStream(System.IO.Path.Combine("C:\\temp\\" +
                          fileName), FileMode.Create, FileAccess.Write));

                    }
                    result.Result =
                     Intelledox.QAWizard.Design.ActionResultType.Success;
                }
                catch (Exception ex)
                {
                    result.Result =
                       Intelledox.QAWizard.Design.ActionResultType.Fail;
                    properties.Wizard.Messages.Add(new
                       Intelledox.Model.Message(ex.Message,
                       Intelledox.Model.MessageLevel.Error));
                }
                return result;
            }
        }
 
 
10.     Build your Action to ensure it compiles without error. The Action can now be deployed and tested.
 
 

Deploying an Action

 
Actions are deployed to an Infiniti environment by copying the Action Provider .dll file to the Produce bin directory and referencing it within Produce’s web.config file.
 
1.         Locate your ‘HelloWorldAction.dll’ file and copy it to the Produce bin directory (usually located C:\inetpub\wwwroot\Infiniti\Produce\bin) and in the Infiniti Scheduler.
 
2.         Open the produce web.config file and locate the <action><providers> </action></providers> section of the file. It will most likely contain references to other Actions already.
 
3.         Add a new Action provider element using the following syntax to the web.config
 
<add name="name" type="namespace,class AssemblyName" />
<action>
  <providers>
    <add name="Email" type="Intelledox.Action.EmailAction, Intelledox.Action" />
    <add name="SQL Server" type="Intelledox.Action.SQLServerAction,
        Intelledox.Action" />
    <add name="Oracle" type="Intelledox.Action.OracleAction, Intelledox.Action" />
    <add name="Message" type="Intelledox.Action.DownloadPageMessageAction,
        Intelledox.Action" />
    <add name="Print" type="Intelledox.Action.PrintAction, Intelledox.Action" />
    <add name="Redirect" type="Intelledox.Action.RedirectAction,
        Intelledox.Action" />
    <add name="helloWorld" type="HelloWorldAction.HelloWorld,
        HelloWorldAction" />
  </providers>
</action>
 
 
4.         Save the web.config file.
 
5.         Navigate to Produce in your browser, an absence of error messages suggests the Action has installed correctly.
 
6.         Open an existing project in Infiniti Design and add the new Action to the question set.
 
 
7.         Save, publish and run the project to ensure it saves the file as expected.
 
 
 

Debugging Actions

 
After deploying an Action it can be debugged by attaching Visual Studio to the w3wp.exe process and triggering the Action from Produce.
 

Using Action Attributes

 
Most Actions 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. Action attributes allow the configuration such values in Design, so that they can be referenced within the code.
 
Using our example above we will add a ‘file path’ attribute to the Action that will replace the hardcoded c:\temp\ path in the code.
 
1.         Attributes are identified by a GUID, it is best practise to declare this GUID as a global variable.
 
public class HelloWorldAction : Intelledox.Action.ActionProvider
{
  Guid m_ActionAttribute_Path =
     new Guid("155A6E08-02AD-4804-9194-8E9292B45ADC");
  …
  …
}
 
2.         Register the Attribute in the constructor class
 
public class HelloWorldAction : Intelledox.Action.ActionProvider
{
  Guid m_ActionAttribute_Path =
     new Guid("155A6E08-02AD-4804-9194-8E9292B45ADC");

  public HelloWorldAction()
  {
    base.RegisterActionType(ActionTypeID(), "Hello World Action", false);
    base.RegisterActionAttribute(ActionTypeID(), m_ActionAttribute_Path,
      "Destination Folder Path", 1, true);
  }
…
…
}
 
3.         The attribute value can now be specified in Design, when the project has been reopened.
 
4.         The attribute value can be retrieved at runtime using the following code.
 
string path = null;
foreach (Intelledox.Model.RoutingOption option in properties.ActionInputs)
{
    if (option.ElementTypeId == m_ActionAttribute_Path)
    {
        path = option.OutputValue;
    }
    //else if (option.ElementTypeId == m_ActionAttribute_NextAttribute)
    //{
    //    blah = option.OutputValue;
    //}
}
 
 

Using Action Outputs

 
Some actions may want to return one or many values to Infiniti. For example if a reference number was produced after the creation of some sort of entity it could be returned to Infiniti and included onscreen, in an email, SMS etc.
 
The following example returns a random reference number.
 
1.         Output Attributes are identified by a GUID, it is best practise to declare this GUID as a global variable together with a meaningful name.
 
public class HelloWorld : Intelledox.Action.ActionProvider
{
const string REFNO = "Reference Number";

  Guid m_ActionOuputAttribute_RefNo =
     new Guid("1c65b2d0-b2f8-4bed-afb1-819c29333cf7");
  …
  …
}
 
 
2.         Register the Attribute in the constructor class
 
public class HelloWorldAction : Intelledox.Action.ActionProvider
{
  const string REFNO = "Reference Number";

  Guid m_ActionOuputAttribute_ReferenceNumber =
     new Guid("1c65b2d0-b2f8-4bed-afb1-819c29333cf7");

  public HelloWorldAction()
  {
    base.RegisterActionType(ActionTypeID(), "Hello World Action", false);
    base.RegisterActionAttribute(ActionTypeID(), m_ActionAttribute_Path,
      "Destination Folder Path", 1, true);
    base.RegisterActionOutput(ActionTypeID(),m_ActionOuputAttribute_RefNo,
      REFNO);
  }
…
…
}
 
3.         The output attribute value can now be seen and referred to in Design, when the project has been reopened.
 
 
4.         The output value can be set at runtime with the following sample code.
 
            
    List<Intelledox.Model.ActionOutput> outputs = new
                   List<Intelledox.Model.ActionOutput>();

                var r = new Random();
                int random = r.Next(1000);

                Intelledox.Model.ActionOutput passwordOutput = new
                  Intelledox.Model.ActionOutput();
                passwordOutput.ID = m_ActionOuputAttribute_RefNo;
                passwordOutput.Name = REFNO;
                passwordOutput.Value = random;
                outputs.Add(passwordOutput);
                result.Outputs = outputs;
 
 

Handling Concurrency

 
It is important to note Infiniti creates a single Action object at runtime and only local variables or global variables with constant values should be implemented. If multiple Actions are sharing a single global variable at runtime conflicts can occur.
 
 

Code Sample: 'Hello World' Action Provider

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace HelloWorldAction
{
    public class HelloWorld : Intelledox.Action.ActionProvider
    {

        const string REFNO = "Reference Number";

        Guid m_ActionOuputAttribute_RefNo %3
 

Related Articles

Keywords