Skip to main content

Exploring the Workflow Sample

This appendix presents an sample that you can find in the package Demo.Workflow in the ENSDEMO namespace. So that you can more easily work with this sample, the appendix also includes some setup information and suggestions on points of interest. This appendix includes the following sections:

Overview of the Sample

The Demo.Workflow sample includes a business process called Demo.Workflow.HelpDeskOpens in a new tab. This accepts an incoming request that contains the basic information required for a problem report; that is, the name of the sender and a description of the problem. On receiving this request for action, HelpDesk begins a sequence of actions that continues until one of these actions resolves the problem.

HelpDesk first sends the problem report, as a task, to the development group. When a member of this group reports that the problem was solved, HelpDesk adds a note to the problem report and sends it, as a task, to the testing group. When a member of this group reports that the repairs were satisfactory, HelpDesk sends a final response to its caller, with a flag indicating that the reported problem was resolved.

Setup Tasks

To set up and work with this sample, do the following:

  1. Create several users as described in “Users” in the Caché Security Administration Guide.

  2. Configure each of these users as a workflow user, as described in “Managing Workflow Roles, Users, and Tasks” in Managing Ensemble.

  3. In the ENSDEMO namespace, start the production Demo.Workflow.ProductionOpens in a new tab.

    When you do so, Ensemble creates two workflow roles: Demo-Development and Demo-Testing. (It creates these roles because the Auto Create Role setting is enabled for the two workflow operations in the production.)

  4. Assign the workflow users to these workflow roles, as described in “Managing Workflow Roles, Users, and Tasks” in Managing Ensemble.

    Some users can be in both roles.

  5. Use the Ensemble,Testing Service page to send a few messages to HelpDesk:

    1. Click Ensemble, then click Testing, then click Business Hosts.

    2. For Target Type, click Business Process.

    3. For Target Name, click HelpDesk.

    4. Click Test.

    5. Type suitable values into the ReportedBy and Problem fields.

    6. Click Invoke Testing Service.

    Send several messages to make the scenario interesting.

  6. Log into the DeepSee User Portal as each of the users and use the Workflow Inbox to manage the tasks.

    First log in as a user in the Demo-Development role and mark some tasks as complete; this generates additional testing tasks. Then log in as a user in the Demo-Testing role and mark the testing tasks complete.

    Tip:

    You might need to configure the /csp/ensdemo web application so that it accepts password authentication but does not accept unauthenticated access. For details, see in “Applications” in the Caché Security Administration Guide.

Sample Request Message

The following request message class defines the request message that comes into the HelpDesk sample business process. It represents a technical problem submitted by a customer. The request message class definition is as follows:

Class Demo.Workflow.ProblemReport
{
/// Name of customer reporting the problem.
Property ReportedBy As %String(MAXLEN = 60);

/// Description of the problem.
Property Problem As %String(MAXLEN = 200);
}

Sample Business Process Class

On receiving a Demo.Workflow.ProblemReportOpens in a new tab request message, the sample BPL business process Demo.Workflow.HelpDeskOpens in a new tab begins a sequence of actions that continues until one of these actions resolves the problem.

The HelpDesk business process consists of a while loop, during which a problem report is sent, first to the development group for a problem to be fixed, and next to the testing group for the fix to be tested. Upon completion of this sequence, the while condition “Resolved” is satisfied, and the business process ends, returning its final response to its caller.

When viewed in the Business Process Designer, the HelpDesk business process looks like this:

generated description: busproc bpl

The top area of the expanded while loop appears as follows:

generated description: busproc bpl expanded top

The bottom section is as follows:

generated description: busproc bpl expanded bottom

The code within the while loop makes two calls to workflow, using the built-in task request and task response classes for each call. The difference between the two <call> elements is easier to see in the BPL source code:

