Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Overview

The purpose of this tutorial is to:

...

Also, instead of creating Users and Work Groups ourselves, we will leave that task to the Identity Management system. In production, we can expect all Users to already be present in the system. Work Groups can be specific to workflows, so we can expect to request that these be created by the system administrators.

Development Steps

  1. Study the Business Process
  2. Gather the Required Details
  3. Create a Document Workflow Diagram
  4. Request Work Groups
  5. Create the Parent Document Type
  6. Create the Child Document Types
  7. Create the eDocLite Form
    • Create the Definition
    • Create the Stylesheet
  8. Create Rule Attributes
  9. Create the Rule Template
  10. Create Routing Rules
  11. Ingest XML Files
  12. Simulate the Business Process
  13. Create Test/QA/QC Plan

The Business Process


In using eDocLite to facilitate this process, we'll need a few things:

...

  • This time there are four responsible parties: Requester, Desktop Services, Firewall Policy Group, and the Firewall Gatekeeper.
  • The Requester submits the request as before, except s/he is now allowed to tell us whether if the request is URGENT. If it is, we expedite the process. If not, we go through the process as normal.
  • The Desktop Services group will field all requests instead of the Firewall Policy Group. We want whoever receives the request to check if the firewall modification being requested is already in effect. If so, disapprove the request. The Requester will then get notification. Also if the request is URGENT, forward the request straight to the Firewall Gatekeeper to make the firewall modification. Otherwise, forward the request to the Firewall Policy Group.
  • The Firewall Policy Group will review all normal requests and, upon approval, forward the request to the Firewall Gatekeeper. This group will review all URGENT requests after the Firewall Gatekeeper has fulfilled them.
  • The Firewall Gatekeeper performs the actual modification of the firewall. As far as the process goes, all the gatekeeper will do is acknowledge the request and implement the modification to the firewall. Once the modification is complete, the gatekeeper will forward the request onward. We say "onward", because the gatekeeper is not routing the request to anyone per se. Behind the scenes, if the request is URGENT, then the request gets routed to the Firewall Policy Group. Otherwise the process is finished and the Requester gets a notification (and maybe all the other responsible parties too).
  • To complicate things further, if the Firewall Gatekeeper modified the firewall based on an URGENT request, and the Firewall Policy Group decides to disapprove the request after the fact, then the request goes back to the gatekeeper to reverse the firewall modification.
  • We documented the Review Non-Urgent Request and Review Urgent Request as subprocesses because there is the potential for the Firewall Policy Group to have continuous correspondence with the Requester. We'll address these in a future Way More Advanced tutorial.

The Request Details

As part of the process, the Firewall Policy Group requires that anyone who wants the firewall rules modified must provide the following details:

...

  • The details we are asking from the Requester are almost the same as those in the Simple Workflow tutorial. This time we decided to split Source Specification and Destination Specification into two fields and allow for the Requester to tell us that this is an URGENT request.
  • The details of the request don't stop there. As the process moves along, we want the other responsible parties to add detail to the form.
  • Once Desktop Services fields the request, we want to capture whether the firewall modification being requested is already in effect or not. Depending on the answer, the workflow will route the form to the appropriate party.
  • If the Firewall Policy Group decides to disapprove the request, we want to capture their reason for doing so.
  • If the request is URGENT, and the Firewall Gatekeeper already modified the firewall rules, and the Firewall Policy Group disapproved the request afterward, we want our workflow to automatically check a box that prompts the Firewall Gatekeeper to revert the modification.

The Document Workflow Diagram

Here is a document workflow diagram based on our business process. It doesn't map exactly to our business process diagram, because we want to represent the state of the Request Firewall Change document as the responsible parties act upon it.

...

  • The Request element is the first node (aka Start Node) in the workflow's route path. This is where the Request Firewall Change document is first created.
  • Each violet element represents a subsequent node in the route path. Each node represents a point in the business process where a responsible party is viewing (and possibly editing) the Request Firewall Change docuement.
  • Each lavender parallelogram represents a rule template that is applied to each node. Each rule template can be associated with a set of rules.
  • The orange skittle represents a split in the workflow. If the request is URGENT, the workflow branches out one way. If not, it branches out the other way.
  • The lime skittle represents a join in the workflow. No matter which way the workflow branched, it will end up at this point.
  • The green Finish element means the workflow has ended with flying colors.
  • The red Acknowledge and Finish elements mean that somewhere in the workflow there was a disapproval. Therefore the entire workflow stops. Out of the box, eDocLite routes the disapproved request back to the Requester for acknowledgment.

