Using Triggers
You need to understand the concepts of states to get a clear understanding of when Job-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 Job 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 Job changes its status, same as Before Process On Change.
- Before Process Pre Running: Before the Pre RunningAction code is executed.
- Before Process Post Running: Before the Post RunningAction code is executed.
- Before Process User Change: Before the process or Workflow is modified.
- Before User Message Operation: When a user interacts with a user message. (This only fires for Jobs 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 Job, Operator Message, Event or alert. It does not apply to changes in Queue status or Job Server status, for example or to changes made by the system.
Tabs and 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.
Warning: 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 17. 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 from the Monitor screen. There, the Detail View lists the runtime details of the currently selected Job. The Trigger-related log file name is located under the Detail View'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 Triggers screen (), 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 Job is derived from the Queue; for example, the Partition of a Job that ran on the GLOBAL.System Queue is thus GLOBAL. This means that the following Triggers only fire for Jobs 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 Job-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 Jobs can be affected. Test your Triggers well and always start by excluding as many Jobs as possible as early as possible.
If you set a new Queue on a Job 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 Job. 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. Make sure you ignore any changes made by the Trigger in your Trigger code.
Context Menu
Triggers support the following context menu options.
Note: For generally applicable Object context menu options, see Object Context Menu.
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 |
Delete | Delete the Trigger |
New Trigger | Create a new filter |
Job-Related Trigger Execution
Job-related Triggers fire at specific times during the life cycle of a Job. The Trigger Points are named after the Job Definition actions they precede; for example, Before Job Definition On Change fires immediately before a On Change Action on a Job Definition, if specified. If a file search is configured on the Job 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 Job Definition. Note, also, that no Trigger Points fire for status Canceled.
Before Job Definition On Change and Before Job 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 Job Definition Pre Running
These Triggers fire before the Job is set to status Running and, if applicable, any pre-running Action on the Job Definition.
Before Job Definition Post Running
These Triggers fire before Job 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 Jobs.
- When a user message is created, forwarded, delegated, and replied to.
- When an attachment is added (before being uploaded) and uploaded.
Before Job User Change
This Trigger fires when a user attempts to save a modified Job, or when the Job is created in a user session, including when a Job is resubmitted or in a recurrence. For example, if a user attempts to change the Queue of a Job in the Run Wizard. This Action fires immediately after the user has chosen Run, before the Job has been persisted to the database. It allows you to veto certain specific modifications to Jobs.
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 class must:
- Inherit from the stub.
- 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 Folders for Objects that can have Folders.
Note: The Before Definition Change Trigger Point does not apply to any change to a Job, Operator Message, Event or alert. It does not apply to changes in Queue status or Job 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. Make sure you ignore any changes made by the Trigger in your Trigger code.
Before Job On Change and Before Job On Change Maintenance
These Triggers fire before a Job gets status Queued for each status change and allow you to interact with the Job. It does not fire when a Job reaches or leaves status LockWait nor does it fire for status Canceled.
Before Job Pre Running
This Trigger fires when a Job is about to leave status Queued and allows you to interact with the Job; this is the last Trigger Point at which you can prevent the Job from starting. The Job Pre Running action code is executed immediately after this Trigger code, if specified on the Job Definition. Note that the Pre Running action of the Job Definition can also prevent the Job from running.
Before Job Post Running
This Trigger fires when a Job is about to leave status Running and before the Post RunningAction code on the Job is executed.
On Job 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 Job 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
Security
The privileges available in the Security tab are as follows.
For more information, see Security Tab.
Privilege | Description |
---|---|
Trigger.Create | Create Triggers |
Trigger.Delete | Delete Triggers |
Trigger.Edit | Edit Triggers |
Trigger.View | Access Triggers |
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 |
Folder | 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 Job has the same Partition as the Queue it ran in.
Example
This example Trigger checks if Job or Workflow Definitions have a Folder, and throws an exception if they do not. This Trigger allows you to force users to put Job Definitions and Workflow Definitions in Folders.
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);
}
}
}