Class Demo.Workflow.HelpDesk Extends Ens.BusinessProcessBPL 
{

XData BPL
{
<process request='Demo.Workflow.ProblemReport'
         response='Ens.Response' >
  <context>
    <property name='Resolved' type='%Boolean' initialexpression='0' />
    <property name='DevelopmentAction' type='%String' />
    <property name='TestingAction' type='%String' />
  </context>

  <sequence>
    <while name='while'
           condition='context.Resolved=0' >
      <annotation>
        Work on this problem until it is resolved.
        (Click on the loop icon to see details of this while loop.)
      </annotation>

      <call name='Notify Development'
            target='Demo-Development'
            async='1' >
        <annotation>
          Send the problem report to Development for review.
        </annotation>
        <request type='EnsLib.Workflow.TaskRequest' >
          <assign property='callrequest.%Actions'
                  value='"Corrected,Ignored"'
                  action='set' />
          <assign property='callrequest.%Subject'
                  value='"Problem reported by "_request.ReportedBy'
                  action='set' />
          <assign property='callrequest.%Message'
                  value='request.Problem'
                  action='set' />
          <assign property='callrequest.%FormFields'
                  value='"Comments"'
                  action='set' />
        </request>
        <response type='EnsLib.Workflow.TaskResponse' >
          <assign property='context.DevelopmentAction'
                  value='callresponse.%Action'
                  action='set' />
        </response>
      </call>

      <sync name='WaitForDevelopment' calls='Notify Development' type='all' />

      <if name='Fixed?' condition='context.DevelopmentAction="Corrected"' >
        <annotation>
          If Development fixed the problem, test it.
        </annotation>

        <true>
          <call name='Notify Testing'
                target='Demo-Testing'
                async='1' >
            <annotation>
              Send the problem to Testing for confirmation.
            </annotation>
            <request type='EnsLib.Workflow.TaskRequest' >
              <assign property='callrequest.%Actions'
                      value='"Corrected,Retest"'
                      action='set' />
              <assign property='callrequest.%Subject'
                      value='"Test this problem from "_request.ReportedBy'
                      action='set' />
              <assign property='callrequest.%Message'
                      value='request.Problem'
                      action='set' />
            </request>
            <response type='EnsLib.Workflow.TaskResponse' >
              <assign property='context.TestingAction'
                      value='callresponse.%Action'
                      action='set' />
            </response>
          </call>

          <sync name='WaitForTesting' calls='Notify Testing' type='all' />

          <if name='Corrected?' condition='context.TestingAction="Corrected"' >
            <annotation>Has the problem been corrected?</annotation>
            <true>
              <assign name='Resolved'
                      property='context.Resolved'
                      value='1'
                      action='set' />
            </true>
          </if>
        </true>

        <false>
          <assign name='Not a problem'
                  property='context.Resolved'
                  value='1'
                  action='set' />
        </false>

      </if>
    </while>
  </sequence>
</process>
}
}

Sample Control Flow