Request Work Groups

After going through the easy and expedient process of requesting Work Groups, the Kuali Rice administrator has notified us that the following groups are available for use in our workflow:

...

Node

Responsible Party

Action Requested

Request

Initiator.Role.RuleAttribute (whoever creates the document)

SUBMIT

Review Current Configuration

ucd.IET.DES.DevelopmentSupport.WorkGroup

APPROVE

Review Request

ucd.IET.AppDev.FirewallPolicyGroup.Workgroup

APPROVE

Fulfill Request

ucd.IET.DCCS.FirewallSysAdmin.Workgroup

ACKNOWLEDGE

Fulfill Urgent Request

ucd.IET.DCCS.FirewallSysAdmin.Workgroup

ACKNOWLEDGE

Review Urgent Request

ucd.IET.AppDev.FirewallPolicyGroup.Workgroup

APPROVE

Acknowledge Configuration

Initiator.Role.RuleAttribute

ACKNOWLEDGE

Create the Parent Document Type

Here we create a parent document type that defines the behavior of all Request Firewall Change documents. This particular parent document type defines everything short of routing paths. The idea is to allow for a hierarchy of child document types that inherit attributes of their parents.

...

Code Block
titleRequestFirewallChange.eDoc.ParentDocType.xml
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData">
<documentTypes xmlns="ns:workflow/DocumentType" xsi:schemaLocation="ns:workflow/DocumentType resource:DocumentType">
	<documentType>
		<name>RequestFirewallChange.eDoc.ParentDocType</name>
		<description>Request Firewall Change eDocLite Parent Document Type</description>
		<label>Request Firewall Change eDocLite Parent Document Type</label>
		<blanketApprovePolicy>NONE</blanketApprovePolicy>
		<docHandler>${workflow.url}/EDocLite</docHandler>
		<active>true</active>
		<routingVersion>2</routingVersion>
	</documentType>
</documentTypes>
</data>

Create the Child Document Type

Here we create one child document type to support the behavior of our workflow. Besides identifying the name and parent of this document type, we define two other main things: routePaths and routeNodes. These define the behavior of the workflow.

...

