Using Triggers
You need to understand the concepts of states to get a clear understanding of when process-related triggers and actions fire, see the States section for more information on the subject.
You can have multiple triggers for one trigger point, the sequence in which the triggers are executed inside a trigger-point are defined in the Execution Order field.
The following trigger-points are available:
- Before Definition Change - before the definition of an object is changed
- Before Process On Change - when a non-maintenance process changes its status until it reaches status Queued (except for the transition LockWait > Queued); it does not fire for status Canceled
- Before Process On Change Maintenance - when a maintenance process changes its status, same as Before Process On Change
- Before Process Pre Running - before the PreRunningAction code is executed
- Before Process Post Running - before the PostRunningAction code is executed
- Before Process User Change - before the process or chain is modified
- Before User Message Operation - when a user interacts with a user message (This only fires for processes of type
UserMessage
) - On File Content Access - when a user accesses output
note
The Before Definition Change trigger-point does not apply to any change to a process, operator message, event or alert. It does not apply to changes in queue status or process server status, for example or to changes made by the system.
Tabs & Fields
Tab | Field | Description |
---|---|---|
Trigger | Partition | The partition of the trigger defines its scope. |
Trigger | Name | The name of the trigger. |
Trigger | Description | The description of the trigger. |
Trigger | Application | The application the trigger belongs to. |
Trigger | Enabled | When the trigger is enabled, the trigger is activated at the appropriate time for the trigger. When the trigger is disabled, the code will not be executed. |
Trigger | Trigger Point | The type of trigger; see above list of trigger points |
Trigger | Execution Order | The order in which this trigger is executed; only relevant where there is more than one enabled trigger for a specific trigger point. |
Trigger | Library | The library used by the trigger; the library usually contains shared packages and classes for use in multiple objects. |
Trigger | Log Level | Verbosity level of logging. |
Trigger | Max Backup Files | The maximum number of log files. |
Trigger | Max Log Size | The maximum size in MB of each file. |
Trigger | Action Subject | The subject as which the trigger code will be executed. If you want to use jcsSession (SchedulerSession) in your trigger code then you must set the Action Subject. |
Trigger | Source | The trigger source to execute. |
Trigger | Stub Source | The stub source contains predefined objects for use in your trigger code. Note that jcsSession is not listed as long as you have not set the Action Subject and saved the trigger. |
Documentation | Documentation | A comment about the object, can be used for documentation purposes. |
Security | * | This is where you can specify who can access/change/remove the trigger. |
RedwoodScript
The code you write must be valid RedwoodScript; note that only a subset of Java classes are available for use in triggers. You import your own class from your library for use in a trigger. Redwood recommends to store as much of the code as possible in a library, especially if you plan on reusing it in other triggers or actions.
note
You must never persist a session in your trigger code, that is done for you at a later point.
By default, RedwoodScript is based on Java 11; you set the /configuration/javatoolkit/SourceVersion
and /configuration/javatoolkit/TargetVersion
registry entries to your desired version and can use all the features of the version you specify.
Trigger Logging
Triggers log to files using the Java logging mechanism. If you set the log level above the log level of the Redwood Server installation, the log entries will also be logged to the default trace file of Redwood Server; its location depends on your application server. On Redwood Platform, triggers log to <install_dir>/j2ee/cluster/server1/log/scheduler/triggers/
and the default trace file is <install_dir>/j2ee/cluster/server1/logs/scheduler.log
.
The five trigger points listed below, when executed, generate a separate log file that is accessible by selecting the Monitoring > Processes section in the navigation bar. From there, the process preview pane lists the run-time details of the currently selected process. The trigger-related log file name is located under the preview pane's Files heading. The trigger points and the log file name they generate are listed below.
- Before Process On Change -
stdonchange.log
- Before Process On Change Maintenance -
stdonchange.log
- Before Process Pre Running -
stdprerunning.log
- Before Process Post Running -
stdpostrunning.log
- Before Process User Change -
onbeforeuserjobchange.log
The two trigger points listed below, when executed, generate a separate log file that is accessible from the Scripting > Triggers section of the navigation bar, providing the Trigger Log Level field is not set "None". Select the desired trigger, then click on the Actions button, then select Download Log. The trigger points and the log file name they generate are listed below.
- Before Definition Change -
BeforeDefinitionChange.<Partition_name>.<Trigger_name>.log
- On File Content Access -
OnJobFileContentAccess.<Partition_name>.<Trigger_name>.log
These two trigger points also allow for log file rollover. You specify the maximum number of files ( Max Backup Files ) and the maximum of each file ( Max Log Size ). As soon as a log file reaches the maximum size, a new file is created provided the maximum number of individual log files has not been reached. When maximum number of log files has been reached and all files are the maximum size, the oldest is overwritten. This allows you to control the maximum space the trigger logs will use on your system.
The final trigger point listed below, when executed, writes only to the default trace file, if the log level is high enough.
- Before User Message Operation -
scheduler.log
Trigger Scope
Triggers fire for all objects that share the same partition as the trigger. There are special System Wide triggers (for example, System_SystemWide_BeforeDefinitionChange), which fire for all objects in all partitions. Note that the partition of a process is derived from the queue; for example, the partition of a process that ran on the GLOBAL.System queue is thus GLOBAL. This means that the following triggers only fire for processes that ran on a queue that is in the same partition as the trigger:
- Before Process On Change
- Before Process On Change Maintenance
- Before Process Pre Running
- Before Process Post Running
- Before Process User Change
Trigger Executions
The Before Process On Change and Before Process On Change Maintenance triggers fire at least twice, once when switching from New to Scheduled and again from Scheduled to Queued. Other process-related triggers might fire several times depending on your code. Note that you can create endless loops in triggers, and that these can have severe consequences as many processes can be affected. Test your triggers well and always start by excluding as many processes as possible as early as possible.
When you set a new queue on a process in a Before Process Pre Running trigger, the trigger will fire again for the change to the new queue. This can be dangerous, especially if you do not ensure the trigger will not change the queue the second time the code executes for that process. You can end up in an endless loop.
warning
When you create or modify objects in your trigger code, these changes might fire the trigger and you potentially end up in an endless loop; you need to ensure that you ignore any changes made by the trigger in your trigger code.
Context-Menu
Triggers support the following context-menu actions:
Action | Description |
---|---|
Disable/Enable | Disable/Enable the trigger |
Download Log | Download the log file of the trigger (Only available for Before Definition Change and On File Content Access triggers, when a log file exists) |
Duplicate | Make a copy of the trigger to create a similar one |
Edit | Edit the trigger |
Edit Security | Edit the security of the trigger |
Export > Export | Export the trigger into a CAR file |
Export > Export with related objects | Export the trigger into a CAR file including referenced objects |
Promote > Promote to system | Promote the object to a remote system |
Promote > Edit further then promote | Edit the export rule set prior to promoting |
Promote | Promote the trigger to another Redwood Server instance |
Delete | Delete the trigger |
Show permalinks | Show links that can be used from third party applications to link to the object |
Add to navigation bar | Add the current object to the navigation bar |
New trigger | Create a new filter |
Filter > New Filter | Create a new trigger filter |
Filter > Edit Filter | Edit current trigger filter |
Filter > Delete | Delete current trigger filter |
Filter > Duplicate Filter | Create a copy of the filter |
Filter > Export Filter | Export the filter into a CAR file |
Filter > Add to navigation bar | Add the filter to a navigation bar |
Filter > Create filter from search | Create a filter from the current IntelliSearch query |
Process-Related Trigger Execution
Process-related triggers fire at specific times during the life-cycle of a process. The trigger points are named after the process definition actions they precede; for example, Before Process Definition On Change fires immediately before a On Change action on a process definition, if specified. If a file search is configured on the process definition, that always fires first, followed by any Before Process Post Running triggers, followed by any Post Running actions, if specified.
Note that triggers fire even if no actions are specified on the process definition. Note, also, that no trigger points fire for status Canceled.
Before Process Definition On Change and Before Process Definition On Change Maintenance
These triggers fire for the following status changes:
- New -> Scheduled
- New -> Held
- Held -> Scheduled
- Scheduled -> Held
- Scheduled -> EventWait
- EventWait -> Scheduled
- Scheduled -> Queued
Before Process Definition Pre Running
These triggers fire before the process is set to status Running and, if applicable, any pre running action on the process definition.
Before Process Definition Post Running
These triggers fire before process is set to a final status, except Canceled. The final statuses this trigger point fires before are Completed, Error, Killed, and Unknown.
Before On User Message Operation
These triggers only fire for user message processes.
- when a user message is created, forwarded, delegated, and replied to
- an attachment is added (before being uploaded) and uploaded
Before Process User Change
This trigger fires when a user attempts to save a modified process or chain, or when the job is created in a user session, including when a job is resubmitted or in a recurrence. For example, a user attempts to change the queue of a process using the submit wizard. This action fires immediately after the user has chosen Submit, before the process has been persisted to the database. It allows you to veto certain specific modifications to processes or chains.
Writing Trigger Code
When you write trigger code, you have the choice between creating your own class and writing directly between curly brackets {}
.
If you choose to surround your method with curly brackets, it will be added to the execute()
method of the stub class.
Your own class must:
- inherit from the stub
- must implement a
public void execute()
Before Definition Change
This trigger fires before changes made by users are persisted to the database. You use it to ensure that a user has filled in all fields, for example. See the example below to force users to specify applications for objects that can have applications.
note
The Before Definition Change trigger-point does not apply to any change to a process, operator message, event or alert. It does not apply to changes in queue status or process server status, for example or to changes made by the system.
warning
When you create or modify objects in your trigger code, these changes might fire the trigger and you potentially end up in an endless loop; you need to ensure that you ignore any changes made by the trigger in your trigger code.
Before Process On Change and Before Process On Change Maintenance
These triggers fire before a process gets status Queued for each status change and allow you to interact with the process. It does not fire when a process reaches or leaves status LockWait nor does it fire for status Canceled.
Before Process Pre Running
This trigger fires when a process is about to leave status Queued and allows you to interact with the process; this is the last trigger point at which you can prevent the process from starting. The process pre-running action code is executed immediately after this trigger code, if specified on the process definition. Note that the pre-running action of the process definition can also prevent the process from running.
Before Process Post Running
This trigger fires when a process is about to leave status Running and before the PostRunningAction code on the process is executed.
On Process File Content Access
This trigger fires as a user attempts to open output.
When you throw an exception (to prevent the user from accessing the process file), you can send a message to the user. If the message starts with <HTML>
, then the message will be sent in HTML.
System Wide Triggers
For each of the trigger-points a System Wide trigger can be defined. This must be defined in the GLOBAL partition and have a name matching the trigger point type, prefixed with System_SystemWide_
; note that the System_
prefix is reserved for system-specific and system-wide objects.
The complete list of System Wide triggers are:
System_SystemWide_BeforeDefinitionChange
System_SystemWide_BeforeJobOnChange
System_SystemWide_BeforeJobOnChangeMaintenance
System_SystemWide_BeforeJobPreRunning
System_SystemWide_BeforeJobPostRunning
System_SystemWide_OnJobFileContentAccess
Finding Triggers
You can search for triggers using filters and the Search Triggers box on the Triggers tab. This box is known as the IntelliSearch box and located under your username on the top right-hand side of the user interface. Filters allow you to specify a list of objects with static criteria. IntelliSearch allows you to specify complex queries in a simple way using prefixes. Prefixes are used to specify which property you are searching in and have short as well as long syntaxes. For example, if you want to display all triggers with the term trigger in the comment, you would use the search criteria as follows:
c:trigger
You can search more than one property, as follows:
c:trigger n:JV
note
No spaces should be entered before or after the colon (:).
See the Advanced Object Search for more information.
The following table illustrates the available prefixes for triggers:
Prefixes | Description |
---|---|
n, name | searches the name property |
c, comm, comment | searches the documentation property |
d, desc, description | searches the description property |
a, application | searches the application property |
cb, changedbefore | (internal) search for triggers that changed before a certain ISO-8601 period |
Security
Privilege | Description |
---|---|
Trigger.Create | Create triggers |
Trigger.Delete | Delete triggers |
Trigger.Edit | Edit triggers |
Trigger.View | Access triggers |
You can grant privileges on two levels, Access and Admin; a privilege granted on Admin level allows the grantee to grant the privilege to other users. These privileges can be granted per partition or system-wide.
The Security tab allows you to specify which users can access, edit, and delete the trigger.
Contexts
For each trigger point, a set of objects are predefined in the context for you to use. Once you have chosen your trigger-point, you can refresh the Stub Source from the context-menu to display the list of predefined objects with their classes (so that you can use the API documentation to lookup the available methods). The objects jcsOut and jcsOutLog write to the same file, the latter uses the Redwood Logging Syntax, which allows you to specify a severity (info, warning, error, fatal, debug) and includes a time-stamp.
The following tables illustrate the predefined objects, their classes as well as a simple example.
Before Definition Change
Object | Class | Example Code |
---|---|---|
jcsOutLog | com.redwood.scheduler.infrastructure.logging.api.Logger | jcsOutLog.fatal("This is a fatal error message!"); |
jcsTriggerContext | com.redwood.scheduler.api.scripting.variables.TriggerScriptObject | jcsTriggerContext.getSchedulerEntity(); |
Before Process On Change
Object | Class | Example Code |
---|---|---|
jcsOutLog | com.redwood.scheduler.infrastructure.logging.api.Logger | jcsOutLog.warn("This is a warning and gets printed to the stdonchangelog file on the process."); |
jcsOnChangeContext | com.redwood.scheduler.api.scripting.variables.PreExecutingActionScriptObject | jcsOnChangeContext.setFailJobOnError(false); |
jcsSession | com.redwood.scheduler.api.model.SchedulerSession | jcsSession.getUserName() |
jcsJob | com.redwood.scheduler.api.model.Job | jcsJob.hold(); |
jcsOut | java.io.PrintWriter | jcsOut.println("This text will be printed to a specific output file on the process."); |
Before Process Pre Running
Object | Class | Example Code |
---|---|---|
jcsOutLog | com.redwood.scheduler.infrastructure.logging.api.Logger | jcsOutLog.info("This is an informational message!") |
jcsSession | com.redwood.scheduler.api.model.SchedulerSession | jcsSession.getQueueByName("UNIX_Generic"); |
jcsJob | com.redwood.scheduler.api.model.Job | jcsJob.hold(); |
jcsPreRunningContext | com.redwood.scheduler.api.scripting.variables.PreExecutingActionScriptObject | String strNewStatus = jcsPreRunningContext.getNewStatus(); |
jcsOut | java.io.PrintWriter | jcsOut.println("This text will be printed to a specific output file on the process."); |
Before Process Post Running
Object | Class | Example Code |
---|---|---|
jcsOutLog | com.redwood.scheduler.infrastructure.logging.api.Logger | jcsOutLog.debug("This is a debug message!") |
jcsPostRunningContext | com.redwood.scheduler.api.scripting.variables.PostRunningActionScriptObject | |
jcsSession | com.redwood.scheduler.api.model.SchedulerSession | jcsSession.getSchedulerEntity() |
jcsJob | com.redwood.scheduler.api.model.Job | jcsJob.restart(); |
jcsOut | java.io.PrintWriter | jcsOut.println("This text will be printed to a specific output file on the process."); |
Values
Field | Description |
---|---|
Partition | The partition of the trigger, this also defines the scope of the trigger as it will only effect trigger-points of objects that are in the partition of the trigger. |
Name | The name of the trigger |
Application | The application the trigger resides in |
Description | A description of the trigger |
Documentation | The comment for the trigger, helpful for other users to understand your trigger |
Enabled | Only enabled triggers will have effect |
Execution Order | The order at which the triggers are executed for one same trigger-point |
Library | Your library of classes to use within the trigger |
Log File Enabled | Should the trigger actions be logged? This is helpful for troubleshooting your trigger |
Source | The source code of the trigger |
Stub Source | The source stub, which contains the stub code with predefined objects |
note
A process has the same partition as the queue it ran in.
Example
This example trigger checks if process definitions or chains have an application, and throws an exception when this is not the case. This trigger allows you to force users to put process definitions and chain definitions in applications.
See the Trigger Examples topic for more examples of triggers.
import java.text.MessageFormat;
import com.redwood.scheduler.api.model.JobDefinition;
{
Object o = jcsTriggerContext.getSchedulerEntity();
if (o instanceof JobDefinition)
{
JobDefinition jDefinition = ((JobDefinition) o);
if ( jDefinition.getParentApplication() == null)
{
String message = jDefinition.getName() + " has no application!";
jcsOutLog.info(message);
throw new RuntimeException(message);
}
}
}
See Also
- Trigger Examples
- Granting and Revoking System Privileges
- Granting or Revoking Object Privileges
- Documenting Objects using the Documentation Tab
OnBeforeJobUserChange OnUserMessageOperation PreRunning PostRunning