When the production is running, the BPL business process example Demo.Workflow.HelpDeskOpens in a new tab works as follows. Try comparing the steps in this control flow with the corresponding statements in the BPL source code, shown in the previous section:

  1. A message of type Demo.Workflow.ProblemReportOpens in a new tab tells the business process who reported the problem, and provides a brief text string to describes the problem. The values for both these properties are provided by the business host that invokes this business process.

  2. In preparing the <call> to the Demo-Development workflow operation, the Demo.Workflow.HelpDeskOpens in a new tab business process uses the incoming request properties ReportedBy and Problem to fill in the task request fields %Subject and %Message, respectively. Two other built-in task properties come into play as well: The call creates a list of possible user actions by assigning the %Actions field a value of Corrected,Ignored. The call also prepares a form field called Comments in which the person reviewing this task can enter data.

  3. The business process makes the <call> to Demo-Development asynchronously, and provides a <sync> element to catch the task response.

  4. The Workflow Engine associates the task with each workflow user in the Demo-Development workflow role.

  5. One of the workflow users accepts the task. The Workflow Engine assigns the task to that user.

  6. The assigned user edits the Comments field and clicks one of the actions Corrected or Ignored.

  7. The task response returns. Its %Action field contains the value of the user action that completed the task (Corrected or Ignored). The business process saves this value into a execution context property called DevelopmentAction.

  8. The business process uses an <if> element to test the DevelopmentAction value. The results are as follows:

    • When DevelopmentAction is Corrected, this value signals to the help desk business process that it should execute the <true> portion of its <if> element. The <true> element issues a <call> to the Demo-Testing workflow role as described in the next step.

    • When DevelopmentAction is not Corrected, this value signals to the help desk business process that it should execute the <false> portion of its <if> element, near the end of the BPL source code. Control reaches this statement when the DevelopmentAction is Ignored by the user. The business process returns its final response to its caller, commenting that the reported problem is Not a problem and setting the Boolean response value Resolved to 1 (true).

  9. In preparing the <call> to the Demo-Testing workflow operation, the business process uses the original, incoming request properties ReportedBy and Problem to fill in the task request fields %Subject and %Message, respectively. However, unlike the previous <call>, the <call> to Demo-Testing has no form fields defined. Also, the list of possible user actions is different: %Actions is different: This <call> assigns the %Actions field a value of Corrected,Retest.

  10. The business process makes the <call> to Demo-Testing asynchronously, and provides a <sync> element to catch the task response.

  11. The Workflow Engine associates the task with each workflow user in the Demo-Testing workflow role.

  12. One of the workflow users accepts the task. The Workflow Engine assigns the task to that user.

  13. The assigned user clicks either Corrected or Retest.

  14. The task response returns. Its %Action field contains the value of the user action that completed the task (Corrected or Retest). The business process saves this value into a execution context property called TestingAction.

  15. The business process uses an <if> element to test the TestingAction value. The results are as follows:

    • When TestingAction is Corrected, the business process returns its final response to its caller, commenting that the reported problem is Resolved and setting the Boolean response value Resolved to 1 (true).

    • When TestingAction is not Corrected, the Boolean response value Resolved retains its initial value of 0 (false). The business process enters the top of the <while> loop again.

Dashboards and Metrics

To see a business metric and dashboard working together to display workflow role statistics, use Studio to view the sample classes Demo.Workflow.WFMetricOpens in a new tab and Demo.Workflow.DashboardOpens in a new tab in the ENSDEMO namespace.

The following sample code from the business metric class Demo.Workflow.WFMetricOpens in a new tab calls three of the available statistical methods and assigns their return values to metric properties. The next appendix describes the available methods.

/// Sample business metric class for Workflow demo
Class Demo.Workflow.WFMetric Extends Ens.BusinessMetric
{

/// Active Tasks
Property ActiveTasks As Ens.DataType.Metric(AUTOHISTORY = 10, RANGELOWER = 0,
                                     RANGEUPPER = 50, UNITS = "Tasks")
                                     [ MultiDimensional ];

/// Active Load
Property Load As Ens.DataType.Metric(AUTOHISTORY = 10, RANGELOWER = 0,
                                     RANGEUPPER = 100, THRESHOLDUPPER = 90,
                                     UNITS = "%") [ MultiDimensional ];

/// Completed Tasks (since previous day)
Property CompletedTasks As Ens.DataType.Metric(AUTOHISTORY = 10, RANGELOWER = 0,
                                     RANGEUPPER = 100, UNITS = "Tasks")
                                     [ MultiDimensional ];

/// Calculate and update the set of metrics for this class
Method OnCalculateMetrics() As %Status
{
  // set the values of our metrics
  // %Instance is the current instance (RoleName in this case)
  Set tRole = ..%Instance

  Set ..ActiveTasks = ##class(EnsLib.Workflow.Engine).BamActiveTasks(tRole)
  Set ..Load = ##class(EnsLib.Workflow.Engine).BamActiveLoad(tRole)

  // Get task since start of previous day
  Set tStart = $ZDT($H-1,3)

  Set ..CompletedTasks =
      ##class(EnsLib.Workflow.Engine).BamCompletedTasks(tRole,tStart)

  Quit $$$OK
}

/// Set of instances for this metric class
/// There is one instance for every defined role.
Query MetricInstances() As %SQLQuery
{
  SELECT Name FROM EnsLib_Workflow.RoleDefinition
}

}

For information about the ObjectScript functions $ZDT ($ZDATETIME) and $H ($HOROLOG) used here , see the chapter “ObjectScript Functions” in the Caché ObjectScript Reference.

FeedbackOpens in a new tab