Code Block
titleRequestFirewallChange.eDoc.ChildDocType.xml
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData">
<documentTypes xmlns="ns:workflow/DocumentType" xsi:schemaLocation="ns:workflow/DocumentType resource:DocumentType">
	<documentType>
		<name>RequestFirewallChange.eDoc.ChildDocType</name>
		<parent>RequestFirewallChange.eDoc.ParentDocType</parent>
		<description>Request Firewall Change eDocLite Child Document Type</description>
		<label>Request Firewall Change eDocLite Child Document Typee</label>
		<postProcessorName>edu.iu.uis.eden.edl.EDocLitePostProcessor</postProcessorName>
		<superUserWorkgroupName>ucd.IET.AppDev.KualiRice.SysAdmin.Workgroup</superUserWorkgroupName>
		<defaultExceptionWorkgroupName>ucd.IET.AppDev.KualiRice.SysAdmin.Workgroup</defaultExceptionWorkgroupName>
		<docHandler>${workflow.url}/EDocLite</docHandler>
		<active>true</active>
		<routingVersion>2</routingVersion>
		<routePaths>
			<routePath>
          			<start name="RequestFirewallChange.eDoc.Request.Node" nextNode="RequestFirewallChange.eDoc.ReviewCurrentConfiguration.Node" />
		          	<requests name="RequestFirewallChange.eDoc.ReviewCurrentConfiguration.Node" nextNode="RequestFirewallChange.eDoc.isUrgent.Split" />
				<split name="RequestFirewallChange.eDoc.isUrgent.Split" nextNode="RequestFirewallChange.eDoc.AcknowledgeConfiguration.Node">
					<branch name="RequestFirewallChange.eDoc.isUrgent.Branch">
						<requests name="RequestFirewallChange.eDoc.FulfillUrgentRequest.Node" nextNode="RequestFirewallChange.eDoc.ReviewUrgentRequest.Node" />
						<requests name="RequestFirewallChange.eDoc.ReviewUrgentRequest.Node" nextNode="RequestFirewallChange.eDoc.isUrgent.Join" />
					</branch>
					<branch name="RequestFirewallChange.eDoc.isNotUrgent.Branch">
						<requests name="RequestFirewallChange.eDoc.ReviewRequest.Node" nextNode="RequestFirewallChange.eDoc.FulfillRequest.Node" />
						<requests name="RequestFirewallChange.eDoc.FulfillRequest.Node" nextNode="RequestFirewallChange.eDoc.isUrgent.Join" />
					</branch>
					<join name="RequestFirewallChange.eDoc.isUrgent.Join" />
				</split>
				<requests name="RequestFirewallChange.eDoc.AcknowledgeConfiguration.Node" />
        	      </routePath>
		</routePaths>
	      <routeNodes>
			<start name="RequestFirewallChange.eDoc.Request.Node">
				<activationType>P</activationType>
			</start>
			<requests name="RequestFirewallChange.eDoc.ReviewCurrentConfiguration.Node">
				<activationType>P</activationType>
				<ruleTemplate>RequestFirewallChange.eDoc.ReviewCurrentConfiguration.RuleTemplate</ruleTemplate>
			</requests>
			<split name="RequestFirewallChange.eDoc.isUrgent.Split" />
			<requests name="RequestFirewallChange.eDoc.FulfillUrgentRequest.Node">
				<activationType>P</activationType>
				<ruleTemplate>RequestFirewallChange.eDoc.FulfillUrgentRequest.RuleTemplate</ruleTemplate>
			</requests>
			<requests name="RequestFirewallChange.eDoc.ReviewUrgentRequest.Node">
				<activationType>P</activationType>
				<ruleTemplate>RequestFirewallChange.eDoc.ReviewUrgentRequest.RuleTemplate</ruleTemplate>
			</requests>
			<requests name="RequestFirewallChange.eDoc.ReviewRequest.Node">
				<activationType>P</activationType>
				<ruleTemplate>RequestFirewallChange.eDoc.ReviewRequest.RuleTemplate</ruleTemplate>
			</requests>
			<requests name="RequestFirewallChange.eDoc.FulfillRequest.Node">
				<activationType>P</activationType>
				<ruleTemplate>RequestFirewallChange.eDoc.FulfillRequest.RuleTemplate</ruleTemplate>
			</requests>
			<join name="RequestFirewallChange.eDoc.isUrgent.Join" />
			<requests name="RequestFirewallChange.eDoc.AcknowledgeConfiguration.Node">
				<activationType>S</activationType>
				<ruleTemplate>RequestFirewallChange.eDoc.AcknowledgeConfiguration.RuleTemplate</ruleTemplate>
				<mandatoryRoute>false</mandatoryRoute>
				<finalApproval>false</finalApproval>
			</requests>
		</routeNodes>
	</documentType>
</documentTypes>
</data>

Create the eDocLite Form

Based on the request details required by our process above (way above), we now build the form for the users to enter those details into.

