All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sakaiproject.component.app.scheduler.ScheduledInvocationManagerImpl Maven / Gradle / Ivy

There is a newer version: 23.3
Show newest version
package org.sakaiproject.component.app.scheduler;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.JobDetailImpl;
import org.sakaiproject.api.app.scheduler.DelayedInvocation;
import org.sakaiproject.api.app.scheduler.ScheduledInvocationManager;
import org.sakaiproject.api.app.scheduler.SchedulerManager;
import org.sakaiproject.component.api.ServerConfigurationService;
import org.sakaiproject.component.app.scheduler.jobs.ScheduledInvocationRunner;
import org.sakaiproject.db.api.SqlService;
import org.sakaiproject.id.api.IdManager;
import org.sakaiproject.time.api.Time;

public class ScheduledInvocationManagerImpl implements ScheduledInvocationManager {

	private static final Logger LOG = LoggerFactory.getLogger(ScheduledInvocationManagerImpl.class);

	private static final String SCHEDULED_INVOCATION_RUNNER_DEFAULT_INTERVAL_PROPERTY = "jobscheduler.invocation.interval";

	private static final int SCHEDULED_INVOCATION_RUNNER_DEFAULT_INTERVAL = 120; //default: time in seconds, run every 2 mins

	
	/** Dependency: IdManager */
	protected IdManager m_idManager = null;

	public void setIdManager(IdManager service) {
		m_idManager = service;
	}

	/** Dependency: SqlService */
	protected SqlService m_sqlService = null;

	public void setSqlService(SqlService service) {
		m_sqlService = service;
	}
	

	/** Dependency: SchedulerManager */
	protected SchedulerManager m_schedulerManager = null;

	public void setSchedulerManager(SchedulerManager service) {
		m_schedulerManager = service;
	}
	
	
	/** Dependency: ServerConfigurationService */
	protected ServerConfigurationService m_serverConfigurationService = null;

	public void setServerConfigurationService(ServerConfigurationService service) {
		m_serverConfigurationService = service;
	}
	

	/** Configuration: Should we autocreate our database tables */
	protected boolean autoDdl;

	public void setAutoDdl(boolean autoDdl) {
		this.autoDdl = autoDdl;
	}
	
	

	public void init() {
		LOG.info("init()");
		if (autoDdl) {
			m_sqlService.ddl(getClass().getClassLoader(), "delayed");
			// Create the additional indexes as hibernate currently fails todo this.
			// Once hibernate is updated to 3.6 it should be able to manage in it's own.
			m_sqlService.ddl(getClass().getClassLoader(), "indexes2");
		}
	      try {
	          registerScheduledInvocationRunner();
	       } catch (SchedulerException e) {
	          LOG.error("failed to schedule ScheduledInvocationRunner job", e);
	       }
	    }

   public void destroy() {
      LOG.info("destroy()");
   }

   protected void registerScheduledInvocationRunner() throws SchedulerException {
	   
	   //trigger will not start immediately, wait until interval has passed before 1st run
	   long startTime = System.currentTimeMillis() + getScheduledInvocationRunnerInterval();
	   
       JobDetail detail = JobBuilder.newJob(ScheduledInvocationRunner.class)
               .withIdentity("org.sakaiproject.component.app.scheduler.ScheduledInvocationManagerImpl.runner", "org.sakaiproject.component.app.scheduler.ScheduledInvocationManagerImpl")
               .build();
               
       Trigger trigger = TriggerBuilder.newTrigger()
               .withIdentity("org.sakaiproject.component.app.scheduler.ScheduledInvocationManagerImpl.runner", "org.sakaiproject.component.app.scheduler.ScheduledInvocationManagerImpl")
               .startAt(new Date(startTime))
               .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                       .repeatForever()
                       .withIntervalInSeconds(getScheduledInvocationRunnerInterval()))
               .build();
               
