LEGACY CONTENT
This article refers to legacy products, components or features. Therefore, the content in this article is offered "as is" and will no longer be updated. This content does not infer that the product, component or feature is supported, or that the product, component or feature will continue to function as described herein.

Introduction

Asynchronous Server Events provide a mechanism for stopping process flow to wait for an external application to programmatically finish the server event before process flow resumes. They behave similar to client events, the difference being that asynchronous server events expect “machine” input from an external system or application, whereas a client event expects “user” input in the form of one or more destination users executing an action against a worklist item associated with the client event.
In order to accomplish this in K2 Five (5.1) or later and K2 Cloud, see How To: Configure and use the "Wait for External System" option in a workflow.

Configure the Asynchronous Server Event

  1. Configure the Destination Rule

    Asynchronous server events are typically used where process flow needs to be stopped then resumed programmatically at a later time based on some event external to K2, rather than being completed interactively by an end user. Since this scenario does not require destination users, the destination rule for the activity containing the server event should be configured to use the ‘Plan per slot (no destinations)’ option.

    To access the Destination Rule Options screen to specify how the activity will be planned, the destination rule wizard must be run in Advanced Mode as follows:
    1. Run the destination rule wizard for the activity where the asynchronous server event will reside
    2. Click the Back button
    3. Check the ‘Run this wizard in Advance Mode’ checkbox and click Next
    4. At the first Destination Rule Options screen select the ‘Plan per slot (no destinations)’ option:
    5. Click Next
    6. At the second Destination Rule Options screen, keep the default option of ‘Select the number of slots to be created’.
    7. Enter the desired number of slots and click Finish to complete the wizard:
    The use of multiple slots and how they will affect the process is discussed later in this article. The ‘Initialization Data (Optional)’ is used for IPC Events and can be left blank.

  2. Configure the Server Event

    Add a ‘Default Server Event (Code)’ to the activity that was configured in step 1 above. By default, the server event will be synchronous and the code behind the event must be changed to make it asynchronous. To access the code:
    1. Right-click on the server event
    2. Select View Code -> Event Item
    3. Add the following line to the Main() method to make the server event asynchronous:

      K2.Synchronous = false;

      The code should look similar to the following example:
    Note the additional line of code that saves the server event SerialNumber to a process data field. When a process instance encounters an asynchronous server event it will execute the event, create a ServerItem with a unique serial number for each slot configured in the destination, then wait for the ServerItem(s) to be completed programmatically before process flow continues. This is similar to a client event that creates worklist items; however, since there is no human interface for accessing a ServerItem, such as a worklist, the ServerItem must be completed programmatically using the serial number.

    Thus it is important to capture and save the serial number so it is accessible by the application that must complete the ServerItem. One option, as shown in the above example, is to save the serial number to process data field, then retrieve it later by opening the process instance using the process instance ID. The SourceCode.Workspace.Management namespace can be used to search for a specific process instance and obtain the ID if it is not known.

    Alternately the serial number could be saved to an external database or passed to the application that will call back into K2 to finish the ServerItem at a later time, when appropriate.

    The important point is that a strategy is needed for saving and retrieving the serial number as it is not possible to search for ServerItems using the K2 API’s.

  3. Configure the Succeeding Rule

    If the destination rule is configured to use multiple slots and process flow must not resume until 2 or more slots are completed, the succeeding rule must be configured accordingly. By default the succeeding rule will evaluate to true when the first slot (ActivityInstanceDestination) is completed. The succeeding rule can be configured to complete the activity when a specified number of slots are completed, or in this example, when all slots are completed:

    When using multiple slots, a ServerItem with a unique serial number will be created for each slot. If the succeeding rule is configured to finish the activity when all slots are completed, each ServerItem must be finished using its unique serial number so it is necessary to keep track of the serial number associated with each slot.

 

Assign Server Event Process Rights

The SourceCode.Workflow.Client namespace is used to programmatically finish a ServerItem. The user that opens the client connection and authenticates against the K2 Workflow Server must have Server Event Process Rights to call the ServerItem.Finish() method. To assign Server Event Process Rights, in Workspace Management Console:

  1. Expand the appropriate K2 server node
  2. Expand the Workflow Server -> Processes node
  3. Expand the desired project -> process and select the Process Rights node
  4. Add the users and/or groups that will need to finish the ServerItem giving them ‘Server Event’ rights

 

Finish the ServerItem(s)


The ServerItem class of the SourceCode.Workflow.Client namespace is used to finish the ServerItem. It simply involves opening and finishing the ServerItem based on its unique serial number as shown in the following C# console application example below. A reference to the SourceCode.Workflow.Client.dll and SourceCode.HostClientAPI.dll assemblies must be added to the project.


using System;
using System.Collections.Generic;

using System.Text;
using SourceCode.Workflow.Client;
using SourceCode.Hosting.Client.BaseAPI;

namespace FinishServerItemCSharp
{
    class Program
    {
        static void Main(string[] args)
        {

            //Replace with appropriate environment values
            string _serverName = "blackpearl";
            //User must have Server Process Rights
            string _user = "Administrator";
            string _domain = "k2demo";
            string _password = "k2pass";
            //Assumes the process instance ID is known
            int processInstanceID = 142;

            //Build a connection string object
            SCConnectionStringBuilder connectionString = new SCConnectionStringBuilder();
            connectionString.Authenticate = true;
            connectionString.Host = _serverName;
            connectionString.Integrated = true;
            connectionString.IsPrimaryLogin = true;
            connectionString.Port = 5252;
            connectionString.UserID = _user;
            connectionString.WindowsDomain = _domain;
            connectionString.Password = _password;
            connectionString.SecurityLabelName = "K2";

            //Open a connection to K2
            Connection connection = new Connection();
            connection.Open(_serverName, connectionString.ToString());

            //Retrieve the process instance and ServerItem serial number
            ProcessInstance processInstance = connection.OpenProcessInstance(processInstanceID);
            String serialNumber = processInstance.DataFields["SerialNumber"].Value.ToString();

            //Open and complete the ServerItem
            ServerItem serverItem = connection.OpenServerItem(serialNumber);
            serverItem.Finish();

            connection.Close();

        }
    }
}

 

In this example there is only one slot being used and the serial number is being saved to a process data field and obtained by opening the process instance. When the ServerItem is finished, the succeeding rule evaluates to true and the activity containing the Asynchronous Sever Event is complete.