...

  1. The eDocLite Form Skeleton
    The Form Skeleton is the structure of the entire eDocLite form minus the Form Definition and Form Stylesheet. We separate this out so that you can use it as a base template for all of your eDocLite forms. This particular skeleton follows the scheme of the out-of-the-box Kuali Rice forms. The scheme uses the same look and feel and makes calls to the eDocLite widgets on the Kuali Rice server.
    Code Block
    titleRequestFirewallChange.eDoc.Form.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData">
    <edoclite xmlns="ns:workflow/EDocLite" xsi:schemaLocation="ns:workflow/EDocLite resource:EDocLite">
      
    	<edl name="RequestFirewallChange.eDoc.Form" title="Request Firewall Change">
    		<security />
    		<createInstructions>** Fields with an asterisk are required.</createInstructions>
    		<instructions>** Fields with an asterisk are required.</instructions>
    		<validations />
    		<attributes />
    	        ...
    	        ...
    	</edl>
    
    	<style name="RequestFirewallChange.eDoc.Style">
    	<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my-class="xalan://edu.iu.uis.eden.edl.WorkflowFunctions" version="1.0">
    		<xsl:include href="widgets" />
    		<xsl:output indent="yes" method="html" omit-xml-declaration="yes" version="4.01" />
    		<xsl:variable name="actionable" select="/documentContent/documentState/actionable" />
    		<xsl:variable name="docHeaderId" select="/documentContent/documentState/docId" />
    		<xsl:variable name="editable" select="/documentContent/documentState/editable" />
    		<xsl:variable name="globalReadOnly" select="/documentContent/documentState/editable != 'true'" />
    		<xsl:variable name="docStatus" select="//documentState/workflowDocumentState/status" />
    		<xsl:variable name="isAtNodeInitiated" select="my-class:isAtNode($docHeaderId, 'Initiated')" />
    		<xsl:variable name="isPastInitiated" select="my-class:isNodeInPreviousNodeList('Initiated', $docHeaderId)" />
    		<xsl:variable name="isUserInitiator" select="my-class:isUserInitiator($docHeaderId)" />
    		<xsl:param name="overrideMain" select="'true'" />
            
    		<xsl:template name="mainForm">
    			<html xmlns="">
    			  <head>
    			  <script language="javascript" />
    			  <xsl:call-template name="htmlHead" />
    			  </head>
      			<body onload="onPageLoad()">
    			  <xsl:call-template name="errors" />
    			  <xsl:call-template name="header" />
    			  <xsl:call-template name="instructions" />
    		  	  <xsl:variable name="formTarget" select="'EDocLite'" />
    		          <form action="{$formTarget}" enctype="multipart/form-data" id="edoclite" method="post" onsubmit="return validateOnSubmit(this)">
    		  	    <xsl:call-template name="hidden-params" />
    		  	    <xsl:call-template name="mainBody" />
    		  	    <xsl:call-template name="notes" />
    		  	    <br />
    		  	    <xsl:call-template name="buttons" />
    		  	    <br />
    		  	  </form>
                              <xsl:call-template name="footer" />
        		  	</body>
        		       </html>
    		</xsl:template>
    
    		<xsl:template name="mainBody">
    			...
    			...
     		</xsl:template>
    
      		<xsl:template name="nbsp">
    			<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
    		</xsl:template>
    	</xsl:stylesheet>
    	</style>
    
    	<association>
    		<docType>RequestFirewallChange.eDoc.ChildDocType</docType>
    		<definition>RequestFirewallChange.eDoc.Form</definition>
    		<style>RequestFirewallChange.eDoc.Style</style>
        		<active>true</active>
      	</association>
    
    </edoclite>
    </data>
    

  2. Form Definition
    The Form Definition defines the data entry fields on the form. Our definitions define field display characteristics and field validations. Place your form definition between the <edl> and </edl> tags in the Form Skeleton.
    Code Block
    titleRequestFirewallChange.eDoc.Form.xml
        <fieldDef name="dateOfChange" title="Date and Time for Change">
          <display>
            <type>text</type>
          </display>
          <validation required="true">
            <regex>^[0-1]?[0-9](/|-)[0-3]?[0-9](/|-)[1-2][0-9][0-9][0-9]$</regex>
            <message>Enter a valid date in the format mm/dd/yyyy.</message>
          </validation>
        </fieldDef>
    
        <fieldDef name="descriptionOfChange" title="Description of the Port Change">
          <display>
            <type>textarea</type>
            <meta>
              <name>rows</name>
              <value>5</value>
            </meta>
            <meta>
              <name>cols</name>
              <value>60</value>
            </meta>
            <meta>
              <name>wrap</name>
              <value>hard</value>
            </meta>
          </display>
          <validation required="true">
            <message>Enter a description of the port change.</message>
          </validation>
        </fieldDef>
    
        <fieldDef attributeName="RequestFirewallChange.eDoc.isUrgent.RuleAttribute" name="isUrgent" title="URGENT">
          <display>
            <type>select</type>
              <values title="NO">NO</values>
              <values title="YES">YES</values>
          </display>
          <validation required="true">
              <message>Is this request URGENT?</message>
          </validation>
        </fieldDef>
    
        <fieldDef name="ingressEgressCharacteristic" title="Ingress/Egress Characteristic">
          <display>
            <type>textarea</type>
            <meta>
              <name>rows</name>
              <value>5</value>
            </meta>
            <meta>
              <name>cols</name>
              <value>60</value>
            </meta>
            <meta>
              <name>wrap</name>
              <value>hard</value>
            </meta>
          </display>
          <validation required="true">
            <message>Enter the ingress/egress characteristic.</message>
          </validation>
        </fieldDef>
    
        <fieldDef name="destinationSourceSpecification" title="Destination/Source Specification">
          <display>
            <type>textarea</type>
            <meta>
              <name>rows</name>
              <value>5</value>
            </meta>
            <meta>
              <name>cols</name>
              <value>60</value>
            </meta>
            <meta>
              <name>wrap</name>
              <value>hard</value>
            </meta>
          </display>
          <validation required="true">
            <message>Enter the destination/source specification.</message>
          </validation>
        </fieldDef>
    
        <fieldDef name="termOfRuleChange" title="Term of Rule Change (indefinite or otherwise)">
          <display>
            <type>text</type>
            <meta>
              <name>size</name>
              <value>50</value>
            </meta>
          </display>
          <validation required="true">
            <message>Enter term of the rule change.</message>
          </validation>
        </fieldDef>
    
        <fieldDef name="relatedProject" title="Project Related to Requested Rule(s) Change">
          <display>
            <type>text</type>
            <meta>
              <name>size</name>
              <value>50</value>
            </meta>
          </display>
          <validation required="true">
            <message>Enter a related project to the requested rule change.</message>
          </validation>
        </fieldDef>
    

  3. Form Stylesheet
    The Form Stylesheet defines the layout of the form and renders the fields from our Form Definition onto the form. Our layout is an HTML table with a row for each field. In this case, we are customizing the mainBody piece of the stylesheet. In general, place your form stylesheet between the <style> and </style> tags in the Form Skeleton.
    Code Block
    titleRequestFirewallChange.eDoc.Form.xml
      <xsl:template name="mainBody">
        <table xmlns="" align="center" border="0" cellpadding="0" cellspacing="0" class="bord-r-t" width="80%">
          <tr>
            <td align="left" border="3" class="thnormal" colspan="1">
              <br />
              <h3>
                University of California, Davis
                <br />
                eDoclite Tutorial
    	  </h3>
              <br />
            </td>
            <td align="center" border="3" class="thnormal" colspan="2">
              <br />
              <h2>Request Firewall Change Form</h2>
            </td>
          </tr>
          <tr>
            <td class="headercell5" colspan="100%">
            <b>Request Details</b>
            </td>
          </tr>
          <tr>
            <td class="thnormal">
              <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="'dateOfChange'" />
                <xsl:with-param name="renderCmd" select="'title'" />
              </xsl:call-template>
              <font color="#ff0000">*</font>
            </td>
            <td class="datacell">
              <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="'dateOfChange'" />
                <xsl:with-param name="renderCmd" select="'input'" />
                <xsl:with-param name="readOnly" select="$isPastInitiated" />
              </xsl:call-template>
            </td>
          </tr>
          <tr>
            <td class="thnormal">
              <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="'descriptionOfChange'" />
                <xsl:with-param name="renderCmd" select="'title'" />
              </xsl:call-template>
              <font color="#ff0000">*</font>
            </td>
            <td class="datacell">
              <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="'descriptionOfChange'" />
                <xsl:with-param name="renderCmd" select="'input'" />
                <xsl:with-param name="readOnly" select="$isPastInitiated" />
              </xsl:call-template>
            </td>
          </tr>
          <tr>
            <td class="thnormal">
              <xsl:call-template name="widget_render">
              <xsl:with-param name="fieldName" select="'isUrgent'" />
              <xsl:with-param name="renderCmd" select="'title'" />
              </xsl:call-template>
              <font color="#ff0000">*</font>
            </td>
            <td class="datacell">
              <xsl:call-template name="widget_render">
              <xsl:with-param name="fieldName" select="'isURgent'" />
              <xsl:with-param name="renderCmd" select="'input'" />
              <xsl:with-param name="readOnly" select="$isPastInitiated" />
              </xsl:call-template>
            </td>
          </tr>
          <tr>
            <td class="thnormal">
              <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="'ingressEgressCharacteristic'" />
                <xsl:with-param name="renderCmd" select="'title'" />
              </xsl:call-template>
              <font color="#ff0000">*</font>
            </td>
            <td class="datacell">
              <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="'ingressEgressCharacteristic'" />
                <xsl:with-param name="renderCmd" select="'input'" />
                <xsl:with-param name="readOnly" select="$isPastInitiated" />
              </xsl:call-template>
            </td>
          </tr>
          <tr>
            <td class="thnormal">
              <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="'destinationSourceSpecification'" />
                <xsl:with-param name="renderCmd" select="'title'" />
              </xsl:call-template>
              <font color="#ff0000">*</font>
            </td>
            <td class="datacell">
              <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="'destinationSourceSpecification'" />
                <xsl:with-param name="renderCmd" select="'input'" />
                <xsl:with-param name="readOnly" select="$isPastInitiated" />
    
              </xsl:call-template>
            </td>
          </tr>
          <tr>
            <td class="thnormal">
              <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="'termOfRuleChange'" />
                <xsl:with-param name="renderCmd" select="'title'" />
              </xsl:call-template>
              <font color="#ff0000">*</font>
            </td>
            <td class="datacell">
              <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="'termOfRuleChange'" />
                <xsl:with-param name="renderCmd" select="'input'" />
                <xsl:with-param name="readOnly" select="$isPastInitiated" />
              </xsl:call-template>
            </td>
          </tr>
          <tr>
            <td class="thnormal">
              <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="'relatedProject'" />
                <xsl:with-param name="renderCmd" select="'title'" />
              </xsl:call-template>
              <font color="#ff0000">*</font>
            </td>
            <td class="datacell">
              <xsl:call-template name="widget_render">
                <xsl:with-param name="fieldName" select="'relatedProject'" />
                <xsl:with-param name="renderCmd" select="'input'" />
                <xsl:with-param name="readOnly" select="$isPastInitiated" />
              </xsl:call-template>
            </td>
          </tr>
        </table>
        <br xmlns="" />
    <xsl:template>
    

