# Logic and Control
Logic and Control Actions are used within a workflow design to manipulate the route or behavior of the defined workflow providing for more complex control of the process through decisions, looping, calling sub-workflow, canceling other workflow activity, joins, gates, and more.
# Call Workflow
The Call Workflow action allows a workflow to call another defined workflow. Called workflows provide for compartmentalization of workflow functionality which provides many benefits including workflow legibility, manageability, and reuse of defined workflow processes.
Sharing contents with called workflow Called workflows will automatically inherit data from the calling workflow. Workflow contents of the parent workflow are automatically linked and accessible by the called workflows. This ensures that the called workflow will receive and have equal access to any submitted form data tied to the workflow.
Copying variable values to called workflow
Additionally, variables and XML variables are automatically copied into the called workflow for any identically named variables.
Local variables are also supported in the called workflow. Identically named local variables, with the @ symbol, are copied to called workflows. The variable value in the called workflow will be the same value as the local path execution in which the call workflow action is called in the parent.
XML Iterators may also be passed by copy to called workflows. However, iterators are pointer references to a location in an XML document and when the sub workflow is called, the iterator will be transformed into an XML variable. To pass an XML iterator XML fragment (the entire XML structure at the iterator level), create an XML variable in the called workflow set to storage of Variable with the same name as the iterator. The entire XML iterator fragment will be set into the XML variable in the called workflow.
Action Outputs: The Call Workflow activity will output the following by default.
[blank] – followed when the called workflow is complete and no specific output was set in the called workflow.
Cancelled – followed when canceled by the “Cancel Activity” action.
Additionally, called workflows can follow any number of additional outputs defined in the “Return Values” property.
Within the called workflow a Set Workflow Output activity can specify any of these outputs to be followed when the called workflow has finished. If the called workflow does not specify a return value, the activity will automatically transition out when complete, or immediately, based on the calling workflow parameters.
Action Properties:
Label
A descriptive label for the action
Properties
Workflow(required)
This property specifies the workflow to be called by the current workflow process. The field provides a drop-down list with the names of all available workflows for the specified application. Select one of the workflows in this list to set it as the workflow to be called.
Wait for the child workflow?
This Yes/No property, set to “No” by default, designates whether the parent workflow should wait for the child workflow to complete before continuing. NOTE: To have the calling workflow follow out a given path for a called workflow, this property must be set to “Yes.”
Control child workflow?
This Yes/No property designates whether workflow control actions, such as pause, resume, and abort, that are applied to the parent workflow should also be applied to the child workflow. (NOTE: If this property is set to “Yes,” then the Wait for ChildWorkflow behavior will be “Yes” as well, regardless of its setting.
Return Values (optional)
This property specifies all the possible output values to follow from the called workflow. This output is set within the called workflow using the ‘Set Workflow Output’ activity.
NOTE: If Return Values are set within this field, the value of the ‘Wait for the child workflow?’ property should also be set to “Yes.”
Steps to set the Return Values property:
Select “Click to add” or “Click to Edit”.
From the displayed pop-up window, set any number of “Return Values” by clicking “Add” and setting a text output to follow for any number of desired rows.
Select “Save” or “Save and Close” to dismiss the window.
Child Workflow Id
Specifies a variable to store the ID of the called workflow
Version
Determines which version of the called workflow to be used when the action is executed.
Latest - indicates that the latest deployed workflow version will be used when the called workflow is started.
Time Locked - indicates that the version to use will be based on the start time of the highest level workflow in the workflow call stack. This ensures that the sub workflow version will be compatible with the full workflow stack, as it will be based on the time of deployment. The purpose of this option can be considered as having the goal to allow workflows to either run as a "set" as if deployed together.
The version of the workflow to be called will be based on the last (most recent) deployed version of the sub workflow which is before the time the current (parent) workflow starts. This means that if a sub workflow "SUBWORKFLOW" is deployed as
1/15/2020 - SUBWORKFLOW Version 1 deployed
1/16/2020 - Parent workflow starts
1/17/2020 - SUBWORKFLOW Version 2 deployed
When Parent workflow gets to the call workflow, it will run version 1 of SUBWORKFLOW, as that is the latest that was deployed prior to starting the parent workflow.
This logic applies for the entire call tree. If a sub workflow, 3 levels down has the property "Time Locked" then it will use the highest level parent start time for this logic.
# Cancel Activity
Action Function: This action allows other waiting workflow activities to be cancelled. Additional activities can be executed after this step or from other cancelled activities by following the "Cancelled" path from a cancelled activity. Additional workflow activities can be defined by following the output from this action.
Action Outputs: This activity will automatically transition out when executed.
SAMPLE SCENARIOS: An example usage of the Cancel Activity action would be to support a “first responder” scenario, where two users are given different tasks, and only the first should be considered. A common scenario is to allow a requestor or another actor the option to cancel a request. Once one of the users has canceled the request, the other user’s task assignment should be canceled, as it is no longer valid. Another example is to use the cancel activity where two routes are happening in parallel but only one activity should occur. Cancel other Routes can be used at the end of each path to cancel the other path’s activities.
Action Properties:
Label
A descriptive label for the action
Properties
Actions to Cancel (optional)
To set specific actions to cancel, click the “Click to add” or “Click to edit” link for the property. This will display a new window where any number of “Action Names” can be set. Click “Add” to generate additional rows to specify action IDs to cancel, and enter an action ID for each row desired. Once complete, click “Save” or “Save and Close” to dismiss the window.
Scope - Allows a sub-workflow to cancel actions in a parent workflow. Options for the scope are "Current Workflow" and "Parent Workflow"
# Change Case
Action Function: The Change Case action will change the capitalization of a given string.
Action Outputs: The Add Comment action returns the following values:
Success – The action executed successfully
Failure – An issue was encountered
Action Properties:
Label
A descriptive label for the action
Properties
String Variable
The input string for which to change the capitalization
Case Options
The capitalization to use: Upper Case, Lower Case, Proper Case
Variable for storing error message
A variable to hold any errors encountered
Variable for storing results
The target variable for the newly capitalized string
# Date Difference
Action Function: This action calculates the amount of time between two “date times”. The resulting value calculated can be returned as a specified unit of time. Inputs for the “date times” are strings containing dates or dates with times. Supported inputs follow the .Net DateTime Parse rules with examples below.
1/1/2000
Fri, 27 Feb 2009 03:11:21 GMT
2009/02/26 18:37:58
Thursday, February 26, 2009
February 26, 2009
2002-02-10
2/21/2009 10:35 PM
8:04:00 PM
Action Outputs: The action will output success or failure based on calculating the time difference.
Action Properties:
Label
A descriptive label for the action
Properties
First Date
The first date to use as the input
Second Date
The second date to use as the input
Output Variable
The variable to store the calculated difference
Output Format
The unit of time measure to use for the calculated result
# Decision
Action Function: Decision steps are used to configure routing logic into your workflow designs. A single path is followed out of the decision step based on the defined business rules or conditions within the action.
Action Outputs: The Decision Action outputs are determined by the outputs defined in the Decision property, based on the rules to be followed.
SAMPLE SCENARIO: A Decision step can change the route of a given workflow based on values submitted by the requester. For example, if the requester has chosen an option in a request form requiring special approval, the workflow can evaluate this condition and route accordingly.
To configure the rules for a Decision action, click the “Click to add” or “Click to edit” link for the action’s “Decision” property.
Any defined Outputs for the action will be listed on the left-hand side of the management window, under the “Outputs” section header. Clicking the “+ Add” button at the top left of the window enables you to create a new output path or route that can be followed from this Decision step in a workflow design.
Each output can have one or many conditions or rules defined for it. Use the “+ Add Row” button to enter all applicable conditions or rules for a given output, one at a time. Each condition row allows you to configure the logic being evaluated, based on data type and operator. Use the When drop-down menu to designate how multiple conditions (if applicable) should be evaluated for an output. Choices for the “When” selection are:
All of these are true
Any of these are true
Each condition row effectively allows you to build criteria for
determining when a given output path from this Decision step should be
followed in the workflow design.
More complex conditions can be built by grouping logic within additional “When” by chaining them together with “Or” or “And” conditions.
Each “condition” or “expression” is comprised of three parts. The first is the workflow context, or code to be evaluated. Click the dropdown and select the desired value.
The second dropdown provides a list of expression “operators” to base the condition. The choices provide for comparing the given value as different data types including String, Number, and Date. The operators provide relevant operators.
Example operators available are:
String operators
== : case sensitive equals
~== : case insensitive equals
!= : not Equal to
Contains : case sensitive substring match
~Contains : case insensitive substring match
Not Contains : case sensitive substring not found
Contains Data : case insensitive substring not found
Is Empty
Number operators For evaluating “Number” data types, the following operators are also available, in addition to the operators listed above for String data (minus “Contains”):
> (Greater Than)
< (Less Than)
>= (Greater Than or Equal to)
<= (Less Than or Equal to)
Date operators For evaluating “Date” data types, the following operators are also available, in addition to the operators listed above for String and Number data:
IS WEEKDAY
IS WEEKEND
The third column provides a similar list of options to select a workflow value for comparison, or to also select “Advance, Code” to insert more advanced logic for the expression.
Right side operands for the expression can also be literal values. Use the Edit icon to the right of the column to manually enter a static value here. This will toggle the input to a standard input field to define a literal value. As usual, you can use the garbage can icon to delete any individual condition row as needed, when updating a given Output.
Once all applicable conditions have been configured, select “DONE” (which is the default value here) from this drop-down menu to indicate no further evaluations are needed:
Once outputs have been defined for a decision action, those outputs become available for use within the diagram.
# Finish Marker
The finish marker works in conjunction with the Workflow Events. The Finish Marker action is found in the designer within the “Logic and Control” category of actions. This action is intended to be used within a design to indicate the point at which the workflow should be considered successfully completed from a business process perspective. Typically, the Finish Marker would be at the end or near the end of a workflow definition, but this is not a requirement. Once any Finish Markers are reached within a workflow design, then the workflow will be considered as “Finished Successfully”, regardless of any future activity that may occur.
# For Each Array
Action Function: The For Each Array Activity is used to iterate or loop through repeating values in an array. Arrays can contain primitives, like
[
"Red",
"Green",
"Blue"
]
or objects as
[
{
"X":"x1"
},
{
"X":"x2"
}
]
or even nested arrays
[
[
"x",
"y",
"z"
],
[
"1",
"2",
"3"
]
]
In each loop, a specified variable will contain the loop instance value, and can be used as normal in the workflow design. The data to be iterated will either be the set of array values found at the top level of the array or can be the data specified with a JSONPath expression to the target data.
Example usage of For Each Array
The For Each Array can be synchronized or joined when all the outputs are completed using the 'Synchronize Array' action.
Action Outputs: This activity follows provides the below outputs
Step – Followed for each iterator value
Loop End – Followed when the end of the loop is reached
Action Properties:
Array Source Variable
The source variable with array data to use for iteration.
JSONPath
This property will be made available when the selected "Array Source Variable" is not a simple array variable. This property allows for a JSONPath expression to specify the search path in the source variable to use as the iteration source.
Loop Variable
The target variable to use in the iteration path. This may specify a standard variable, JSON Object, or local variable.
re reached within a workflow design, then the workflow will be considered as “Finished Successfully”, regardless of any future activity that may occur.
# Synchronize Array
Action Function: The Synchronize Array action will wait until reached for all of the paths executed from a selected 'For Each Array' action. The synchronization is based on a count of the entries matched by the respective 'For Each Array' array data or JSONPath matched data.
Action Properties:
For Each Action
A select list of 'For Each Array' actions within the current diagram.
# For Each App File
Action Function: For Each App File allows you to construct a loop (used in conjunction with the 'Next Loop' action), to iterate over all the files submitted to an application designer page via the 'File Upload' widget. Each loop iteration will store the current file into the specified "File Variable" (workflow variable whose type is file).
Properties:
App Id The application page's ID (required). This is the id for the app page that the files were uploaded to.
Entity Id The unique identifier used by the File Upload widget on an application page. If the entitiy id is omitted then all files associated with the app page will be returned and iterated over. Providing a valid entity id will limit the returned list of files to any file uploaded which corresponds to the app page's Id and the entity id.
File Variable File Variable to store the current file in.
Variable For Storing Error Message A variable to store any resulting errors from the action
# For Each Request File
Action Function: For Each Request File allows you to construct a loop (with Next Loop action if used in Serial), to iterate over all the files submitted with a request. Each loop will store the current file into the specified "Loop File Name" (a File Variable).
Properties:
Loop File Name
File Variable to store the current request file in.
**Question ** The name (mapping path name) of the question to limit to. Blank for all questions.
**Execution/Scope **
Allow working on the collection in parallel or serial.
# For Each Loop
Action Function: The For Each Loop Activity is used to loop through repeating values in an XML document for a given XML Iterator Variable. This action allows repeated execution of an activity or group of activities in serial or in parallel. The Next Loop Activity must be used if the execution is in serial to trigger this activity to execute the next step. The Synchronize Iterator action can be used to join all prior paths.
Example use of Serial execution: For a given set of records in a database lookup, loop through each and create a user account in a target application. The use of a timer action within the path can throttle the execution speed if the target system is unable to handle heavy volume.
Simple example of Serial Execution:
Example use of a Parallel execution: To expedite onboarding of an employee, each selected application for the new hire must be approved by different managers. Each application is submitted to approving managers in parallel, and once each manager has approved or rejected a given application, the workflow would continue and proceed to a technician for installation of the approved applications.
Simplified example of parallel execution:
Action Outputs: The For Each Loop Activity returns the following values
Empty Iterator – followed when the iterator has no entries
Step – Followed for each iterator value
Loop End – Followed when the end of the loop is reached
Action Properties:
Label
A label for the action
Properties:
XML Iterator (required)
Select the XML Iterator variable to be looped through. All existing XML Iterator variables declared in the initial Start step are available for selection.
Execution (required)
This property specifies the desired execution mode, and offers a drop-down menu with the following choices:
Serial – designates the activity is to be looped through each item in a collection in sequence, one at a time
Parallel – designates the action should simultaneously create execution paths for each iterated value
Empty Iterator Output
Selects the execution path to follow when the iterator is empty. Choices are “Loop End” and “Empty Iterator”
# For Loop
Action Function: The For Loop Activity can be used to start a loop within a workflow. It is useful for repeating workflow activities for a specified count. This action works in conjunction with the Next Loop Activity.
Action Outputs: The For Loop Activity outputs the following values:
Step – Indicates the loop step
Loop End – Indicates when end of the loop is reached
Variable Not Found – followed when the specified variable is not found
Invalid Count – followed when there is an invalid loop count
Simple For Loop layout
Action Properties:
Label
A text label for the activity
Properties:
Loop Variable
This property allows the user to specify the variable to use as the counter for the loop. As the For Loop action is executed subsequently in the workflow, The variable will be incremented by 1. By default if the variable is not initialized, it will start at 0, but may be set to some other value initially as the starting point for the loop.
Loop Count (optional)
This property allows the user to specify the loop count, an integer which will determine the number of iterations of the loop. (For example, if the Loop Count value is set to “5,” then the Loop Variable will be incremented from 1 to 5 accordingly for a given loop.)
The Loop Count property may be set to a fixed number, or set to reflect the value of a variable or custom expression via the field controls provided.
# Gate
Action Function: The Gate activity provides the ability to limit the amount of times the activity will continue. The Gate provides a control to merge prior activities and "fire" an output for a limited number of times. This activity is useful to merge one or more prior possible paths or to output only when the first activity completes which is mapped to this step. Additional workflow activities can be defined by following the output from this action. Additionally, the Gate activity can be used as a workflow design layout facility to support merging prior activities into a single output. (When used in this manner, the Max Pass Through should be set to ‘-1’ to allow unlimited pass through.)
Action Outputs: The Gate activity provides a single output which occurs based on configuration.
Action Properties:
Label
A text label for the activity
Properties:
Max Pass Through (required)
This property specifies the number of times to follow the output when the prior step (or steps) has completed. Typically, this value is set to '1'. The output will be followed for each prior step completion up to the number specified for this property. Use '-1' to allow unlimited pass through.
# Get Current DateTime
Action Function: The Get Current DateTime Action will get current date and time
Action Outputs: The action returns the following:
Success – The action successfully performed the operation
Failure – The action failed to perform the operation
Action Properties:
Label
A label for the activity.
Properties
Time Zone
The time zone to use as the local time zone
Date Format
The format to use for formatting the result into the target string variable
Formatted String
A target string variable to store the formatted time
Date Format
The format to use for formatting the result into the target string variable
UTC Date Output
A date variable to store the UTC datetime
Time Zone Local Output
A date variable to store the local datetime based on specified timezone
Variable For Storing Error Message
A variable to store any resulting errors from the action
# Math
Action Function: The Math Action takes two numbers as inputs and performs one of the following binary operations: Add, Subtract, Multiply, Divide or Modulo.
Action Outputs: The Math Action returns the following:
Successful – The action successfully performed the operation
Unsuccessful – The action failed to perform the operation
Action Properties:
Label
A label for the activity.
Properties
First Number
The first input of the operation
Second Number
The second input of the operation
Operation
The operation to be performed on the two inputs. Select from the following options:
Add (First Number + Second Number)
Subtract (First Number – Second Number)
Multiple (First Number * Second Number)
Divide (First Number/Second Number)
Modulo (First Number % Second Number)
Output Variable
Variable to store the result of the operation
Error Variable
Variable to store the error message (if any)
# Next Loop
Action Function: The Next Loop Activity can be used as the final activity in a looped process using a “For Loop” or a “For Each Loop” Activity to indicate the completion of the loop. This action will indicate to the “For Loop” or “For Each Loop” action to proceed to the next step.
Action Outputs: The Next Loop Activity returns the following:
- Next Step – followed to indicate the next step in the loop. (NOTE: This output must be connected directly to the respective “For” activity to trigger the action to execute its next process or completion accordingly.)
Action Properties:
Label
A label for the activity
# Replace Substring
The Replace Substring action will replace occurrences substrings, with optional pattern matching, within another string with a replacement string.
Action Outputs: The action has the following outputs
Failure – An issue was encountered in the action
Success – The action ran without issue
Action Properties:
Label
A label for the activity
Properties
String Variable
The source string variable with values to be replaced
Replacements
This property panel allows for one or more substrings to be specified to be replaced. One or more rows of rules may be specified with each row having the following properties.
Variable For Storing Results
The target variable to store the new string
Old Value - The substring to be replaced
New Value - The new value to replace the old value
Mode - The mode to use to replace the given substring. Options are Normal, Extended, Regex (CS), and Regex (CI)
# Run Workflow
Action function: The Run Workflow action allow running other workflow in synchronous mode.
Label
A label for the action in the diagram
Properties
Execution
Mode to run selected workflow.
Workflow
Workflow to run.
Wait For Workflow Result
Choose if this workflow will wait for this workflow to complete befor eit continues.
Send Content
Choose if you want this workflows content to be sent into the called workflow.
Return Values
Specify ouputs that the calling workflow might return so they can be mapped to output routes.
# Rule
The Rule action has been deprecated. Previously configured Rule actions will continue to run, however they have been removed from the Workflow Action palette. In workflow designs with Rule actions configured, workflow designers will be able to see what the rules are doing in plain text and adjust as needed directly in the text.
If the workflow designers need to do more than that, the Rule action will need to be replaced with a Decision action. The plain text from the Rule can be used as a guide when creating the Decision.
# Set Workflow Output
Action Function: The Set Workflow Output Activity is used within a called workflow to set the output value for a “Call Workflow” activity in the calling workflow. The calling workflow action must have a matching output value set to be followed.
In this simplified example, a workflow will call another workflow, “TestSub1” which will set its own output to be “Green” which is then followed out in the calling workflow.
Calling workflow:
Called workflow, “TestSub1”
Action Outputs: The Set Workflow output variable activity has no outputs.
Action Properties:
Label
A label for the activity.
Properties
Set Workflow Output (required)
This property specifies the output of the workflow to be followed in the “Call Workflow” action of the calling workflow.
# Split String to XML
Action Function: This action takes a string and parses it into XML/JSON. The string is split based upon a user defined delimiter character.
Action Outputs: The action has the following outputs:
Failure – some error occurred in executing the command
Success – The command was executed without error
Action Properties: The Split String to XML action has the following configurable properties.
String Variable *(required)
The string to be parsed into a Workflow Objects variable.
Delimiter *(required)
The character used to split the "String Variable" so it may be parsed into a Workflow Object.
- Example String Variable:
This, is, a, comma, delimited, string
Specifying the character ,
as the delimiter's value will split the string variable into
separate pieces using a comma to determine where the split should occur during the action's execution.
Variable For Storing Error Message
Specifies the variable which will store any error messages that occur.
XML Variable For Storing Results
Specifies which Workflow Object variable will be used to store the XML.
# String Length
Action Function: This action returns the character count for a given string.
Action Outputs: The action has the following outputs:
Failure – some error occurred in executing the command
Success – The command was executed without error
Action Properties: The String Length action has the following configurable properties.
String Variable *(required)
The string for which the value length will be determined. The length is determined by how many characters are contained within the string variable. Spaces and special characters are included in the total character count.
Variable For Storing Error Message
Specifies the variable which will store any error messages that occur.
Variable For Storing String Length
Specifies the variable used to store the total character count calculated based upon the "String Variable" property.
# Substring
Action Function: This action will return a substring obtained from the value of the "String Variable" property. The substring will start from the specified "Start" index and end at the index which is calculated by [ start + (numberOfCharacters - 1) ].
String Variable: 0123456
Start index: 2
Number of characters: 3
Substring Returned: 234
Action Outputs: The action has the following outputs:
Failure – some error occurred in executing the command
Success – The command was executed without error
Action Properties: The Substring action has the following configurable properties.
String Variable *(required)
The string from which the substring will be acquired.
Start (starting at 0)
Specify the starting index for the substring. Blank values will default the index to zero.
Number of Characters
Specifies the number of characters, starting at the defined "Start" property's index listed above, to acquire a subset of characters (substring) from the "String Variable" property.
Variable For Storing Error Message
Specifies the variable which will store any error messages that occur.
Variable For Storing Substring
Specifies the variable used to store the substring obtained from the "String Variable" property.
# Synchronize
Action Function: The Synchronize Activity synchronizes the execution of prior activities. The workflow will not progress past this action until all actions leading to this activity are completed.
Action Outputs: The Synchronize Activity automatically transitions out once all prior activities are complete.
Action Properties:
Label
A label for the activity.
# Synchronize Parallel XML Iterator
Action Function: This activity waits for all parallel activities to complete for a given “For Each Loop” activity. Once all the inputs complete then the workflow will continue.
Example usage: In a scenario where a selected set of software applications must be approved, with each software item requiring approval from a different manager, a For Each Loop activity can be used to trigger all of the approval activity to run in parallel. The Synchronize Parallel XML Iterator can then be used to hold the workflow progression until all approvals have been received.
Action Outputs: The Synchronize Parallel XML Iterator does not return any value. The activity will transition out once all the requisite prior paths have completed.
Action Properties:
Label
A label for the activity.
Properties
XmlIterator
This property is used to select the XMLIterator specified in the related For Each Loop step. The field will offer a drop-down menu of all existing XML Iterator Variables defined for the current workflow.
# Delay
Action Function: This action should be used when needing to add a delay to workflow of less than 1 minute. This action creates less resource load on the PMG workflow engine compared to a Timer action, particularly in high volume workflows involving timers. The Delay action also supports creating a random delay to help space out activities when multiple instances of the same workflow are running.
Action Properties:
Label
A label for the activity.
Properties
Fixed Seconds
A fixed amount of time in seconds to delay
Random Min Seconds
A minimum amount of time to delay for a new random time delay
Random Max Seconds
A maximum amount of time to delay for a new random time delay
# Get Current Date
Action Function: Will get the current date and time at the time it is ran, and allows for selecting the time zone and date format
Action Properties:
Label
A label for the action
Properties
Time Zone
The time zone to use for the returned date and time
Date Format
The syntax to use for the formatted returned date and time
Results Variable
The variable to store the result
# Format Date
Action Function: Formats a provided date from a date variable or string into the specified output format
Action Properties:
Label
A label for the action
Properties
Date
The date (and time) to be formatted
Date Format
The syntax to use for the formatted returned date and time
Results Variable
The variable to store the result
# Add to Date
Action Function: Will add a timespan to a given date and time
Action Properties:
Label
A label for the action
Properties
Date
The date (and time) to be begin with
Timespan to Add
The amount of time as a timespan to add to the date. Timespan format is 0.00:00:00, as d.hh:mm:ss
Output Variable
The variable to store the result
# Set Workflow Return Value
Action Function: Sets the return value for a Workflow ran as a “Workflow Action”. See “Workflow Functions” for more information on defining workflows as actions.
Action Properties:
Label
A label for the action
Properties
Set Workflow Return Value
Specifies the Return Value of the workflow as an action, which can be used by the calling workflow diagram for routing