Swimlanes
Introduction
A Swimlane is an editor Component that allows defining Access Control over Process Tokens. Through a Swimlane, you can choose which Participants are allowed to access the Tokens placed on the components contained in the Swimlane itself. A Swimlane Participant can be either a single User, a Group, or Role (see Users, Gruops and Roles). The Participant value can also be determined at runtime through a script. Moreover, a Sentry expression can be added to enforce Access Control conditions that cannot be expressed via a single User, Group or Role.
Adding a Swimlane
- To add a Swimlane to your Process, you can either:
- Right-click on an empty place in the Editor and select Add Swimlane from the context menu.
- Drag a Swimlane from the Component Library onto the Process Model.
- Set the properties of your Swimlane (see Swimlane Properties ).
- To adjust the position and size of the Swimlane, move the cursor over the Swimlane header and drag it to another position. Click on the bottom border of the Swimlane and drag the cursor to change the Swimlane height.
- To delete a Swimlane, right-click on it and select Delete Element from the context
Swimlane Properties
Property | Description |
---|---|
Task List Name | Task name as displayed in a Task List or in FNZ Studio Runtime |
Color | Swimlane color |
Participant | (Required) This property defines Access Control conditions on the token for user/s at design time. Select a User, Group or Role (Users, Gruops and Roles) associated with the Sub-Process from the dropdown list, or enter a script to define such user/s (see details). |
Sentry Evaluation |
This property defines when the conditions set in the Sentry property below are evaluated:
|
Sentry |
This property defines further Access Control conditions for user/s (in addition to the conditions defined in the Participant field):
|
Workqueues
When a Token reaches an activity included in a Swimlane with a Participant, the activity needs to be assigned to a Workqueue. A Workqueue is a virtual object, defined only by its name. There are implicit Workqueues for Users, Groups and Roles:
- The name of a Workqueue for a User is equal to the User Id.
- The names of Workqueues for Roles and Groups look like
GROUP:GroupName
andROLE:RoleName
.
By using expressions on a Swimlane, a Task can be assigned to an arbitrary Workqueue. The expression is expected to return a String. The result is treated as Workqueue name.
Example Expressions:
'ROLE:LegalOfficer'
IF($amount > 1000,'GROUP:Compliance','GROUP:Backoffice')
GetSupervisor($employeeId)
'User1234'
The Expression is evaluated whenever a Participant Activity is enabled in the Swimlane. The result of the evaluation determines the Workqueue name for the current Activity, but has no effect on other, existing Tasks in the same Swimlane. The information to which Workqueue an Activity has been assigned is saved in the Token.
The value of the Workqueue of a specific Process Token at runtime can be inspected in FNZ Studio Composition under Solution Maintenance > Process Instances > [Process Instance] > Details > Tokens tab > [Token] > View. The Workqueue is shown in the Queue Name field.
The Workqueue of a Token can be changed through reassignments. Reassignment can be performed either by clicking the Assign button on the Token, or through a Script Functions such as AssignWorkitemToUser
.
Note on Sentries Upon access, after checking the Participant/Workqueue conditions, the Sentry expression (if set) is evaluated. The return value of the Sentry expression defines whether access to the token is granted or denied. An example of Sentry expression could be a condition that checks the value of a user preference against the value stored in the Process Instance attributes.
An example of a Sentry expression is:
Integer $requiredAccessLevel := TOINTEGER(ProcessInstanceGetAttribute(ProcessInstanceId(), 'level'));
Integer $userAccessLevel := User:Get(User:CurrentUserGetId()).getPreference('level');
If $userAccessLevel >= $requiredAccessLevel Then
Return Process:SwimlaneSentryState.ALLOW_ACCESS();
Else
Return Process:SwimlaneSentryState.DENY_ACCESS();
End
Use Cases
Assigning a Swimlane to the Current User
Let's suppose you want to set the participant user expression of a Swimlane to the User who initiates the first task in that Swimlane.
It is fairly easy to access the current user in context in FNZ Studio, as the Platform provides the following two functions out of the box:
User:Get()
– Returns the currently logged-in User object (providing access to all the User’s attributes like the userId, first and last name, and user preferences)User:CurrentUserGetId()
– Returns the userId of the currently logged-in User
The two functions above retrieve the User from a thread local variable set when the User establishes a new session with the server.
Potential Issues
There are many scenarios where the User:Get()
and the User:CurrentUserGetId()
functions are adopted as an easy solution to access the current user. In most of those scenarios, however, the developer perhaps forgets to consider the consequences in case those operations are executed when a user is not in context.
For this reason it is recommended you ask yourself the following questions before using the User:Get()
or the User:CurrentUserGetId()
functions:
- Is this function always called in the context of an HttpRequest?
- Is there any potential troubleshooting activity on the backend that triggers a call to this function?
- Does my script still behave properly even if the function returns
null
?
Whenever the User:Get()
and User:CurrentUserGetId()
functions are called in the context of an HttpThread, they correctly return the current, logged-in User who submitted the request.
If those functions are called by a background thread, however, they do not have access to the aforementioned HttpThread local variable. This means the return value generated by a background thread will be null.
The following two example scenarios examine the issues in more detail.
Scenario #1 — Redirects
In this Process, the developer assumes that the User starts the task by clicking on a link or on a button, triggering an HTTPRequest.
The first task ('Now') is correctly assigned to the User who clicked the link. After the Redirect Task, however, the Process Tokens are managed by a background thread — a thread that does not have access to the current user in context (as, technically, the user is not in context anymore).
For this reason, the second task ('Later') is suspended: The engine is not able to evaluate the participant user expression set on the Swimlane when the token gets there. This situation is shown in the following figure:
A suggested solution is to define a variable (e.g. $creator
), the value of which defaults to User:CurrentUserGetId()
, but that "remembers" the value returned by the User:CurrentUserGetId()
function at the time the Process was started - and keeps it in case any background processing happens. This approach is illustrated in the figure below:
Scenario #2 — Calls
Even if there is no Redirect or Intermediate task that hands over the control to a background thread it is still not a good idea to use the User:CurrentUserGetId()
function directly in the Swimlane's Participant User Expression.
The call to the backend system illustrated in the figure above can fail, leading to the system administrator needing to issue a 'retry' action from the console:
Unfortunately, even if the retry operation is successful, this scenario also sees the execution of the retry handled by a background thread (because the original creator of the task is gone). With a Process design such as that illustrated above, the Process is again suspended due to the missing participant in the Swimlane expression.
In this case, it is recommended to:
- Introduce appropriate
null
checks - Use other techniques, such as the one explained in the first scenario, that can mitigate the risk of a "null" user in context