Create Rule Attributes

Here we create a Rule Attribute that is associated with the isUrgent field in the form. Let's use <process name>.eDoc.<rule attribute name>.RuleAttribute to name our rule attributes and <process name>.eDoc.RuleAttributes to name the associated XML file defining our collection of rule attributes.

Code Block
title"RequestFirewallChange.eDoc.RuleAttributes.xml
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData">
<ruleAttributes xmlns="ns:workflow/RuleAttribute" xsi:schemaLocation="ns:workflow/RuleAttribute resource:RuleAttribute">
	<ruleAttribute>
      	<name>RequestFirewallChange.eDoc.isUrgent.RuleAttribute</name>
	      <className>edu.iu.uis.eden.routetemplate.xmlrouting.StandardGenericXMLRuleAttribute</className>
      	<label>Request Firewall Change Is Urgent Rule Attribute</label>
	      <description>Request Firewall Change Is Urgent Rule Attribute</description>
      	<type>RuleXmlAttribute</type>
      	<routingConfig>
        		<fieldDef name="isUrgent" title="URGENT" workflowType="ALL">
	          		<display>
            			<type>select</type>
            			<values title="NO">NO</values>
            			<values title="YES">YES</values>
             		</display>
          			<validation required="true" />
          			<fieldEvaluation>
            			<xpathexpression>//isUrgent = wf:ruledata('isUrgent')</xpathexpression>
          			</fieldEvaluation>
       		</fieldDef>
        		<xmlDocumentContent>
          			<isUrgent>%isUrgent%</isUrgent>
        		</xmlDocumentContent>
      	</routingConfig>
    </ruleAttribute>
