View source | Discuss this page | Page history | Printable version   
Toolbox
Main Page
Upload file
What links here
Recent changes
Help

PDF Books
Show collection (0 pages)
Collections help

Search

ERP 2.50:Developers Guide/Concepts/Process Scheduling

ERP 2.50:Developers Guide

Index


Contents

Overview

Openbravo Process Scheduling is a framework to provide developers and users with finer control over process scheduling and monitoring within Openbravo ERP. Openbravo ERP release 2.50 leverages the power and flexibility of the Quartz Job Scheduling Framework.

Glossary

Process
Refers to a unit of work that can be scheduled to execute in the application's Scheduler.
ProcessBundle
Is the detail of a Process, which includes identifying, contextual and security information, parameters and a log of the process' execution.
Scheduler
Manages the execution of Processes (Jobs).
Job
Is the Quartz representation of what Openbravo ERP calls a Process - a unit of work that can be scheduled to execute.
Trigger
Is a definition of the instance(s) of time when a Process should be executed. A Quartz Job is scheduled in the Scheduler with a specified Trigger.

Why Quartz?

Quartz is a robust, scalable and extensible open source process scheduling framework that can be integrated into virtually any Java EE or Java SE application. There are a number of reasons why Quartz is especially suitable to Openbravo ERP as a process scheduling framework;

On top of its extensibility, Quartz provides a very flexible range of scheduling options, including nearly any combination of the following:

Quartz Configuration

The Quartz jar is included in the lib/runtime folder and org.openbravo.base.OBSchedulerInitializerListener, an implementation of javax.servlet.ServletContextListener, is configured as a listener in the AD_MODEL_OBJECT table. When Tomcat is started, OBSchedulerInitializer listener is loaded and configures the scheduler environment with the parameters defined in the web.xml and in the quartz.properties file (see below). OBSchedulerInitializerListener is basically a replica of the Quartz provided org.quartz.ee.servlet.QuartzInitializerListener listener, but also stores a reference to the Openbravo Connection Pool and Config Parameters in the scheduler's context. This ensures that these object's are available to the Openbravo Scheduler and Monitor when processes are scheduled and process events occur.

<!-- Quartz context params -->
<context-param>
  <param-name>config-file</param-name>
  <param-value>quartz.properties</param-value>
</context-param>
<context-param>
  <param-name>shutdown-on-unload</param-name>
  <param-value>true</param-value>
</context-param>
<context-param>
  <param-name>start-scheduler-on-load</param-name>
  <param-value>true</param-value>
</context-param>
<context-param>
  <param-name>start-delay-seconds</param-name>
  <param-value>30</param-value>
</context-param>

Although not necessary as default properties are internally configured in Quartz, Openbravo ERP provides a default quart.properties file to make adding or modifying properties a breeze:

## Quartz properties
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

org.quartz.jobStore.misfireThreshold = 60000

org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

For a full list of configuration options see this Quartz Configuration document.

Process Scheduling

You can view the Process Request window by navigating in the Menu to General Setup -> Process Scheduling -> Process Request. Here you can see the typical Openbravo ERP window options, but in particular notice the Process and Timing options. These two fields allow you to select the background process to run and how it will be run, or more specifically for development purposes, the Trigger that will be used/generated for Scheduler.

Process Request.png

When requesting a process through the Process Request window, there are three options that a user can select from:

Schedule Options

These options enable users of the system to fine tune exactly when a background process will start, repeat and stop, and are translated into Quartz Triggers and fed into the underlying scheduling framework when the process is scheduled.

TriggerProvider is a private inner class in OBScheduler (discussed below), which takes the options entered by the user in the Process Request window and transforms them into Quartz Triggers which can be fed into the Quartz Scheduler along with the Processes (Jobs) to be executed.

Scheduling by seconds, minutes and hours

Schedule-minutes.png

When scheduling by seconds, minutes or hours, two options are given: the interval between the seconds/minutes/hours, and the number of repetitions that will be performed before the process stops repeating (if left blank it will continue indefinitely, except when a finish date is specified). TriggerProvider uses the Quartz TriggerUtils, a utility class that simplifies creating simple triggers, to transform the selected values into a scheduleable Quartz Trigger:

int i = Integer.parseInt(interval);
int r = Integer.parseInt(repetitions);
...
if (type.equals(FREQUENCY_SECONDLY)) {
  return TriggerUtils.makeSecondlyTrigger(i, r);

} else if (type.equals(FREQUENCY_MINUTELY)) {
  return TriggerUtils.makeMinutelyTrigger(i, r);

} else if (type.equals(FREQUENCY_HOURLY)) {
  return TriggerUtils.makeHourlyTrigger(i, r);
}

Scheduling daily

Daily provides an identical selection as explained above in seconds, minutes and hours, but also allows users to schedule the process on Weekdays or Weekends:

Schedule-daily.png

