Trigger and Action Examples

This topic provides examples of triggers to show you what can be done.

Tune Scheduling Parameters at Runtime

You can use a Before Process Pre Running trigger to change scheduling parameters.

Request 1

Processes from many Process Definitions should run in a Queue specified in a parameter if the Queue is open.

Solution 1

Copy
{
  //get Parameter and Queue

  JobParameter jParameter = jcsJob.getJobParameterByName("Queue");
  Queue q = jcsSession.getQueueByName(jParameter.getInValueString());

  if (jParameter != null && q.isOpen())
  {
    jcsOut.println("Setting process to run in Queue from JobParameter " + jParameter.getInValueString());
    jcsOutLog.info("Setting process to run in Queue from JobParameter " + jParameter.getInValueString());
    //Set Queue on the job
    jcsJob.setQueue(q);
  }
}

Note: The output and log will be attached to the process. You must specify an Action Subject for jcsSession (SchedulerSession) to be available.

Alternate Request 1a

Processes from a few Process Definitions should run in a Queue specified in a parameter if the Queue is open.

Solution 1a

Copy
{
  //get Parameter and Queue

  JobParameter jParameter = jcsJob.getJobParameterByName("Queue");
  Queue q = jcsSession.getQueueByName(jParameter.getInValueString());

  if (jParameter != null && q.isOpen())
  {
    jcsOut.println("Setting process to run in Queue from JobParameter " + jParameter.getInValueString());
    //Set Queue on the job
    jcsJob.setQueue(q);
  }
}

Overrule Errors

You use Before Process Post Running triggers to influence the final state of a process.

Request 2

A process reaches status Error because the exit code is higher than 0. You want to override this, as exit codes 15 to 24 are in fact just warnings.

This should be done for most Process Definitions.

Solution 2

You specify a parameter ReturnCodeMapToWarning, which contains a range, 15-24 in this case, on the Process Definitions for which you wish to override the final status.

You specify a Before Process Post Running trigger like the one below:

Copy
{
  JobDefinition jDefinition = jcsJob.getJobDefinition();

  // Only run for user defined process definitions
  if (jDefinition.getBehavior().longValue() == 0)
  {
    // Will contain ReturnCodeMapToWarning parameter if it exists
    JobParameter jp;
    // Will contain the range of codes to map to warning.
    String mapToWarning;
    // Is it in the range.
    boolean inRange;
    Long returnCode;

    // Look for the ReturnCodeMapToWarning parameter
    jParameter = jcsJob.getJobParameterByName("ReturnCodeMapToWarning");
    if (jParameter == null)
    {
      //Parameter does not exist, do nothing
      mapToWarning = null;
    }
    else
    {
      mapToWarning = jParameter.getInValueString();
    }

    // Only do mapping if there is a sensible value
    if (mapToWarning != null && mapToWarning.length() >= 0)
    {
      returnCode = jcsJob.getReturnCode();
      if (returnCode == null)
      {
        // Handle null as 0
        returnCode = new Long(0);
      }

      // Use jcsSession.inRange to determine if the code is in range.
      if (jcsSession.inRange(returnCode.intValue(), mapToWarning))
      {
        JobNote jn = jcsJob.createJobNote();
        jn.setText("Setting status to Completed as "
                   + jcsJob.getReturnCode()
                   + " is in "
                   + mapToWarning);
        jcsPostRunningContext.setFinalStatus(JobStatus.Completed);
      }
    }
  }
}

Note: You must set an Action Subject for jcsSession (SchedulerSession) to be available.

Alternate Request 2a

Only a few Process Definitions are concerned.

Alternate Solution 2a

You specify a post-running action on the processes concerned by this. Triggers fire for all processes, if you specify the action on each Process Definition that is concerned by this, you can save processor cycles. Note that you will have to add the action to each Process Definition, though.

The code for the action is the same as for the trigger.

Change Status According to output

Request 3

Processes reach status Completed because the return code is 0, however, you want the process to reach status Error when an error was reported in the output of the process. A lot of Process Definitions are concerned by this issue.

Solution 3

You specify a parameter containing the pattern to search for. The pattern should match the error as found in the output file. In this example, the error appears in the process file stdout.log

For example, an error in the process will be printed as follows:

Copy
myprog: cannot access /u01/backup/example: No such file or directory

In this case, the ErrorSearch parameter could be set to No such file or directory, for example.

You use the Before Process Post Running trigger code below:

Copy
import com.redwood.scheduler.api.model.*;
import com.redwood.scheduler.api.model.enumeration.*;
import com.redwood.scheduler.api.search.*;

{
  JobParameter jParameter = jcsJob.getJobParameterByName("ErrorSearch");
  if (jParameter != null)
  {
    String errorSearch = jParameter.getInValueString();
    JobFile jf = jcsJob.getJobFileByName("stdout.log");
    SearchResultSet rs = jf.search(errorSearch);
    while (rs.next() && rs.getSearchResult().wasFound())
    {
      SearchResult sr = rs.getSearchResult();
      jcsOut.println("Found " + errorSearch + " at " + sr.getLineNumber());
      jcsOut.println(sr.getLineText());
      jcsPostRunningContext.setFinalStatus(JobStatus.Error);
    }
  }
}

Alternate Request 3a

Only a few Process Definitions are concerned.

Alternate Solution 3a

You specify a post-running action on the process concerned by this. Triggers fire for all processes, if you specify the action on each Process Definition that is concerned by this, you can save processor cycles. Note that you will have to add the action to each Process Definition, though.

The code for the action is the same as for the trigger.

Check User Access to Process Files

Request 4

Users have access to output they should not be able to access, you want to ensure that only authorized personnel have access. Your users have roles representing their respective teams. You use the value of a parameter to define which team the process belongs to. When this parameter does not exist, no further restrictions apply. This trigger does not alleviate roles and object privileges, it only restricts the access a little more.

Solution 4

The following On Process File Content Access trigger code illustrates how you can control access to process files.

Copy
{
  //initialize the team, get the process and its parameter
  String uTeam = null;
  Job process = jcsJobFile.getJob();
  JobParameter jParameter = process.getJobParameterByName("TEAM");

  if (jParameter != null)
  {
    //Get the value of the parameter
    String jteam = jParameter.getInValueString();

    //iterate through the users roles
    for (SubjectRoleGrant o : jcsSubject.getAssignedSubjectRoleGrants())
    {
      String role= o.getGrantedSubject().getName();
      //Compare each role with the required one
      if (role.equals(jteam))
      {
        uTeam = role;
      }
    }
    //if the team is null, users have no access
    if (uTeam == null)
    {
      throw new Exception("Access denied");
    }
  }
  //Parameter does not exist, access granted.
}

See Also

Triggers