</ruleAttributes>
</data>


Create Rule Templates

Here we create several Rule Templates that are applied to each route node. Let's use <process name>.eDoc.<rule template name>.RuleTemplate to name our rule templates and <process name>.eDoc.RuleTemplates to name the associated XML file defining our collection of rule templates.

Code Block
titleRequestFirewallChange.eDoc.RuleTemplates.xml
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData">
<ruleTemplates xmlns="ns:workflow/RuleTemplate" xsi:schemaLocation="ns:workflow/RuleTemplate resource:RuleTemplate">
	<ruleTemplate>
      		<name>RequestFirewallChange.eDoc.ReviewCurrentConfiguration.RuleTemplate</name>
      		<description>ReviewCurrentConfiguration RuleTemplate</description>
	</ruleTemplate>
	<ruleTemplate>
      		<name>RequestFirewallChange.eDoc.FulfillUrgentRequest.RuleTemplate</name>
      		<description>FulfillUrgentRequest RuleTemplate</description>
	</ruleTemplate>
	<ruleTemplate>
      		<name>RequestFirewallChange.eDoc.ReviewUrgentRequest.RuleTemplate</name>
      		<description>ReviewUrgentRequest RuleTemplate</description>
	</ruleTemplate>
	<ruleTemplate>
      		<name>RequestFirewallChange.eDoc.ReviewRequest.RuleTemplate</name>
      		<description>ReviewRequest RuleTemplate</description>
	</ruleTemplate>
	<ruleTemplate>
      		<name>RequestFirewallChange.eDoc.FulfillRequest.RuleTemplate</name>
      		<description>FulfillRequest RuleTemplate</description>
	</ruleTemplate>
	<ruleTemplate>
      		<name>RequestFirewallChange.eDoc.AcknowledgeConfiguration.RuleTemplate</name>
      		<description>AcknowledgeConfiguration RuleTemplate</description>
			<attributes>
				<attribute>
					<name>Initiator.Role.RuleAttribute</name>
					<required>true</required>
				</attribute>
			</attributes>
	</ruleTemplate>