Daily scheduling options are transformed into a Quartz CronTrigger for use by the scheduler. CronTriggers follow the same formatting rules as a typical cron expression in a Linux system. More about Quartz CronTriggers can be found in their tutorial and in the Quartz documentation.

} else if (data.dailyOption.equals(WEEKDAYS)) {
  final String cronExpression = second + " " + minute + " " + hour + " ? * MON-FRI";
  trigger = new CronTrigger(name, OB_GROUP, cronExpression);

} else if (data.dailyOption.equals(WEEKENDS)) {
  final String cronExpression = second + " " + minute + " " + hour + " ? * SAT,SUN";
  trigger = new CronTrigger(name, OB_GROUP, cronExpression);

Scheduling weekly

Scheduling weekly allows users to select individual days of the week to execute the process:

Schedule-weekly.png

And similar to the Triggers generated when users schedule a process on weekdays or weekends, a CronTrigger is generated by TriggerProvider that represents the days selected:

} else if (data.frequency.equals(FREQUENCY_WEEKLY)) {
  final StringBuilder sb = new StringBuilder();
  if (data.daySun.equals("Y"))
    sb.append("SUN");
  if (data.dayMon.equals("Y"))
    sb.append(sb.length() == 0 ? "MON" : ",MON");
  ...
  if (sb.length() != 0) {
    sb.insert(0, second + " " + minute + " " + hour + " ? * ");
    trigger = new CronTrigger(name, OB_GROUP, sb.toString());

Scheduling monthly

Monthly offers a few more variances than in the preceding options:

Schedule-monthly.png

All of the monthly options are transformed by TriggerProvider into CronTriggers in much the same way the Weekly option is.

Scheduling by cron expression

Finally there is an option to directly enter a Quartz cron expression which is directly transformed into a CronTrigger. If the expression is malformed, an error will be thrown. For details on CronTrigger format, see the JavaDoc.

Quartz Scheduler Integration

At the heart of the Quartz scheduling framework is the org.quartz.Scheduler. The scheduler is responsible for Job and Trigger management, scheduling and unscheduled tasks and retrieving and updating scheduler state and information.

Openbravo Process Scheduling creates a simple interface to the Quartz Scheduler via the org.openbravo.scheduling.OBScheduler, a singleton instance that is initialized at startup and exposes a number of methods to schedule Openbravo Processes. The underlying Quartz Scheduler is available by calling the getScheduler() method on the OBScheduler instance. This enables developers full access to the power of the underlying Quartz framework, especially for registering custom Listeners and retrieving Scheduler information.

Job/Process Integration

The interface org.openbravo.scheduling.Process needs to be implemented in order to be scheduled directly with the OBScheduler and monitored by the Process Monitor. A base implementation of Process is provided in the org.openbravo.service.db.DalBaseProcess, which should be extended in preference of directly implementing Process, as the DalBaseProcess class provides built in security.

The org.openbravo.scheduling.ProcessBundle is the class which is passed to Openbravo Processes as the only parameter to the execute() method. Any parameters that a process needs should be stored in the ProcessBundle's parameter Map. ProcessBundle also provides access to process specific contextual information Openbravo application information. By using the ProcessLogger, which is also wrapped up in the ProcessBundle, developers are able to log messages which will be displayed in the Process' log on the Process Monitor window.

The org.openbravo.scheuling.DefaultJob is an implementation of the Quartz Job interface and takes care of the integration between Quartz and Openbravo ERP. The DefaultJob is what is scheduled with the Quartz Scheduler; an Openbravo Process (and its ProcessBundle) is stored and retrieved from the DefaultJob's execution context when it is scheduled, executed and whenever the Process Monitor requires it. For example:

public void execute(JobExecutionContext jec) throws JobExecutionException {
  final ProcessBundle bundle = (ProcessBundle) jec.getMergedJobDataMap().get(ProcessBundle.KEY);
  try {
    final Process process = bundle.getProcessClass().newInstance();
    ...
    process.execute(bundle);

Demonstrates retrieving the Openbravo Process and ProcessBundle from the DefaultJob when it is executed by the Quartz Scheduler.

Process Monitoring

Monitoring process execution in the application is done via the General Setup -> Process Scheduling -> Process Monitor window:

Process Monitor.png

Monitoring is achieved through the use of Quartz Listeners. You register listeners with the Scheduler to perform an action when a specific event occurs within the scheduling environment, such as when a Job is executed or fails. The org.openbravo.scheduling.ProcessMonitor class implements Quartz JobListener, TriggerListener and SchedulerListener and responds to the following events:

For a full listing of listener events see JobListener, TriggerListener and SchedulerListener.



ERP 2.50:Developers Guide/Concepts/Data Access Layer | ERP 2.50:Developers Guide/Concepts/Authentication 

Retrieved from "http://wiki.openbravo.com/wiki/ERP_2.50:Developers_Guide/Concepts/Process_Scheduling"

This page has been accessed 11,806 times. This page was last modified on 14 June 2011, at 11:03. Content is available under Creative Commons Attribution-ShareAlike 2.5 Spain License.