       Scheduler scheduler = m_schedulerManager.getScheduler();
       // This removes the jobs if there are no trigger left on it.
       scheduler.unscheduleJob(trigger.getKey());
       scheduler.scheduleJob(detail, trigger);
    }
   
   protected int getScheduledInvocationRunnerInterval() {
	   return m_serverConfigurationService.getInt(SCHEDULED_INVOCATION_RUNNER_DEFAULT_INTERVAL_PROPERTY, SCHEDULED_INVOCATION_RUNNER_DEFAULT_INTERVAL);
   }
   
	/* (non-Javadoc)
	 * @see org.sakaiproject.api.app.scheduler.ScheduledInvocationManager#createDelayedInvocation(org.sakaiproject.time.api.Time, java.lang.String, java.lang.String)
	 */
	public String createDelayedInvocation(Time time, String componentId, String opaqueContext) {

		String uuid = m_idManager.createUuid();

		LOG.debug("Creating new Delayed Invocation: " + uuid);
		String sql = "INSERT INTO SCHEDULER_DELAYED_INVOCATION VALUES(?,?,?,?)";

		Object[] fields = new Object[4];

		fields[0] = uuid;
		fields[1] = time;
		fields[2] = componentId;
		fields[3] = opaqueContext;

		LOG.debug("SQL: " + sql);
		if (m_sqlService.dbWrite(sql, fields)) {
			LOG.info("Created new Delayed Invocation: uuid=" + uuid);
			return uuid;
		} else {
			LOG.error("Failed to create new Delayed Invocation: componentId=" + componentId + 
					", opaqueContext=" + opaqueContext);
			return null;
		}

	}

	/* (non-Javadoc)
	 * @see org.sakaiproject.api.app.scheduler.ScheduledInvocationManager#deleteDelayedInvocation(java.lang.String)
	 */
	public void deleteDelayedInvocation(String uuid) {

		LOG.debug("Removing Delayed Invocation: " + uuid);
		String sql = "DELETE FROM SCHEDULER_DELAYED_INVOCATION WHERE INVOCATION_ID = ?";

		Object[] fields = new Object[1];
		fields[0] = uuid;

		LOG.debug("SQL: " + sql);
		m_sqlService.dbWrite(sql, fields);

	}

	/* (non-Javadoc)
	 * @see org.sakaiproject.api.app.scheduler.ScheduledInvocationManager#deleteDelayedInvocation(java.lang.String, java.lang.String)
	 */
	public void deleteDelayedInvocation(String componentId, String opaqueContext) {
		LOG.debug("componentId=" + componentId + ", opaqueContext=" + opaqueContext);

		//String sql = "DELETE FROM SCHEDULER_DELAYED_INVOCATION WHERE COMPONENT = ? AND CONTEXT = ?";
		String sql = "DELETE FROM SCHEDULER_DELAYED_INVOCATION";

		Object[] fields = new Object[0];
		if (componentId.length() > 0 && opaqueContext.length() > 0) {
			// both non-blank
			sql += " WHERE COMPONENT = ? AND CONTEXT = ?";
			fields = new Object[2];
			fields[0] = componentId;
			fields[1] = opaqueContext;
		} else if (componentId.length() > 0) {
			// context blank
			sql += " WHERE COMPONENT = ?";
			fields = new Object[1];
			fields[0] = componentId;
		} else if (opaqueContext.length() > 0) {
			// component blank
			sql += " WHERE CONTEXT = ?";
			fields = new Object[1];
			fields[0] = opaqueContext;
		} else {
			// both blank
		}

		LOG.debug("SQL: " + sql);
		if ( m_sqlService.dbWrite(sql, fields) ) {
			LOG.info("Removed all scheduled invocations matching: componentId=" + componentId + ", opaqueContext=" + opaqueContext);
		} else {
			LOG.error("Failure while attempting to remove invocations matching: componentId=" + componentId + ", opaqueContext=" + opaqueContext);
		}

	}

	/* (non-Javadoc)
	 * @see org.sakaiproject.api.app.scheduler.ScheduledInvocationManager#findDelayedInvocations(java.lang.String, java.lang.String)
	 */
	public DelayedInvocation[] findDelayedInvocations(String componentId, String opaqueContext) {
		LOG.debug("componentId=" + componentId + ", opaqueContext=" + opaqueContext);

		//String sql = "SELECT * FROM SCHEDULER_DELAYED_INVOCATION WHERE COMPONENT = ? AND CONTEXT = ?";
		String sql = "SELECT * FROM SCHEDULER_DELAYED_INVOCATION";

		Object[] fields = new Object[0];
		if (componentId.length() > 0 && opaqueContext.length() > 0) {
			// both non-blank
			sql += " WHERE COMPONENT = ? AND CONTEXT = ?";
			fields = new Object[2];
			fields[0] = componentId;
			fields[1] = opaqueContext;
		} else if (componentId.length() > 0) {
			// context blank
			sql += " WHERE COMPONENT = ?";
			fields = new Object[1];
			fields[0] = componentId;
		} else if (opaqueContext.length() > 0) {
			// component blank
			sql += " WHERE CONTEXT = ?";
			fields = new Object[1];
			fields[0] = opaqueContext;
		} else {
			// both blank
		}

		List invocations = m_sqlService.dbRead(sql, fields, new DelayedInvocationReader());
		return (DelayedInvocation[]) invocations.toArray( new DelayedInvocation[] {} );
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy