Package ch.hortis.sonar.core

Source Code of ch.hortis.sonar.core.Batch$RunningJobListener

/*
* This program is copyright (c) 2007 Hortis-GRC SA.
*
* This file is part of Sonar.
* Sonar is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package ch.hortis.sonar.core;

import ch.hortis.sonar.model.JdbcData;

import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.util.Date;
import java.util.Properties;

public class Batch {

  public static final long DEFAULT_PURGE_REPEAT_INTERVAL_MILLIS = 24 * 60 * 60 * 1000; // 24h
 
  private long purgeRepeatInMillis = DEFAULT_PURGE_REPEAT_INTERVAL_MILLIS;
 
  public final static String SONAR_JOBS_GROUP = "Sonar jobs";
  public final static String METRICS_CALCULATIONS_JOB_NAME = "Metrics calculations job";
  public final static String DATA_CLEANUP_JOB_NAME = "Data cleanup job";

  private BaseJobDetail calculatorJobDetail;
  private Scheduler scheduler;
  private JdbcData jdbcData;
 
  protected static final Logger LOG = LoggerFactory.getLogger( Batch.class );
 
  private static Batch systemInstance = null;

  public Batch( String jdbcURL, String jdbcDriver, String username, String password ) {
    this( new JdbcData( jdbcURL, jdbcDriver, username, password ) );
  }
 
  public Batch( String datasource, String jdbcDialect ) {
    this( new JdbcData( datasource,  jdbcDialect ) );
  }

  public Batch( JdbcData jdbcData ) {
    this.jdbcData = jdbcData;
    if ( systemInstance == null ) {
      systemInstance = this;
    }
  }

  public static Batch getSystemInstance() {
    return systemInstance;
  }

  public long getPurgeRepeatInMillis() {
    return purgeRepeatInMillis;
  }

  public void setPurgeRepeatInMillis( long purgeRepeatInMillis ) {
    this.purgeRepeatInMillis = purgeRepeatInMillis;
  }

  public void start() throws SchedulerException {
    Properties props = new Properties();
    props.setProperty( "org.quartz.scheduler.instanceName", "sonar-scheduler" );
    props.setProperty( "org.quartz.threadPool.class", org.quartz.simpl.SimpleThreadPool.class.getName() );
    props.setProperty( "org.quartz.threadPool.threadCount", "1" );
    props.setProperty( "org.quartz.jobStore.class", org.quartz.simpl.RAMJobStore.class.getName() );

    StdSchedulerFactory factory = new StdSchedulerFactory();
    factory.initialize( props );
   
    scheduler = factory.getScheduler();

    Date firstStartup = new Date( System.currentTimeMillis() + ( 30 * 1000 ) );
   
    jdbcData.setIsolationLevel( Connection.TRANSACTION_READ_COMMITTED );
   
    calculatorJobDetail = new BaseJobDetail( METRICS_CALCULATIONS_JOB_NAME, SONAR_JOBS_GROUP, MeasuresCalculatorJob.class );
    calculatorJobDetail.setJdbcData( jdbcData );
   
    JobsChaining.chainJob( ProjectEreaseJob.class );
    JobsChaining.chainJob( SnapshotGroupsPurgeJob.class );
    JobsChaining.chainJob( MeasuresPurgeJob.class );
   
    BaseJobDetail dataCleanupDetail = new BaseJobDetail( DATA_CLEANUP_JOB_NAME, SONAR_JOBS_GROUP, JobsChaining.class );
    dataCleanupDetail.setJdbcData( jdbcData );
    Trigger dataCleanupTrigger = new SimpleTrigger( DATA_CLEANUP_JOB_NAME, SONAR_JOBS_GROUP, firstStartup, null,
                                                 SimpleTrigger.REPEAT_INDEFINITELY, purgeRepeatInMillis );
   
    scheduler.scheduleJob( dataCleanupDetail, dataCleanupTrigger );
    LOG.info( "Scheduling job " + JobsChaining.class.getName() + " for each " + purgeRepeatInMillis + " ms" );
   
    scheduler.addJobListener( new RunningJobListener( METRICS_CALCULATIONS_JOB_NAME ) );
    scheduler.start();
    LOG.info( "Scheduler started" );
  }

  public void shutdown() throws SchedulerException {
    boolean waitJobsToComplete = true;
    scheduler.shutdown( waitJobsToComplete );
    LOG.info( "Scheduler stopped" );
  }
 
  public synchronized void triggerJob( String jobName ) throws SchedulerException {
    if ( jobName.equals( METRICS_CALCULATIONS_JOB_NAME ) ) {
      Trigger calculationsTrigger = new SimpleTrigger( jobName, SONAR_JOBS_GROUP, new Date() );
      RunningJobListener listener = (RunningJobListener)scheduler.getJobListener( jobName );
      // scheduling a job currently running, enqueue it later trough the listener
      if ( listener.isJobRunning() ) {
        listener.scheduleJob( calculatorJobDetail, calculationsTrigger );
      } else {
        scheduler.scheduleJob( calculatorJobDetail, calculationsTrigger );
      }
    } else {
      scheduler.triggerJob( jobName, Batch.SONAR_JOBS_GROUP );
    }
  }
 
  private class RunningJobListener implements JobListener {

    private String jobName;
    private boolean jobRunning;
   
    private Trigger trigger;
    private JobDetail detail;

    public RunningJobListener(String jobName) {
      this.jobName = jobName;
    }

    public String getName() {
      return jobName;
    }

    public void jobExecutionVetoed(JobExecutionContext ctx) {
      if ( ctx.getJobDetail().getName().equals( jobName ) ) {
        jobRunning = false;
      }
    }

    public void jobToBeExecuted(JobExecutionContext ctx) {
      if ( ctx.getJobDetail().getName().equals( jobName ) ) {
        jobRunning = true;
      }
    }

    public void jobWasExecuted(JobExecutionContext ctx, JobExecutionException execException) {
      if ( ctx.getJobDetail().getName().equals( jobName ) ) {
        jobRunning = false;
        if ( trigger != null && detail != null ) {
          trigger.setStartTime(new Date());
          try {
            ctx.getScheduler().scheduleJob(detail, trigger);
          } catch (SchedulerException e) {
            LOG.error("Error occured when rescheduling job " + jobName, e);
          }
          detail = null;
          trigger = null;
        }
      }
    }

    public boolean isJobRunning() {
      return jobRunning;
    }

    public void scheduleJob(JobDetail detail, Trigger trigger) {
      this.trigger = trigger;
      this.detail = detail;
    }
  }

  public static void main( String[] args ) throws Exception {
    //Batch core = new Batch( "jdbc:derby://localhost:1527/sonar", "org.apache.derby.jdbc.ClientDriver", "sonar", "sonar" );
    Batch batch = new Batch( "jdbc:mysql://localhost:3306/sonar_development", "com.mysql.jdbc.Driver", "sonar", "sonar" );
    batch.start();
    batch.triggerJob(METRICS_CALCULATIONS_JOB_NAME);
  }
}
TOP

Related Classes of ch.hortis.sonar.core.Batch$RunningJobListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.