</ruleTemplates>
</data>


Create Routing Rules

Finally, we create Routing Rules that is associated with RequestFirewallChange.eDoc.ChildDocType and its associated rule templates. Let's use <process name>.eDoc.RoutingRules to name the associated XML file defining our collection of routing rules.

...

Note:

actionRequested codes: A = APPROVE, K = ACKNOWLEDGE

XML File Ingestion

  1. Open the URL to a Kuali Rice development server (e.g. http://ricedevhost.ucdavis.edu:8080/rice-0.9.3-server/)
  2. Click on Kuali Enterprise Workflow
  3. Log in as admin
  4. Under Administration, click on XML Ingester
  5. Upload the XML files we created in the following order:

    Rule Attributes

    RequestFirewallChange.eDoc.RuleAttributes.xml

    Rule Templates

    RequestFirewallChange.eDoc.RuleTemplates.xml

    Parent Document Type

    RequestFirewallChange.eDoc.ParentDocType.xml

    Child Document Types

    RequestFirewallChange.eDoc.ChildDocType.xml

    EDL Form

    RequestFirewallChange.eDoc.Form.xml

    Routing Rules:

    RequestFirewallChange.eDoc.RoutingRules.xml

Simulate the Business Process

First, let's simulate a Firewall Change Request that gets approved by someone in the Firewall Policy Group:

  1. Log in as requester1
  2. Click on EDocLites
  3. Click Search
  4. Find the eDocLite whose Definition Name is RequestFirewallChange.eDoc.Form
  5. Click on Create Document
  6. Here's the form we built:
  7. Fill out the form, set URGENT to NO and click route
  8. Log in as DES1
  9. Click on Action List
  10. Find and open the document initiated by requester1. Its status should be ENROUTE
  11. Click on the document and it should look like so:
  12. Click approve
  13. Log in as FPG1
  14. Click on Action List
  15. Find and open the document initiated by requester1 and approved by DES1. Its status should be ENROUTE
  16. Click approve
  17. Login as DCCS1
  18. Click on Action List
  19. Find and open the document initiated by requester1, approved by DES1, and approved by FPG1. Its status should be PROCESSED
  20. Click acknowledge
  21. Log in as requester1 again
  22. Click on Action List
  23. Find and open the document initiated by requester1, approved by DES1, approved by FPG1, and acknowledged by DCCS1. Its status should be PROCESSED
  24. Click acknowledge
  25. Click Document Search
  26. Find the document again
  27. Click on the Log icon
  28. The log should like like so:

Create Validation Checklist

Let's build a checklist that the QA team can use to validate the above simulation:

Requested Node

Action

Taken By

RequestFirewallChange.eDoc.Request.Node

Fill out form, set URGENT to NO, click route

requester1

RequestFirewallChange.eDoc.ReviewCurrentConfiguration.Node

Click approve

DES1

RequestFirewallChange.eDoc.ReviewRequest.Node

Click approve

FPG1

RequestFirewallChange.eDoc.FulfillRequest.Node

Click approve

DCCS1

RequestFirewallChange.eDoc.AcknowledgeConfiguration.Node

Click acknowledge

requester1

Do the same for the following scenarios:

  • Submit an urgent request
  • Submit any request that later gets disapproved

Reference

https://test.kuali.org/confluence/display/KULRICE/EDocLite+Documentation+Guide
https://test.kuali.org/confluence/display/KULRICE/eDocLite+Example+1