<?xml version='1.0' encoding='UTF-8'?>
<!-- This document was created with Syntext Serna Free. --><!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []>
<section id="Kernel.JobSchedulerService">
<title>Job Scheduler Service</title>
  <para><emphasis role="bold">Job scheduler</emphasis>  defines a job to execute a given number of times during a given period. It is a service that is in charge of unattended background executions, commonly known for historical reasons as batch processing. It is used to create and run jobs automatically and continuously, to schedule event-driven jobs and reports.</para>
  <section id="Kernel.JobSchedulerService.WhatIsJobSchedulerServiceIneXoProducts">
    <title>Where is Job Scheduler Service used in eXo Products?</title>
    <para>Job Scheduler Service is widely used in many eXo products such as Social, DMS, WCM, eXo Knowledge and eXo Collaboration.</para>
    <para>In eXo products, Job Schedulers are used to do some tasks as below:</para>
    <itemizedlist>
      <listitem>
        <para>Automatically send notification, such as task/event reminder in the Calendar application of eXo Collaboration. </para>
      </listitem>
      <listitem>
        <para>Automatically save chat messages from Openfire Server to History in the Chat application of eXo Collaboration. </para>
      </listitem>
      <listitem>
        <para>Inactivate topics in the Forum application of eXo Knowledge.</para>
      </listitem>
      <listitem>
        <para>Calculate the number of active and online users in the Forum application of eXo Knowledge.</para>
      </listitem>
      <listitem>
        <para>Automatically collect RSS items from various RSS resources to post to the activity stream of users and spaces in eXo Social.</para>
      </listitem>
      <listitem>
        <para>Automatically send Newsletters to users in WCM.</para>
      </listitem>
    </itemizedlist>
    <para>Also, it is used in Schedule lifecycle in DMS.</para>
    <para>By using Job Scheduler Service in eXo kernel, many kinds of job can be configured to run, such as, addPeriodJob, addCronJob, addGlobalJobListener, addJobListener and many more. Just write a job (a class implements Job interface of quartz library and configures plug-in for JobSchedulerService and you&apos;re done. </para>
  </section>
  <section id="Kernel.JobSchedulerService.HowJobSchedulerWork">
    <title>How does Job Scheduler work?</title>
    <para>Jobs are scheduled to run when a given Trigger occurs. Triggers can
    be created with nearly any combination of the following directives:</para>
    <itemizedlist>
      <listitem>
        <para>at a certain time of day (to the millisecond)</para>
      </listitem>
      <listitem>
        <para>on certain days of the week</para>
      </listitem>
    </itemizedlist>
    <itemizedlist>
      <listitem>
        <para>on certain days of the month</para>
      </listitem>
      <listitem>
        <para>on certain days of the year</para>
      </listitem>
    </itemizedlist>
    <itemizedlist>
      <listitem>
        <para>not on certain days listed within a registered Calendar (such as
        business holidays)</para>
      </listitem>
    </itemizedlist>
    <itemizedlist>
      <listitem>
        <para>repeated a specific number of times</para>
      </listitem>
    </itemizedlist>
    <itemizedlist>
      <listitem>
        <para>repeated until a specific time/date</para>
      </listitem>
      <listitem>
        <para>repeated indefinitely</para>
      </listitem>
    </itemizedlist>
    <itemizedlist>
      <listitem>
        <para>repeated with a delay interval</para>
      </listitem>
    </itemizedlist>
    <para>Jobs are given names by their creator and can also be organized into
    named groups. Triggers may also be given names and placed into groups, in
    order to easily organize them within the scheduler. Jobs can be added to
    the scheduler once, but registered with multiple Triggers. Within a J2EE
    environment, Jobs can perform their work as part of a distributed (XA)
    transaction.</para>
    <para>(Source: quartz-scheduler.org) </para>
    <section id="Kernel.JobSchedulerService.HowJobSchedulerWork.JobSchedulerServiceInKernel">
      <title>How can Job Scheduler Service be used in Kernel?</title>
      <para>Kernel leverages <ulink url="http://www.quartz-scheduler.org">Quartz</ulink> for its scheduler
      service and wraps <classname>org.quartz.Scheduler</classname> in
      <classname>org.exoplatform.services.scheduler.impl.QuartzSheduler</classname>
      for easier service wiring and configuration like any other services. To
      work with Quartz in Kernel, you will  mostly work with
      <classname>org.exoplatform.services.scheduler.JobSchedulerService</classname>
      (implemented by
      <classname>org.exoplatform.services.scheduler.impl.JobSchedulerServiceImpl</classname>.</para>
      <para>To use <classname>JobSchedulerService</classname>, you can
      configure it as a component in the configuration.xml. Because
      <classname>JobSchedulerService</classname> requires
      <classname>QuartzSheduler</classname> and
      <classname>QueueTasks</classname>, you also have to configure these two
      components.</para>
      <programlisting language="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;configuration
  xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
  xsi:schemaLocation=&quot;http://www.exoplatform.org/xml/ns/kernel_1_3.xsd http://www.exoplatform.org/xml/ns/kernel_1_3.xsd&quot;
  xmlns=&quot;http://www.exoplatform.org/xml/ns/kernel_1_3.xsd&quot;&gt;

  &lt;component&gt;
    &lt;type&gt;org.exoplatform.services.scheduler.impl.QuartzSheduler&lt;/type&gt;
  &lt;/component&gt;

  &lt;component&gt;
    &lt;type&gt;org.exoplatform.services.scheduler.QueueTasks&lt;/type&gt;
  &lt;/component&gt;

  &lt;component&gt;
    &lt;key&gt;org.exoplatform.services.scheduler.JobSchedulerService&lt;/key&gt;
    &lt;type&gt;org.exoplatform.services.scheduler.impl.JobSchedulerServiceImpl&lt;/type&gt;
  &lt;/component&gt;

&lt;/configuration&gt;</programlisting>
    </section>
    <section id="Kernel.JobSchedulerService.HowJobSchedulerWork.Samples">
      <title>Samples</title>
      <note>
        <para>You can download the project code from <ulink url="https://github.com/hoatle/job-scheduler-service-tutorial">here</ulink></para>
      </note>
      <para>Work with <classname>JobSchedulerService</classname> by
      creating a sample project and use GateIn-3.1.0-GA for testing.</para>
      <para>Firstly, create a project by using maven archetype plugin:</para>
      <programlisting>mvn archetype:generate
</programlisting>
      <itemizedlist>
        <listitem>
          <para>For project type:   select <emphasis role="bold">maven-archetype-quickstart </emphasis></para>
        </listitem>
        <listitem>
          <para>For groupId: select <emphasis role="bold">org.exoplatform.samples</emphasis></para>
        </listitem>
        <listitem>
          <para>For artifactId: select <emphasis role="bold">exo.samples.scheduler</emphasis></para>
        </listitem>
        <listitem>
          <para>For version: select<emphasis role="bold"> 1.0.0-SNAPSHOT</emphasis></para>
        </listitem>
        <listitem>
          <para>For package: select  <emphasis role="bold">org.exoplatform.samples.scheduler</emphasis></para>
        </listitem>
      </itemizedlist>
      <para>Edit the pom.xml as follows:</para>
      <programlisting language="xml">&lt;project
  xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
  xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
  xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;

  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

  &lt;parent&gt;
    &lt;artifactId&gt;exo.portal.parent&lt;/artifactId&gt;
    &lt;groupId&gt;org.exoplatform.portal&lt;/groupId&gt;
    &lt;version&gt;3.1.0-GA&lt;/version&gt;
  &lt;/parent&gt;

  &lt;groupId&gt;org.exoplatform.samples&lt;/groupId&gt;
  &lt;artifactId&gt;exo.samples.scheduler&lt;/artifactId&gt;
  &lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;
  &lt;name&gt;eXo Samples For Scheduler&lt;/name&gt;
  &lt;description&gt;eXo Samples Code For Scheduler&lt;/description&gt;
&lt;/project&gt;    </programlisting>
      <para>Generate an eclipse project by using maven eclipse plugin and then import into eclipse:</para>
      <programlisting>mvn eclipse:eclipse</programlisting>
      <para>eXo Kernel makes it easier to work with job scheduler service. All you need is just to define your &quot;job&quot; class to be performed by implementing <emphasis role="italic">org.quartz.Job</emphasis> interface and add configuration for it. </para>
      <section id="Kernel.JobSchedulerService.HowJobSchedulerWork.Samples.DefineJob">
        <title>Define a job</title>
        <para>To define a job, do as follows:</para>
        <para>Define your job to be performed. For example, the job <emphasis role="italic">DumbJob</emphasis> is defined as follows:</para>
        <programlisting language="java">package org.exoplatform.samples.scheduler.jobs;

import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/**
 * DumbJob for executing a defined dumb job.
 */
public class DumbJob implements Job {

  /**
   * The logger
   */
  private static final Log LOG = ExoLogger.getLogger(DumbJob.class);

  /**
   * The job of the DumbJob will be done by executing this method.
   *
   * @param context
   * @throws JobExecutionException
   */
  public void execute(JobExecutionContext context) throws JobExecutionException {
    LOG.info(&quot;DumbJob is executing...&quot;);
  }
}</programlisting>
        <para>All jobs are required to implement the method <emphasis role="italic">execute</emphasis> from <emphasis role="italic">org.quartz.Job</emphasis> interface. This method will be called whenever a job is performed. With <emphasis role="italic">DumbJob</emphasis>, you just use logging to see that it will work. By looking at the terminal, you will see the the log message: &quot;DumbJob is executing...&quot;</para>
      </section>
      <section id="Kernel.JobSchedulerService.HowJobSchedulerWork.Samples.JobConfiguration">
        <title>Job configuration</title>
        <para>After defining the &quot;job&quot;, the only next step is to configure it by using <emphasis role="italic">external-component-plugin</emphasis> configuration for <emphasis role="italic">org.exoplatform.services.scheduler.JobSchedulerService</emphasis>. You can use these methods below for setting component plugin:</para>
        <programlisting language="java">public void addPeriodJob(ComponentPlugin plugin) throws Exception;</programlisting>
        <para>The component plugin for this method must be the type of <emphasis role="italic">org.exoplatform.services.scheduler.PeriodJob</emphasis>. This type of job is used to perform actions that are executed in a period of time. You have to define when this job is performed, when it ends, when it performs the first action, how many times it is executed and the period of time to perform the action. See the configuration sample below to understand more clearly:</para>
        <programlisting language="xml">&lt;external-component-plugins&gt;
   &lt;target-component&gt;org.exoplatform.services.scheduler.JobSchedulerService&lt;/target-component&gt;
    &lt;component-plugin&gt;
      &lt;name&gt;PeriodJob Plugin&lt;/name&gt;
      &lt;set-method&gt;addPeriodJob&lt;/set-method&gt;
      &lt;type&gt;org.exoplatform.services.scheduler.PeriodJob&lt;/type&gt;
      &lt;description&gt;period job configuration&lt;/description&gt;
      &lt;init-params&gt;
        &lt;properties-param&gt;
          &lt;name&gt;job.info&lt;/name&gt;
          &lt;description&gt;dumb job executed  periodically&lt;/description&gt;
          &lt;property name=&quot;jobName&quot; value=&quot;DumbJob&quot;/&gt;
          &lt;property name=&quot;groupName&quot; value=&quot;DumbJobGroup&quot;/&gt;
          &lt;property name=&quot;job&quot; value=&quot;org.exoplatform.samples.scheduler.jobs.DumbJob&quot;/&gt;
          &lt;property name=&quot;repeatCount&quot; value=&quot;0&quot;/&gt;
          &lt;property name=&quot;period&quot; value=&quot;60000&quot;/&gt;
          &lt;property name=&quot;startTime&quot; value=&quot;+45&quot;/&gt;
          &lt;property name=&quot;endTime&quot; value=&quot;&quot;/&gt;
        &lt;/properties-param&gt;
      &lt;/init-params&gt;
    &lt;/component-plugin&gt;
 &lt;/external-component-plugins&gt;</programlisting>
        <programlisting language="java">public void addCronJob(ComponentPlugin plugin) throws Exception;</programlisting>
        <para>The component plugin for this method must be the type of <emphasis role="italic">org.exoplatform.services.scheduler.CronJob</emphasis>. This type of job is used to perform actions at specified time with Unix &apos;cron-like&apos; definitions. The plugin uses &quot;expression&quot; field for specifying the &apos;cron-like&apos; definitions to execute the job. This is considered as the most powerful and flexible job to define when it will execute. For example, at 12pm every day =&gt; &quot;0 0 12 * * ?&quot;; or at 10:15am every Monday, Tuesday, Wednesday, Thursday and Friday =&gt; &quot;0 15 10 ? * MON-FRI&quot;. To see more about Cron expression, please refer to this article: <para><ulink url="http://en.wikipedia.org/wiki/CRON_expression">CRON expression</ulink>.</para>See the configuration sample below to understand more clearly:</para>
        <programlisting language="xml">&lt;external-component-plugins&gt;
    &lt;target-component&gt;org.exoplatform.services.scheduler.JobSchedulerService&lt;/target-component&gt;
    &lt;component-plugin&gt;
      &lt;name&gt;CronJob Plugin&lt;/name&gt;
      &lt;set-method&gt;addCronJob&lt;/set-method&gt;
      &lt;type&gt;org.exoplatform.services.scheduler.CronJob&lt;/type&gt;
      &lt;description&gt;cron job configuration&lt;/description&gt;
      &lt;init-params&gt;
        &lt;properties-param&gt;
          &lt;name&gt;cronjob.info&lt;/name&gt;
          &lt;description&gt;dumb job executed by cron expression&lt;/description&gt;
          &lt;property name=&quot;jobName&quot; value=&quot;DumbJob&quot;/&gt;
          &lt;property name=&quot;groupName&quot; value=&quot;DumbJobGroup&quot;/&gt;
          &lt;property name=&quot;job&quot; value=&quot;org.exoplatform.samples.scheduler.jobs.DumbJob&quot;/&gt;
          &lt;!-- The job will be performed at 10:15am every day --&gt;
          &lt;property name=&quot;expression&quot; value=&quot;0 15 10 * * ?&quot;/&gt; 
        &lt;/properties-param&gt;
      &lt;/init-params&gt;
    &lt;/component-plugin&gt;
  &lt;/external-component-plugins&gt;</programlisting>
        <programlisting language="java">public void addGlobalJobListener(ComponentPlugin plugin) throws Exception;</programlisting>
        <programlisting language="java">public void addJobListener(ComponentPlugin plugin) throws Exception;</programlisting>
        <para>The component plugin for two methods above must be the type of <emphasis role="italic">org.quartz.JobListener.</emphasis> This job listener is used so that it will be informed when a <emphasis role="italic">org.quartz.JobDetail</emphasis> executes.</para>
        <programlisting language="java">public void addGlobalTriggerListener(ComponentPlugin plugin) throws Exception;</programlisting>
        <programlisting language="java">public void addTriggerListener(ComponentPlugin plugin) throws Exception;</programlisting>
        <para>The component plugin for two methods above must be the type of <emphasis role="italic">org.quartz.TriggerListener</emphasis>. This trigger listener is used so that it will be informed when a <emphasis role="italic">org.quartz.Trigger</emphasis> fires.</para>
      </section>
      <section id="Kernel.JobSchedulerService.HowJobSchedulerWork.Samples.RunProject">
        <title>Run the project</title>
        <para>Create <emphasis role="italic">conf.portal</emphasis> package in your sample project. Add the configuration.xml file with the content as follows:</para>
        <programlisting language="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;configuration
  xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
  xsi:schemaLocation=&quot;http://www.exoplatform.org/xml/ns/kernel_1_3.xsd http://www.exoplatform.org/xml/ns/kernel_1_3.xsd&quot;
  xmlns=&quot;http://www.exoplatform.org/xml/ns/kernel_1_3.xsd&quot;&gt;

  &lt;component&gt;
    &lt;type&gt;org.exoplatform.services.scheduler.impl.QuartzSheduler&lt;/type&gt;
  &lt;/component&gt;
  &lt;component&gt;
    &lt;type&gt;org.exoplatform.services.scheduler.QueueTasks&lt;/type&gt;
  &lt;/component&gt;
  &lt;component&gt;
    &lt;key&gt;org.exoplatform.services.scheduler.JobSchedulerService&lt;/key&gt;
    &lt;type&gt;org.exoplatform.services.scheduler.impl.JobSchedulerServiceImpl&lt;/type&gt;
  &lt;/component&gt;

  &lt;external-component-plugins&gt;
    &lt;target-component&gt;org.exoplatform.services.scheduler.JobSchedulerService&lt;/target-component&gt;
    &lt;component-plugin&gt;
      &lt;name&gt;PeriodJob Plugin&lt;/name&gt;
      &lt;set-method&gt;addPeriodJob&lt;/set-method&gt;
      &lt;type&gt;org.exoplatform.services.scheduler.PeriodJob&lt;/type&gt;
      &lt;description&gt;period job configuration&lt;/description&gt;
      &lt;init-params&gt;
        &lt;properties-param&gt;
          &lt;name&gt;job.info&lt;/name&gt;
          &lt;description&gt;dumb job executed periodically&lt;/description&gt;
          &lt;property name=&quot;jobName&quot; value=&quot;DumbJob&quot;/&gt;
          &lt;property name=&quot;groupName&quot; value=&quot;DumbJobGroup&quot;/&gt;
          &lt;property name=&quot;job&quot; value=&quot;org.exoplatform.samples.scheduler.jobs.DumbJob&quot;/&gt;
          &lt;property name=&quot;repeatCount&quot; value=&quot;0&quot;/&gt;
          &lt;property name=&quot;period&quot; value=&quot;60000&quot;/&gt;
          &lt;property name=&quot;startTime&quot; value=&quot;+45&quot;/&gt;
          &lt;property name=&quot;endTime&quot; value=&quot;&quot;/&gt;
        &lt;/properties-param&gt;
      &lt;/init-params&gt;
    &lt;/component-plugin&gt;
  &lt;/external-component-plugins&gt;
&lt;/configuration&gt;</programlisting>
        <para><emphasis role="italic">mvn clean install </emphasis>the project. Copy .jar file to<emphasis role="italic"> lib</emphasis> in tomcat bundled with GateIn-3.1.0-GA. Run <emphasis role="italic">bin/gatein.sh</emphasis> to see the <emphasis role="italic">DumbJob</emphasis> to be executed on the terminal when portal containers are initialized. Please look at the terminal to see the log message of <emphasis role="italic">DumbJob</emphasis>.</para>
        <para>From now on, you can easily create any job to be executed in GateIn&apos;s portal by defining your job and configuring it.

</para>
      </section>
    </section>
  </section>
  <section id="Kernel.JobSchedulerService.Reference">
    <title>Reference</title>
    <para>To further understand about Job Scheduler, you can refer the
    following links:</para>
    <itemizedlist>
      <listitem>
        <para><ulink url="http://www.quartz-scheduler.org/">http://www.quartz-scheduler.org/</ulink></para>
      </listitem>
      <listitem>
        <para><ulink url="http://en.wikipedia.org/wiki/Job_scheduler">http://en.wikipedia.org/wiki/Job_scheduler</ulink></para>
      </listitem>
      <listitem>
        <para><ulink url="http://www.theserverside.com/news/1364726/Job-Scheduling-in-J2EE-Applications">http://www.theserverside.com/news/1364726/Job-Scheduling-in-J2EE-Applications</ulink></para>
      </listitem>
      <listitem>
        <para><ulink url="http://technet.microsoft.com/en-us/library/cc720070%28WS.10%29.aspx">http://technet.microsoft.com/en-us/library/cc720070%28WS.10%29.aspx</ulink></para>
      </listitem>
    </itemizedlist>
  </section>
</section>
