|
From: <bla...@us...> - 2008-10-11 01:48:47
|
Revision: 51
http://drawbridge.svn.sourceforge.net/drawbridge/?rev=51&view=rev
Author: blamonica
Date: 2008-10-11 01:48:39 +0000 (Sat, 11 Oct 2008)
Log Message:
-----------
Implement Quartz Scheduling of Jobs
Modified Paths:
--------------
trunk/drawbridge/.settings/org.springframework.ide.eclipse.core.prefs
trunk/drawbridge/.springBeans
trunk/drawbridge/WebContent/WEB-INF/classes/drawbridge.properties
trunk/drawbridge/WebContent/WEB-INF/drawbridge-servlet.xml
trunk/drawbridge/WebContent/WEB-INF/web.xml
trunk/drawbridge/src/java/drawbridge-core-spring.xml
trunk/drawbridge/src/java/drawbridge-env-spring.xml
trunk/drawbridge/src/java/net/sf/drawbridge/dao/JobDao.java
trunk/drawbridge/src/java/net/sf/drawbridge/exec/JobExecuter.java
trunk/drawbridge/src/java/net/sf/drawbridge/sched/QuartzDrawbridgeScheduleLoader.java
trunk/drawbridge/src/java/net/sf/drawbridge/util/StringPropertiesConverter.java
trunk/drawbridge/src/sql/create_drawbridge_schema.sql
trunk/drawbridge/src/sql/example_data.sql
trunk/drawbridge/src/test/db.script
trunk/drawbridge/src/test/drawbridge.properties
trunk/drawbridge/src/test/net/sf/drawbridge/dao/JobDaoTest.java
trunk/drawbridge/src/test/net/sf/drawbridge/sched/QuartzDrawbridgeScheduleLoaderTest.java
Added Paths:
-----------
trunk/drawbridge/src/java/beanRefFactory.xml
trunk/drawbridge/src/java/net/sf/drawbridge/sched/ExecuteQueryJob.java
trunk/drawbridge/src/java/net/sf/drawbridge/sched/drawbridge-quartz-spring.xml
trunk/drawbridge/src/test/net/sf/drawbridge/sched/ExecuteQueryJobTest.java
Removed Paths:
-------------
trunk/drawbridge/src/java/net/sf/drawbridge/sched/HeartBeatJob.java
Modified: trunk/drawbridge/.settings/org.springframework.ide.eclipse.core.prefs
===================================================================
--- trunk/drawbridge/.settings/org.springframework.ide.eclipse.core.prefs 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/.settings/org.springframework.ide.eclipse.core.prefs 2008-10-11 01:48:39 UTC (rev 51)
@@ -1,9 +1,10 @@
-#Tue Mar 11 20:22:15 CDT 2008
+#Thu Oct 09 12:37:40 CDT 2008
eclipse.preferences.version=1
org.springframework.ide.eclipse.core.builders.enable.aopreferencemodelbuilder=true
+org.springframework.ide.eclipse.core.builders.enable.beanmetadatabuilder=false
org.springframework.ide.eclipse.core.enable.project.preferences=false
org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.beans.core.beansvalidator=true
-org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.core.springvalidator=true
+org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.core.springvalidator=false
org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.webflow.core.validator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanAlias-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanClass-org.springframework.ide.eclipse.beans.core.beansvalidator=true
@@ -17,7 +18,7 @@
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.methodOverride-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.parsingProblems-org.springframework.ide.eclipse.beans.core.beansvalidator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.requiredProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=false
-org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.core.springClasspath-org.springframework.ide.eclipse.core.springvalidator=true
+org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.core.springClasspath-org.springframework.ide.eclipse.core.springvalidator=false
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.action-org.springframework.ide.eclipse.webflow.core.validator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.actionstate-org.springframework.ide.eclipse.webflow.core.validator=true
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attribute-org.springframework.ide.eclipse.webflow.core.validator=true
Modified: trunk/drawbridge/.springBeans
===================================================================
--- trunk/drawbridge/.springBeans 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/.springBeans 2008-10-11 01:48:39 UTC (rev 51)
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<beansProjectDescription>
<version>1</version>
- <pluginVersion><![CDATA[2.0.3.v200802061800]]></pluginVersion>
+ <pluginVersion><![CDATA[2.2.0.v200809261800]]></pluginVersion>
<configSuffixes>
<configSuffix><![CDATA[xml]]></configSuffix>
</configSuffixes>
@@ -12,6 +12,8 @@
<config>src/java/net/sf/drawbridge/dao/drawbridge-dao-spring.xml</config>
<config>src/test/drawbridge-test-spring.xml</config>
<config>WebContent/WEB-INF/drawbridge-servlet.xml</config>
+ <config>src/java/net/sf/drawbridge/sched/drawbridge-quartz-spring.xml</config>
+ <config>src/java/beanRefFactory.xml</config>
</configs>
<configSets>
</configSets>
Modified: trunk/drawbridge/WebContent/WEB-INF/classes/drawbridge.properties
===================================================================
--- trunk/drawbridge/WebContent/WEB-INF/classes/drawbridge.properties 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/WebContent/WEB-INF/classes/drawbridge.properties 2008-10-11 01:48:39 UTC (rev 51)
@@ -1,2 +1,5 @@
drawbridge.hibernate.dialect=org.hibernate.dialect.MySQLDialect
-drawbridge.hibernate.show_sql=true
\ No newline at end of file
+drawbridge.hibernate.show_sql=true
+#drawbridge.quartz.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+drawbridge.quartz.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegate
+drawbridge.quartz.selectWithLockSQL=SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE
\ No newline at end of file
Modified: trunk/drawbridge/WebContent/WEB-INF/drawbridge-servlet.xml
===================================================================
--- trunk/drawbridge/WebContent/WEB-INF/drawbridge-servlet.xml 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/WebContent/WEB-INF/drawbridge-servlet.xml 2008-10-11 01:48:39 UTC (rev 51)
@@ -6,10 +6,7 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
- <import resource="classpath:drawbridge-core-spring.xml"/>
- <import resource="classpath:drawbridge-env-spring.xml"/>
<context:component-scan base-package="net.sf.drawbridge.controller"/>
- <context:property-placeholder location="classpath:drawbridge.properties"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
Modified: trunk/drawbridge/WebContent/WEB-INF/web.xml
===================================================================
--- trunk/drawbridge/WebContent/WEB-INF/web.xml 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/WebContent/WEB-INF/web.xml 2008-10-11 01:48:39 UTC (rev 51)
@@ -6,6 +6,16 @@
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/drawbridge-servlet.xml</param-value>
</context-param>
+
+ <context-param>
+ <param-name>locatorFactorySelector</param-name>
+ <param-value>classpath*:beanRefFactory.xml</param-value>
+ </context-param>
+
+ <context-param>
+ <param-name>parentContextKey</param-name>
+ <param-value>drawbridge</param-value>
+ </context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
Added: trunk/drawbridge/src/java/beanRefFactory.xml
===================================================================
--- trunk/drawbridge/src/java/beanRefFactory.xml (rev 0)
+++ trunk/drawbridge/src/java/beanRefFactory.xml 2008-10-11 01:48:39 UTC (rev 51)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
+
+<beans>
+
+ <bean id="drawbridge" class="org.springframework.context.support.ClassPathXmlApplicationContext">
+ <constructor-arg>
+ <list>
+ <value>drawbridge-core-spring.xml</value>
+ <value>drawbridge-env-spring.xml</value>
+ </list>
+ </constructor-arg>
+ </bean>
+
+</beans>
\ No newline at end of file
Modified: trunk/drawbridge/src/java/drawbridge-core-spring.xml
===================================================================
--- trunk/drawbridge/src/java/drawbridge-core-spring.xml 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/src/java/drawbridge-core-spring.xml 2008-10-11 01:48:39 UTC (rev 51)
@@ -3,7 +3,8 @@
<beans>
<import resource="net/sf/drawbridge/dao/drawbridge-dao-spring.xml"/>
-
+ <import resource="net/sf/drawbridge/sched/drawbridge-quartz-spring.xml"/>
+
<bean id="DrawbridgeService" class="net.sf.drawbridge.domain.SecureDrawbridgeService">
<constructor-arg>
<bean id="DefaultDrawbridgeService" class="net.sf.drawbridge.domain.DefaultDrawbridgeService">
@@ -23,18 +24,6 @@
<bean id="SecurityService" class="net.sf.drawbridge.security.DefaultSecurityService"/>
- <bean id="Scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="autoStartup" value="true"/>
- <property name="globalJobListeners">
- <list></list>
- </property>
- <property name="overwriteExistingJobs" value="true"/>
- </bean>
-
- <bean id="ScheduleLoader" class="net.sf.drawbridge.sched.QuartzDrawbridgeScheduleLoader">
- <constructor-arg ref="Scheduler"/>
- </bean>
-
<bean id="QueryParser" class="net.sf.drawbridge.exec.DefaultQueryParser"/>
<bean id="JobExecuter" class="net.sf.drawbridge.exec.DefaultJobExecuter"/>
Modified: trunk/drawbridge/src/java/drawbridge-env-spring.xml
===================================================================
--- trunk/drawbridge/src/java/drawbridge-env-spring.xml 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/src/java/drawbridge-env-spring.xml 2008-10-11 01:48:39 UTC (rev 51)
@@ -1,8 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
-<beans>
+ <context:property-placeholder location="classpath:drawbridge.properties"/>
+
<bean id="DataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:/comp/env/jdbc/DrawbridgeDataSource"/>
</bean>
-</beans>
+</beans>
\ No newline at end of file
Modified: trunk/drawbridge/src/java/net/sf/drawbridge/dao/JobDao.java
===================================================================
--- trunk/drawbridge/src/java/net/sf/drawbridge/dao/JobDao.java 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/src/java/net/sf/drawbridge/dao/JobDao.java 2008-10-11 01:48:39 UTC (rev 51)
@@ -22,7 +22,8 @@
import net.sf.drawbridge.vo.Job;
public interface JobDao extends Dao<Job, Long>{
-
+ public static final String BEAN_NAME = "JobDao";
+
List<Job> getJobsForDatabase(Integer databaseId);
}
Modified: trunk/drawbridge/src/java/net/sf/drawbridge/exec/JobExecuter.java
===================================================================
--- trunk/drawbridge/src/java/net/sf/drawbridge/exec/JobExecuter.java 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/src/java/net/sf/drawbridge/exec/JobExecuter.java 2008-10-11 01:48:39 UTC (rev 51)
@@ -26,6 +26,7 @@
import net.sf.drawbridge.vo.RunAsAccount;
public interface JobExecuter {
+ public static final String BEAN_NAME="JobExecuter";
public List<Map<String, Object>> executeJob(Driver driver, Database database, RunAsAccount runAsAccount, String query, List<QueryParam> params) throws Exception;
Added: trunk/drawbridge/src/java/net/sf/drawbridge/sched/ExecuteQueryJob.java
===================================================================
--- trunk/drawbridge/src/java/net/sf/drawbridge/sched/ExecuteQueryJob.java (rev 0)
+++ trunk/drawbridge/src/java/net/sf/drawbridge/sched/ExecuteQueryJob.java 2008-10-11 01:48:39 UTC (rev 51)
@@ -0,0 +1,121 @@
+/*
+ * This file is part of DrawBridge.
+ * Copyright 2008 Ben La Monica
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation,Inc.,51 Franklin Street,Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package net.sf.drawbridge.sched;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import net.sf.drawbridge.dao.JobDao;
+import net.sf.drawbridge.exec.JobExecuter;
+import net.sf.drawbridge.exec.handler.ResultHandler;
+import net.sf.drawbridge.util.StringPropertiesConverter;
+import net.sf.drawbridge.vo.Database;
+import net.sf.drawbridge.vo.Driver;
+import net.sf.drawbridge.vo.Job;
+import net.sf.drawbridge.vo.QueryParam;
+import net.sf.drawbridge.vo.RunAsAccount;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.quartz.SchedulerException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.access.SingletonBeanFactoryLocator;
+
+public class ExecuteQueryJob implements org.quartz.Job {
+
+ private static final Log log = LogFactory.getLog(ExecuteQueryJob.class);
+
+ private JobExecuter executer;
+
+ private JobDao jobDao;
+
+ private StringPropertiesConverter propConverter;
+
+ static BeanFactory factory;
+
+ private static synchronized BeanFactory getFactory() {
+ if (factory == null) {
+ factory = SingletonBeanFactoryLocator.getInstance().useBeanFactory("drawbridge").getFactory();
+ }
+ return factory;
+ }
+
+ private static Object getBean(String name) {
+ Object bean = getFactory().getBean(name);
+ if (bean == null) {
+ throw new IllegalArgumentException("Unable to look up the bean with name: " + name);
+ }
+
+ return bean;
+ }
+
+ /**
+ * Default constructor, will retrieve necessary dependencies from the Spring context.
+ * NOTE: Do not use this constructor if you are using this within a spring config, or you will
+ * cause a circular dependency and it will throw an exception on startup.
+ */
+ public ExecuteQueryJob() {
+ this((JobDao) getBean(JobDao.BEAN_NAME),
+ (JobExecuter) getBean(JobExecuter.BEAN_NAME),
+ (StringPropertiesConverter) getBean(StringPropertiesConverter.BEAN_NAME));
+ }
+
+ public ExecuteQueryJob(JobDao jobDao, JobExecuter executer, StringPropertiesConverter propConverter) {
+ this.jobDao = jobDao;
+ this.executer = executer;
+ this.propConverter = propConverter;
+ }
+
+ public void execute(JobExecutionContext ctx) throws JobExecutionException {
+ Job job = jobDao.get(new Long(ctx.getJobDetail().getName()));
+
+ if (job != null && job.isActive()) {
+ RunAsAccount runAs = job.getRunAsAccount();
+ Database db = runAs.getDatabase();
+ Driver driver = db.getDriver();
+ String query = job.getQuery();
+ ResultHandler handler = (ResultHandler) getBean(job.getHandler());
+ String handlerParams = job.getHandlerParams();
+ List<QueryParam> params = Collections.emptyList();
+ try {
+ List<Map<String, Object>> results = executer.executeJob(driver, db, runAs, query, params);
+ handler.handleQuery(results, propConverter.convertToProperties(handlerParams));
+ ctx.setResult(Boolean.TRUE);
+ } catch (Exception e) {
+ ctx.setResult(e);
+ log.error("Unable to run job #" + job.getId() + ": " + job.getName(), e);
+ }
+ } else {
+ // job either doesn't exist in the database or is inactive, so we should not have it in the scheduler
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("Attempting to remove job [" + ctx.getJobDetail() + "] from Scheduler.");
+ }
+ ctx.getScheduler().deleteJob(ctx.getJobDetail().getName(), ctx.getJobDetail().getGroup());
+ } catch (SchedulerException e) {
+ if (log.isWarnEnabled()) {
+ log.warn("Unable to remove job from scheduler because of '" + e.getLocalizedMessage() + "'.");
+ }
+ }
+ }
+ }
+
+}
Deleted: trunk/drawbridge/src/java/net/sf/drawbridge/sched/HeartBeatJob.java
===================================================================
--- trunk/drawbridge/src/java/net/sf/drawbridge/sched/HeartBeatJob.java 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/src/java/net/sf/drawbridge/sched/HeartBeatJob.java 2008-10-11 01:48:39 UTC (rev 51)
@@ -1,34 +0,0 @@
-/*
- * This file is part of DrawBridge.
- * Copyright 2008 Adam Cresse
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation,Inc.,51 Franklin Street,Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package net.sf.drawbridge.sched;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.quartz.Job;
-import org.quartz.JobExecutionContext;
-import org.quartz.JobExecutionException;
-
-public class HeartBeatJob implements Job{
-
- private static final Log log=LogFactory.getLog(HeartBeatJob.class);
-
- public void execute(JobExecutionContext ctx) throws JobExecutionException {
- log.debug("Scheduler is still up and running.");
- }
-
-}
Modified: trunk/drawbridge/src/java/net/sf/drawbridge/sched/QuartzDrawbridgeScheduleLoader.java
===================================================================
--- trunk/drawbridge/src/java/net/sf/drawbridge/sched/QuartzDrawbridgeScheduleLoader.java 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/src/java/net/sf/drawbridge/sched/QuartzDrawbridgeScheduleLoader.java 2008-10-11 01:48:39 UTC (rev 51)
@@ -17,28 +17,74 @@
*/
package net.sf.drawbridge.sched;
+import java.util.List;
+
+import net.sf.drawbridge.dao.JobDao;
+import net.sf.drawbridge.vo.Job;
+import net.sf.drawbridge.vo.Schedule;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.Trigger;
public class QuartzDrawbridgeScheduleLoader implements DrawbridgeScheduleLoader {
+
+ private static final Log log = LogFactory.getLog(QuartzDrawbridgeScheduleLoader.class);
+ private JobDao jobDao;
+
private Scheduler scheduler;
- public QuartzDrawbridgeScheduleLoader(Scheduler scheduler) throws Exception{
+ private Class<? extends org.quartz.Job> jobClass;
+
+ public QuartzDrawbridgeScheduleLoader(Scheduler scheduler, JobDao jobDao) {
+ this(scheduler, jobDao, ExecuteQueryJob.class);
+ }
+
+ public QuartzDrawbridgeScheduleLoader(Scheduler scheduler, JobDao jobDao, Class<? extends org.quartz.Job> jobClass) {
this.scheduler=scheduler;
- loadSchedule();
+ this.jobDao = jobDao;
+ this.jobClass = jobClass;
}
public void loadSchedule() throws Exception{
- JobDetail jobDetail=new JobDetail("heartbeat","system",HeartBeatJob.class);
- CronTrigger trigger = new CronTrigger("heartbeat-trigger", "system", "heartbeat", "system", "0/60 * * * * ?");
- try{
- //this is getting called twice because 2 contexts are being created after the context loader listener was added
- //dwr needs the context loader listener
- scheduler.scheduleJob(jobDetail,trigger);
- } catch(Exception ex){
- ex.printStackTrace();
+ List<Job> jobs = jobDao.getAll();
+
+ for (Job job : jobs) {
+ if (job.isActive()) {
+ if (log.isDebugEnabled()) {
+ log.debug("Scheduling Job #" + job.getId() + ": " + job.getName() + ".");
+ }
+
+ String jobId = String.valueOf(job.getId());
+ String jobGroupId = String.valueOf(job.getRunAsAccount().getId());
+ JobDetail detail = new JobDetail(jobId, jobGroupId, jobClass);
+ detail.setDescription(job.getName());
+ for (Schedule schedule : job.getSchedules()) {
+ Trigger trigger = new CronTrigger(
+ String.valueOf(schedule.getId()), // trigger id
+ jobId, // trigger group
+ jobId, // job id
+ jobGroupId, // job group id
+ schedule.getStartDate(), // start time
+ schedule.getStopDate(), // stop time
+ schedule.getSchedule()); // cron expression
+
+ try {
+ scheduler.scheduleJob(detail, trigger);
+ } catch (SchedulerException e) {
+ log.error("Unable to schedule Job #" + job.getId() + ": " + job.getName() + ".", e);
+ }
+ }
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("Job #" + job.getId() + ": " + job.getName() + " is not active, will not schedule.");
+ }
+ }
}
}
Added: trunk/drawbridge/src/java/net/sf/drawbridge/sched/drawbridge-quartz-spring.xml
===================================================================
--- trunk/drawbridge/src/java/net/sf/drawbridge/sched/drawbridge-quartz-spring.xml (rev 0)
+++ trunk/drawbridge/src/java/net/sf/drawbridge/sched/drawbridge-quartz-spring.xml 2008-10-11 01:48:39 UTC (rev 51)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
+
+<beans>
+ <bean id="Scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
+ <property name="autoStartup" value="true"/>
+ <property name="dataSource" ref="DataSource"/>
+ <property name="quartzProperties">
+ <props>
+ <prop key="org.quartz.jobStore.driverDelegateClass">${drawbridge.quartz.driverDelegateClass}</prop>
+ <prop key="org.quartz.jobStore.selectWithLockSQL">${drawbridge.quartz.selectWithLockSQL}</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean id="ScheduleLoader" class="net.sf.drawbridge.sched.QuartzDrawbridgeScheduleLoader" init-method="loadSchedule">
+ <constructor-arg ref="Scheduler"/>
+ <constructor-arg ref="JobDao"/>
+ </bean>
+</beans>
Modified: trunk/drawbridge/src/java/net/sf/drawbridge/util/StringPropertiesConverter.java
===================================================================
--- trunk/drawbridge/src/java/net/sf/drawbridge/util/StringPropertiesConverter.java 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/src/java/net/sf/drawbridge/util/StringPropertiesConverter.java 2008-10-11 01:48:39 UTC (rev 51)
@@ -3,7 +3,8 @@
import java.util.Properties;
public interface StringPropertiesConverter {
-
+ public static final String BEAN_NAME = "StringPropertiesConverter";
+
public String convertToString(Properties properties);
public Properties convertToProperties(String string) throws Exception;
Modified: trunk/drawbridge/src/sql/create_drawbridge_schema.sql
===================================================================
--- trunk/drawbridge/src/sql/create_drawbridge_schema.sql 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/src/sql/create_drawbridge_schema.sql 2008-10-11 01:48:39 UTC (rev 51)
@@ -1,14 +1,15 @@
-DROP TABLE DB_USER;
-DROP TABLE DB_GROUP;
-DROP TABLE DB_USER_GROUP;
-DROP TABLE DB_DRIVER;
-DROP TABLE DB_DATABASE;
-DROP TABLE DB_RUN_AS;
-DROP TABLE DB_JOB;
-DROP TABLE DB_PERMISSION_LIST;
-DROP TABLE DB_SYSTEM_PERMISSION;
-DROP TABLE DB_DATABASE_PERMISSION;
-DROP TABLE DB_RUN_AS_PERMISSION;
+DROP TABLE IF EXISTS DB_USER;
+DROP TABLE IF EXISTS DB_GROUP;
+DROP TABLE IF EXISTS DB_USER_GROUP;
+DROP TABLE IF EXISTS DB_DRIVER;
+DROP TABLE IF EXISTS DB_DATABASE;
+DROP TABLE IF EXISTS DB_RUN_AS;
+DROP TABLE IF EXISTS DB_SCHEDULE;
+DROP TABLE IF EXISTS DB_JOB;
+DROP TABLE IF EXISTS DB_PERMISSION_LIST;
+DROP TABLE IF EXISTS DB_SYSTEM_PERMISSION;
+DROP TABLE IF EXISTS DB_DATABASE_PERMISSION;
+DROP TABLE IF EXISTS DB_RUN_AS_PERMISSION;
CREATE TABLE DB_USER(
ID INTEGER NOT NULL AUTO_INCREMENT,
@@ -18,14 +19,14 @@
ACTIVE VARCHAR(1) NOT NULL DEFAULT 'Y',
PRIMARY KEY (ID),
CONSTRAINT UNQ_DB_USER UNIQUE (USER_NAME)
-);
+) TYPE=InnoDB;
CREATE TABLE DB_GROUP(
ID INTEGER NOT NULL AUTO_INCREMENT,
GROUP_NAME VARCHAR(16) NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT UNQ_DB_GROUP UNIQUE (GROUP_NAME)
-);
+) TYPE=InnoDB;
CREATE TABLE DB_USER_GROUP(
USER_ID INTEGER NOT NULL,
@@ -33,7 +34,7 @@
PRIMARY KEY (USER_ID, GROUP_ID),
CONSTRAINT FK_DB_USER_GROUP_DB_USER FOREIGN KEY FK_DB_USER_GROUP_DB_USER (USER_ID) REFERENCES DB_USER (ID) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FK_DB_USER_GROUP_DB_GROUP FOREIGN KEY FK_DB_USER_GROUP_DB_GROUP (GROUP_ID) REFERENCES DB_GROUP (ID) ON DELETE CASCADE ON UPDATE CASCADE
-);
+) TYPE=InnoDB;
CREATE TABLE DB_DRIVER(
ID INTEGER NOT NULL AUTO_INCREMENT,
@@ -41,7 +42,7 @@
CLASS_NAME VARCHAR(128) NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT UNQ_DB_DRIVER UNIQUE (NAME)
-);
+) TYPE=InnoDB;
CREATE TABLE DB_DATABASE(
ID INTEGER NOT NULL AUTO_INCREMENT,
@@ -51,7 +52,7 @@
PRIMARY KEY (ID),
CONSTRAINT FK_DB_DATABASE_DB_DRIVER FOREIGN KEY FK_DB_DATABASE_DB_DRIVER (DRIVER_ID) REFERENCES DB_DRIVER (ID),
CONSTRAINT UNQ_DB_DATABASE UNIQUE (NAME)
-);
+) TYPE=InnoDB;
CREATE TABLE DB_RUN_AS(
ID INTEGER NOT NULL AUTO_INCREMENT,
@@ -61,7 +62,7 @@
PRIMARY KEY (ID),
CONSTRAINT FK_DB_RUN_AS_DB_DATABASE FOREIGN KEY FK_DB_RUN_AS_DB_DATABASE (DATABASE_ID) REFERENCES DB_DATABASE (ID),
CONSTRAINT UNQ_DB_RUN_AS UNIQUE (USER_NAME, DATABASE_ID)
-);
+) TYPE=InnoDB;
CREATE TABLE DB_JOB(
ID INTEGER NOT NULL AUTO_INCREMENT,
@@ -85,7 +86,7 @@
CONSTRAINT FK_DB_JOB_APPROVED_BY FOREIGN KEY FK_DB_JOB_APPROVED_BY (APPROVED_BY) REFERENCES DB_USER (ID),
CONSTRAINT UNQ_DB_JOB UNIQUE (NAME),
CONSTRAINT CHK_DB_JOB_ACTIVE CHECK ACTIVE IN ('Y','N')
-);
+) TYPE=InnoDB;
CREATE TABLE DB_SCHEDULE(
ID INTEGER NOT NULL AUTO_INCREMENT,
@@ -96,7 +97,7 @@
VERSION INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY(ID),
CONSTRAINT FK_DB_SCHEDULE_DB_JOB FOREIGN KEY FK_DB_SCHEDULE_DB_JOB (JOB_ID) REFERENCES DB_JOB(ID)
-);
+) TYPE=InnoDB;
CREATE TABLE DB_PERMISSION_LIST(
ID INTEGER NOT NULL,
@@ -105,7 +106,7 @@
PRIMARY KEY (ID),
CONSTRAINT UNQ_DB_PERMISSION UNIQUE (NAME, PERMISSION_TYPE),
CONSTRAINT CHK_DB_PERMISSION_LIST_PERMISSION_TYPE CHECK PERMISSION_TYPE IN ('S','D','R')
-);
+) TYPE=InnoDB;
CREATE TABLE DB_SYSTEM_PERMISSION(
ID INTEGER NOT NULL AUTO_INCREMENT,
@@ -115,7 +116,7 @@
CONSTRAINT FK_DB_SYSTEM_PERMISSION_DB_GROUP FOREIGN KEY FK_DB_SYSTEM_PERMISSION_DB_GROUP (GROUP_ID) REFERENCES DB_GROUP (ID) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FK_DB_SYSTEM_PERMISSION_DB_PERMISSION_LIST FOREIGN KEY FK_DB_SYSTEM_PERMISSION_DB_PERMISSION_LIST (PERMISSION_ID) REFERENCES DB_PERMISSION_LIST (ID) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT UNQ_DB_SYSTEM_PERMISSION UNIQUE (GROUP_ID, PERMISSION_ID)
-);
+) TYPE=InnoDB;
CREATE TABLE DB_DATABASE_PERMISSION(
ID INTEGER NOT NULL AUTO_INCREMENT,
@@ -127,7 +128,7 @@
CONSTRAINT FK_DB_DATABASE_PERMISSION_DB_DATABASE FOREIGN KEY FK_DB_DATABASE_PERMISSION_DB_DATABASE (DATABASE_ID) REFERENCES DB_DATABASE (ID) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FK_DB_DATABASE_PERMISSION_DB_PERMISSION_LIST FOREIGN KEY FK_DB_DATABASE_PERMISSION_DB_PERMISSION_LIST (PERMISSION_ID) REFERENCES DB_PERMISSION_LIST (ID) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT UNQ_DB_GRAP UNIQUE (GROUP_ID, DATABASE_ID, PERMISSION_ID)
-);
+) TYPE=InnoDB;
CREATE TABLE DB_RUN_AS_PERMISSION(
ID INTEGER NOT NULL AUTO_INCREMENT,
@@ -139,7 +140,7 @@
CONSTRAINT FK_DB_RUN_AS_PERMISSION_DB_RUN_AS FOREIGN KEY FK_DB_RUN_AS_PERMISSION_DB_RUN_AS (RUN_AS_ID) REFERENCES DB_RUN_AS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FK_DB_RUN_AS_PERMISSION_DB_PERMISSION_LIST FOREIGN KEY FK_DB_RUN_AS_PERMISSION_DB_PERMISSION_LIST (PERMISSION_ID) REFERENCES DB_PERMISSION_LIST (ID) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT UNQ_DB_GRAP UNIQUE (GROUP_ID, RUN_AS_ID, PERMISSION_ID)
-);
+) TYPE=InnoDB;
INSERT INTO DB_PERMISSION_LIST (ID, NAME, PERMISSION_TYPE) VALUES (1,'ADD USER','S');
INSERT INTO DB_PERMISSION_LIST (ID, NAME, PERMISSION_TYPE) VALUES (2,'EDIT USER','S');
@@ -179,4 +180,151 @@
INSERT INTO DB_PERMISSION_LIST (ID, NAME, PERMISSION_TYPE) VALUES (209,'DOES NOT REQUIRE APPROVAL FOR RUN-AS','R');
INSERT INTO DB_PERMISSION_LIST (ID, NAME, PERMISSION_TYPE) VALUES (210,'GRANT PERMISSIONS FOR RUN-AS','R');
-COMMIT;
\ No newline at end of file
+COMMIT;
+
+DROP TABLE IF EXISTS QRTZ_JOB_LISTENERS;
+DROP TABLE IF EXISTS QRTZ_TRIGGER_LISTENERS;
+DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
+DROP TABLE IF EXISTS QRTZ_LOCKS;
+DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
+DROP TABLE IF EXISTS QRTZ_CALENDARS;
+
+CREATE TABLE QRTZ_JOB_DETAILS(
+JOB_NAME VARCHAR(200) NOT NULL,
+JOB_GROUP VARCHAR(200) NOT NULL,
+DESCRIPTION VARCHAR(250) NULL,
+JOB_CLASS_NAME VARCHAR(250) NOT NULL,
+IS_DURABLE VARCHAR(1) NOT NULL,
+IS_VOLATILE VARCHAR(1) NOT NULL,
+IS_STATEFUL VARCHAR(1) NOT NULL,
+REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
+JOB_DATA BLOB NULL,
+PRIMARY KEY (JOB_NAME,JOB_GROUP))
+TYPE=InnoDB;
+
+CREATE TABLE QRTZ_JOB_LISTENERS (
+JOB_NAME VARCHAR(200) NOT NULL,
+JOB_GROUP VARCHAR(200) NOT NULL,
+JOB_LISTENER VARCHAR(200) NOT NULL,
+PRIMARY KEY (JOB_NAME,JOB_GROUP,JOB_LISTENER),
+INDEX (JOB_NAME, JOB_GROUP),
+FOREIGN KEY (JOB_NAME,JOB_GROUP)
+REFERENCES QRTZ_JOB_DETAILS(JOB_NAME,JOB_GROUP))
+TYPE=InnoDB;
+
+CREATE TABLE QRTZ_TRIGGERS (
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+JOB_NAME VARCHAR(200) NOT NULL,
+JOB_GROUP VARCHAR(200) NOT NULL,
+IS_VOLATILE VARCHAR(1) NOT NULL,
+DESCRIPTION VARCHAR(250) NULL,
+NEXT_FIRE_TIME BIGINT(13) NULL,
+PREV_FIRE_TIME BIGINT(13) NULL,
+PRIORITY INTEGER NULL,
+TRIGGER_STATE VARCHAR(16) NOT NULL,
+TRIGGER_TYPE VARCHAR(8) NOT NULL,
+START_TIME BIGINT(13) NOT NULL,
+END_TIME BIGINT(13) NULL,
+CALENDAR_NAME VARCHAR(200) NULL,
+MISFIRE_INSTR SMALLINT(2) NULL,
+JOB_DATA BLOB NULL,
+PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP),
+INDEX (JOB_NAME, JOB_GROUP),
+FOREIGN KEY (JOB_NAME,JOB_GROUP)
+REFERENCES QRTZ_JOB_DETAILS(JOB_NAME,JOB_GROUP))
+TYPE=InnoDB;
+
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+REPEAT_COUNT BIGINT(7) NOT NULL,
+REPEAT_INTERVAL BIGINT(12) NOT NULL,
+TIMES_TRIGGERED BIGINT(7) NOT NULL,
+PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP),
+INDEX (TRIGGER_NAME, TRIGGER_GROUP),
+FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP))
+TYPE=InnoDB;
+
+CREATE TABLE QRTZ_CRON_TRIGGERS (
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+CRON_EXPRESSION VARCHAR(120) NOT NULL,
+TIME_ZONE_ID VARCHAR(80),
+PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP),
+INDEX (TRIGGER_NAME, TRIGGER_GROUP),
+FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP))
+TYPE=InnoDB;
+
+CREATE TABLE QRTZ_BLOB_TRIGGERS (
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+BLOB_DATA BLOB NULL,
+PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP),
+INDEX (TRIGGER_NAME, TRIGGER_GROUP),
+FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP))
+TYPE=InnoDB;
+
+CREATE TABLE QRTZ_TRIGGER_LISTENERS (
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+TRIGGER_LISTENER VARCHAR(200) NOT NULL,
+PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_LISTENER),
+INDEX (TRIGGER_NAME, TRIGGER_GROUP),
+FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP)
+REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP))
+TYPE=InnoDB;
+
+CREATE TABLE QRTZ_CALENDARS (
+CALENDAR_NAME VARCHAR(200) NOT NULL,
+CALENDAR BLOB NOT NULL,
+PRIMARY KEY (CALENDAR_NAME))
+TYPE=InnoDB;
+
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+PRIMARY KEY (TRIGGER_GROUP))
+TYPE=InnoDB;
+
+CREATE TABLE QRTZ_FIRED_TRIGGERS (
+ENTRY_ID VARCHAR(95) NOT NULL,
+TRIGGER_NAME VARCHAR(200) NOT NULL,
+TRIGGER_GROUP VARCHAR(200) NOT NULL,
+IS_VOLATILE VARCHAR(1) NOT NULL,
+INSTANCE_NAME VARCHAR(200) NOT NULL,
+PRIORITY INTEGER NOT NULL,
+STATE VARCHAR(16) NOT NULL,
+JOB_NAME VARCHAR(200) NULL,
+JOB_GROUP VARCHAR(200) NULL,
+IS_STATEFUL VARCHAR(1) NULL,
+REQUESTS_RECOVERY VARCHAR(1) NULL,
+PRIMARY KEY (ENTRY_ID))
+TYPE=InnoDB;
+
+CREATE TABLE QRTZ_SCHEDULER_STATE (
+INSTANCE_NAME VARCHAR(200) NOT NULL,
+LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
+CHECKIN_INTERVAL BIGINT(13) NOT NULL,
+PRIMARY KEY (INSTANCE_NAME))
+TYPE=InnoDB;
+
+CREATE TABLE QRTZ_LOCKS (
+LOCK_NAME VARCHAR(40) NOT NULL,
+PRIMARY KEY (LOCK_NAME))
+TYPE=InnoDB;
+
+INSERT INTO QRTZ_LOCKS values('TRIGGER_ACCESS');
+INSERT INTO QRTZ_LOCKS values('JOB_ACCESS');
+INSERT INTO QRTZ_LOCKS values('CALENDAR_ACCESS');
+INSERT INTO QRTZ_LOCKS values('STATE_ACCESS');
+INSERT INTO QRTZ_LOCKS values('MISFIRE_ACCESS');
+commit;
\ No newline at end of file
Modified: trunk/drawbridge/src/sql/example_data.sql
===================================================================
--- trunk/drawbridge/src/sql/example_data.sql 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/src/sql/example_data.sql 2008-10-11 01:48:39 UTC (rev 51)
@@ -14,6 +14,6 @@
INSERT INTO DB_USER_GROUP (USER_ID,GROUP_ID) VALUES (-1,-1);
-INSERT INTO DB_JOB (ID,NAME,RUN_AS_ID,QUERY,SUBMITTED_BY,SUBMITTED_ON,REVIEWED_BY,REVIEWED_ON,APPROVED_BY,APPROVED_ON,ACTIVE,SCHEDULE,HANDLER,HANDLER_PARAMS) VALUES (-1,'all jobs',-2,'SELECT * FROM DB_JOB',-1,{d '2008-03-19'},null,null,null,null,'Y',null,'NoOpResultHandler',null);
+INSERT INTO DB_JOB (ID,NAME,RUN_AS_ID,QUERY,SUBMITTED_BY,SUBMITTED_ON,REVIEWED_BY,REVIEWED_ON,APPROVED_BY,APPROVED_ON,ACTIVE,HANDLER,HANDLER_PARAMS) VALUES (-1,'all jobs',-2,'SELECT * FROM DB_JOB',-1,{d '2008-03-19'},null,null,null,null,'Y','NoOpResultHandler',null);
COMMIT;
\ No newline at end of file
Modified: trunk/drawbridge/src/test/db.script
===================================================================
--- trunk/drawbridge/src/test/db.script 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/src/test/db.script 2008-10-11 01:48:39 UTC (rev 51)
@@ -13,6 +13,18 @@
CREATE MEMORY TABLE DB_SYSTEM_PERMISSION(GROUP_ID INTEGER NOT NULL,PERMISSION_ID INTEGER NOT NULL,PRIMARY KEY(GROUP_ID,PERMISSION_ID),CONSTRAINT FK_DB_SYSTEM_PERMISSION_DB_GROUP FOREIGN KEY(GROUP_ID) REFERENCES PUBLIC.DB_GROUP(ID) ON DELETE CASCADE ON UPDATE CASCADE,CONSTRAINT FK_DB_SYSTEM_PERMISSION_DB_PERMISSION_LIST FOREIGN KEY(PERMISSION_ID) REFERENCES PUBLIC.DB_PERMISSION_LIST(ID) ON DELETE CASCADE ON UPDATE CASCADE)
CREATE MEMORY TABLE DB_DATABASE_PERMISSION(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,GROUP_ID INTEGER NOT NULL,DATABASE_ID INTEGER NOT NULL,PERMISSION_ID INTEGER NOT NULL,CONSTRAINT FK_DB_DATABASE_PERMISSION_DB_GROUP FOREIGN KEY(GROUP_ID) REFERENCES PUBLIC.DB_GROUP(ID) ON DELETE CASCADE ON UPDATE CASCADE,CONSTRAINT FK_DB_DATABASE_PERMISSION_DB_DATABASE FOREIGN KEY(DATABASE_ID) REFERENCES PUBLIC.DB_DATABASE(ID) ON DELETE CASCADE ON UPDATE CASCADE,CONSTRAINT FK_DB_DATABASE_PERMISSION_DB_PERMISSION_LIST FOREIGN KEY(PERMISSION_ID) REFERENCES PUBLIC.DB_PERMISSION_LIST(ID) ON DELETE CASCADE ON UPDATE CASCADE,CONSTRAINT UNQ_DB_GRAP UNIQUE(GROUP_ID,DATABASE_ID,PERMISSION_ID))
CREATE MEMORY TABLE DB_RUN_AS_PERMISSION(GROUP_ID INTEGER NOT NULL,RUN_AS_ID INTEGER NOT NULL,PERMISSION_ID INTEGER NOT NULL,PRIMARY KEY(GROUP_ID,RUN_AS_ID,PERMISSION_ID),CONSTRAINT FK_DB_RUN_AS_PERMISSION_DB_GROUP FOREIGN KEY(GROUP_ID) REFERENCES PUBLIC.DB_GROUP(ID) ON DELETE CASCADE ON UPDATE CASCADE,CONSTRAINT FK_DB_RUN_AS_PERMISSION_DB_RUN_AS FOREIGN KEY(RUN_AS_ID) REFERENCES PUBLIC.DB_RUN_AS(ID) ON DELETE CASCADE ON UPDATE CASCADE,CONSTRAINT FK_DB_RUN_AS_PERMISSION_DB_PERMISSION_LIST FOREIGN KEY(PERMISSION_ID) REFERENCES PUBLIC.DB_PERMISSION_LIST(ID) ON DELETE CASCADE ON UPDATE CASCADE)
+CREATE MEMORY TABLE QRTZ_JOB_DETAILS(JOB_NAME VARCHAR(200) NOT NULL,JOB_GROUP VARCHAR(200) NOT NULL,DESCRIPTION VARCHAR(250),JOB_CLASS_NAME VARCHAR(250) NOT NULL,IS_DURABLE BOOLEAN NOT NULL,IS_VOLATILE BOOLEAN NOT NULL,IS_STATEFUL BOOLEAN NOT NULL,REQUESTS_RECOVERY BOOLEAN NOT NULL,JOB_DATA BINARY,PRIMARY KEY(JOB_NAME,JOB_GROUP))
+CREATE MEMORY TABLE QRTZ_JOB_LISTENERS(JOB_NAME VARCHAR(200) NOT NULL,JOB_GROUP VARCHAR(200) NOT NULL,JOB_LISTENER VARCHAR(200) NOT NULL,PRIMARY KEY(JOB_NAME,JOB_GROUP,JOB_LISTENER),FOREIGN KEY(JOB_NAME,JOB_GROUP) REFERENCES PUBLIC.QRTZ_JOB_DETAILS(JOB_NAME,JOB_GROUP))
+CREATE MEMORY TABLE QRTZ_TRIGGERS(TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,JOB_NAME VARCHAR(200) NOT NULL,JOB_GROUP VARCHAR(200) NOT NULL,IS_VOLATILE BOOLEAN NOT NULL,DESCRIPTION VARCHAR(250),NEXT_FIRE_TIME NUMERIC(13,0),PREV_FIRE_TIME NUMERIC(13,0),PRIORITY INTEGER,TRIGGER_STATE VARCHAR(16) NOT NULL,TRIGGER_TYPE VARCHAR(8) NOT NULL,START_TIME NUMERIC(13,0) NOT NULL,END_TIME NUMERIC(13,0),CALENDAR_NAME VARCHAR(200),MISFIRE_INSTR NUMERIC(2,0),JOB_DATA BINARY,PRIMARY KEY(TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY(JOB_NAME,JOB_GROUP) REFERENCES PUBLIC.QRTZ_JOB_DETAILS(JOB_NAME,JOB_GROUP))
+CREATE MEMORY TABLE QRTZ_SIMPLE_TRIGGERS(TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,REPEAT_COUNT NUMERIC(7,0) NOT NULL,REPEAT_INTERVAL NUMERIC(12,0) NOT NULL,TIMES_TRIGGERED NUMERIC(7,0) NOT NULL,PRIMARY KEY(TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY(TRIGGER_NAME,TRIGGER_GROUP) REFERENCES PUBLIC.QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP))
+CREATE MEMORY TABLE QRTZ_CRON_TRIGGERS(TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,CRON_EXPRESSION VARCHAR(120) NOT NULL,TIME_ZONE_ID VARCHAR(80),PRIMARY KEY(TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY(TRIGGER_NAME,TRIGGER_GROUP) REFERENCES PUBLIC.QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP))
+CREATE MEMORY TABLE QRTZ_BLOB_TRIGGERS(TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,BLOB_DATA BINARY,PRIMARY KEY(TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY(TRIGGER_NAME,TRIGGER_GROUP) REFERENCES PUBLIC.QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP))
+CREATE MEMORY TABLE QRTZ_TRIGGER_LISTENERS(TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,TRIGGER_LISTENER VARCHAR(200) NOT NULL,PRIMARY KEY(TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_LISTENER),FOREIGN KEY(TRIGGER_NAME,TRIGGER_GROUP) REFERENCES PUBLIC.QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP))
+CREATE MEMORY TABLE QRTZ_CALENDARS(CALENDAR_NAME VARCHAR(200) NOT NULL PRIMARY KEY,CALENDAR BINARY NOT NULL)
+CREATE MEMORY TABLE QRTZ_PAUSED_TRIGGER_GRPS(TRIGGER_GROUP VARCHAR(200) NOT NULL PRIMARY KEY)
+CREATE MEMORY TABLE QRTZ_FIRED_TRIGGERS(ENTRY_ID VARCHAR(95) NOT NULL PRIMARY KEY,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,IS_VOLATILE BOOLEAN NOT NULL,INSTANCE_NAME VARCHAR(200) NOT NULL,FIRED_TIME NUMERIC(13,0) NOT NULL,PRIORITY INTEGER NOT NULL,STATE VARCHAR(16) NOT NULL,JOB_NAME VARCHAR(200),JOB_GROUP VARCHAR(200),IS_STATEFUL BOOLEAN,REQUESTS_RECOVERY BOOLEAN)
+CREATE MEMORY TABLE QRTZ_SCHEDULER_STATE(INSTANCE_NAME VARCHAR(200) NOT NULL PRIMARY KEY,LAST_CHECKIN_TIME NUMERIC(13,0) NOT NULL,CHECKIN_INTERVAL NUMERIC(13,0) NOT NULL)
+CREATE MEMORY TABLE QRTZ_LOCKS(LOCK_NAME VARCHAR(40) NOT NULL PRIMARY KEY)
ALTER TABLE DB_USER ALTER COLUMN ID RESTART WITH 2
ALTER TABLE DB_GROUP ALTER COLUMN ID RESTART WITH 3
ALTER TABLE DB_DRIVER ALTER COLUMN ID RESTART WITH 1
@@ -40,8 +52,8 @@
INSERT INTO DB_RUN_AS VALUES(1,'dev','base64',0)
INSERT INTO DB_JOB VALUES(0,'Job 1',0,'select count(*) from dual',0,'2008-03-19 19:00:00.000000',1,'2008-03-20 18:00:00.000000',1,'2008-03-20 18:00:01.000000','Y','handler','testKey1=testVal1\u000atestKey2=testVal2')
INSERT INTO DB_JOB VALUES(1,'Job 2',0,'select count(*) from dual',0,'2008-03-19 19:00:00.000000',1,'2008-03-20 18:00:00.000000',1,'2008-03-20 18:00:01.000000','Y','handler','testKey1=testVal1\u000atestKey2=testVal2')
-INSERT INTO DB_SCHEDULE VALUES(0,0,NULL,NULL,'schedule',0)
-INSERT INTO DB_SCHEDULE VALUES(1,1,NULL,NULL,'schedule',0)
+INSERT INTO DB_SCHEDULE VALUES(0,0,NULL,NULL,'0/60 * * * * ?',0)
+INSERT INTO DB_SCHEDULE VALUES(1,1,NULL,NULL,'0/60 * * * * ?',0)
INSERT INTO DB_PERMISSION_LIST VALUES(1,'ADD USER','S')
INSERT INTO DB_PERMISSION_LIST VALUES(2,'EDIT USER','S')
INSERT INTO DB_PERMISSION_LIST VALUES(3,'DELETE USER','S')
@@ -72,3 +84,8 @@
INSERT INTO DB_PERMISSION_LIST VALUES(208,'DOES NOT REQUIRE REVIEW FOR RUN-AS','R')
INSERT INTO DB_PERMISSION_LIST VALUES(209,'DOES NOT REQUIRE APPROVAL FOR RUN-AS','R')
INSERT INTO DB_PERMISSION_LIST VALUES(210,'GRANT PERMISSIONS FOR RUN-AS','R')
+INSERT INTO QRTZ_LOCKS VALUES('CALENDAR_ACCESS')
+INSERT INTO QRTZ_LOCKS VALUES('JOB_ACCESS')
+INSERT INTO QRTZ_LOCKS VALUES('MISFIRE_ACCESS')
+INSERT INTO QRTZ_LOCKS VALUES('STATE_ACCESS')
+INSERT INTO QRTZ_LOCKS VALUES('TRIGGER_ACCESS')
Modified: trunk/drawbridge/src/test/drawbridge.properties
===================================================================
--- trunk/drawbridge/src/test/drawbridge.properties 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/src/test/drawbridge.properties 2008-10-11 01:48:39 UTC (rev 51)
@@ -1,2 +1,4 @@
drawbridge.hibernate.dialect=org.hibernate.dialect.HSQLDialect
+drawbridge.quartz.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegate
+drawbridge.quartz.selectWithLockSQL=SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ?
drawbridge.hibernate.show_sql=true
\ No newline at end of file
Modified: trunk/drawbridge/src/test/net/sf/drawbridge/dao/JobDaoTest.java
===================================================================
--- trunk/drawbridge/src/test/net/sf/drawbridge/dao/JobDaoTest.java 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/src/test/net/sf/drawbridge/dao/JobDaoTest.java 2008-10-11 01:48:39 UTC (rev 51)
@@ -76,7 +76,7 @@
assertEquals("approvedOn", "03-20-2008 18:00:01", df.format(result.getApprovedOn().getTime()));
assertTrue("active", result.isActive());
assertEquals("schedule", 1, result.getSchedules().size());
- assertEquals("schedule", "schedule", result.getSchedules().iterator().next().getSchedule());
+ assertEquals("schedule", "0/60 * * * * ?", result.getSchedules().iterator().next().getSchedule());
assertEquals("handler", "handler", result.getHandler());
assertEquals("handlerParams", params, result.getHandlerParams());
}
@@ -142,7 +142,7 @@
TransactionStatus tx = txManager.getTransaction(new DefaultTransactionDefinition());
try {
Job job = target.get(0L);
- jdbc.update("update DB_SCHEDULE set VERSION=3 where ID=" + job.getId());
+ jdbc.update("update DB_SCHEDULE set VERSION=100 where ID=" + job.getId());
job.getSchedules().iterator().next().setSchedule("blah");
sessionFactory.getCurrentSession().flush();
fail("should have thrown a stale object exception");
Added: trunk/drawbridge/src/test/net/sf/drawbridge/sched/ExecuteQueryJobTest.java
===================================================================
--- trunk/drawbridge/src/test/net/sf/drawbridge/sched/ExecuteQueryJobTest.java (rev 0)
+++ trunk/drawbridge/src/test/net/sf/drawbridge/sched/ExecuteQueryJobTest.java 2008-10-11 01:48:39 UTC (rev 51)
@@ -0,0 +1,104 @@
+package net.sf.drawbridge.sched;
+
+import java.util.Date;
+import java.util.Properties;
+
+import net.sf.drawbridge.dao.JobDao;
+import net.sf.drawbridge.exec.JobExecuter;
+import net.sf.drawbridge.exec.handler.ResultHandler;
+import net.sf.drawbridge.util.StringPropertiesConverter;
+import net.sf.drawbridge.vo.Database;
+import net.sf.drawbridge.vo.Driver;
+import net.sf.drawbridge.vo.Job;
+import net.sf.drawbridge.vo.RunAsAccount;
+
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+import org.quartz.CronTrigger;
+import org.quartz.JobDetail;
+import org.quartz.JobExecutionContext;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.spi.TriggerFiredBundle;
+import org.springframework.beans.factory.BeanFactory;
+
+public class ExecuteQueryJobTest extends MockObjectTestCase {
+
+ private Mock mockJobDao = mock(JobDao.class);
+
+ private Mock mockJobExecuter = mock(JobExecuter.class);
+
+ private Mock mockPropConverter = mock(StringPropertiesConverter.class);
+
+ private Mock mockHandler = mock(ResultHandler.class);
+
+ private Mock mockBeanFactory = mock(BeanFactory.class);
+
+ private Mock mockScheduler = mock(Scheduler.class);
+
+ protected void setUp() {
+ ExecuteQueryJob.factory = (BeanFactory) mockBeanFactory.proxy();
+ }
+
+ private ExecuteQueryJob target = new ExecuteQueryJob((JobDao) mockJobDao.proxy(),
+ (JobExecuter) mockJobExecuter.proxy(),
+ (StringPropertiesConverter) mockPropConverter.proxy());
+
+ public void testShouldRemoveJobFromSchedulerIfNoLongerExistsInDatabase() throws Exception {
+ mockScheduler.expects(once()).method("deleteJob").with(eq("1"), eq("2")).will(returnValue(true));
+ mockJobDao.expects(once()).method("get").with(eq(new Long(1))).will(returnValue(null));
+ target.execute(getContext());
+ }
+
+ public void testShouldRemoveJobFromSchedulerIfJobIsInactive() throws Exception {
+ mockScheduler.expects(once()).method("deleteJob").with(eq("1"), eq("2")).will(returnValue(true));
+ Job job = new Job();
+ job.setActive("N");
+ mockJobDao.expects(once()).method("get").with(eq(new Long(1))).will(returnValue(new Job()));
+ target.execute(getContext());
+ }
+
+ private Job getJob() {
+ Job job = new Job();
+ RunAsAccount runAs = new RunAsAccount();
+ Driver driver = new Driver();
+ Database db = new Database();
+ db.setDriver(driver);
+ runAs.setDatabase(db);
+ job.setRunAsAccount(runAs);
+ job.setName("Unit Test Job");
+ job.setId(1L);
+ job.setActive("Y");
+ job.setHandler("SomeHandler");
+ job.setHandlerParams("SomeParams");
+ job.setQuery("select * from dual");
+
+ runAs.setId(2);
+ db.setId(3);
+ return job;
+ }
+
+ public void testShouldExecuteJobAndSendResultsToHandler() throws Exception {
+ Job job = getJob();
+ mockJobExecuter.expects(once()).method("executeJob");
+ mockBeanFactory.expects(once()).method("getBean").with(eq("SomeHandler")).will(returnValue(mockHandler.proxy()));
+ mockPropConverter.expects(once()).method("convertToProperties").will(returnValue(new Properties()));
+ mockHandler.expects(once()).method("handleQuery");
+ mockJobDao.expects(once()).method("get").with(eq(new Long(1))).will(returnValue(job));
+ target.execute(getContext());
+ }
+
+ private JobExecutionContext getContext() {
+ TriggerFiredBundle triggerBundle = new TriggerFiredBundle(new JobDetail("1","2",ExecuteQueryJob.class), new CronTrigger(), null, false, new Date(), new Date(), new Date(), new Date());
+ JobExecutionContext ctx = new JobExecutionContext((Scheduler) mockScheduler.proxy(), triggerBundle, null);
+ return ctx;
+ }
+
+ public void testShouldLogErrorMessageIfUnableToDeleteJobFromScheduler() throws Exception {
+ mockScheduler.expects(once()).method("deleteJob").with(eq("1"), eq("2")).will(throwException(new SchedulerException("The Spanish Inquisition!!")));
+ Job job = new Job();
+ job.setActive("N");
+ mockJobDao.expects(once()).method("get").with(eq(new Long(1))).will(returnValue(new Job()));
+ target.execute(getContext());
+ }
+}
Modified: trunk/drawbridge/src/test/net/sf/drawbridge/sched/QuartzDrawbridgeScheduleLoaderTest.java
===================================================================
--- trunk/drawbridge/src/test/net/sf/drawbridge/sched/QuartzDrawbridgeScheduleLoaderTest.java 2008-10-08 19:05:02 UTC (rev 50)
+++ trunk/drawbridge/src/test/net/sf/drawbridge/sched/QuartzDrawbridgeScheduleLoaderTest.java 2008-10-11 01:48:39 UTC (rev 51)
@@ -1,6 +1,7 @@
/*
* This file is part of DrawBridge.
* Copyright 2008 Adam Cresse
+ * Copyright 2008 Ben La Monica
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -17,25 +18,65 @@
*/
package net.sf.drawbridge.sched;
-import net.sf.drawbridge.sched.QuartzDrawbridgeScheduleLoader;
+import java.util.ArrayList;
+import java.util.List;
+import net.sf.drawbridge.dao.JobDao;
+import net.sf.drawbridge.vo.Job;
+import net.sf.drawbridge.vo.RunAsAccount;
+import net.sf.drawbridge.vo.Schedule;
+
+import org.jmock.Mock;
import org.jmock.MockObjectTestCase;
import org.quartz.Scheduler;
-import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+import org.quartz.SchedulerException;
public class QuartzDrawbridgeScheduleLoaderTest extends MockObjectTestCase {
- public void testShouldRunJobs() throws Exception{
- SchedulerFactoryBean schedFact=new SchedulerFactoryBean();
- schedFact.setAutoStartup(true);
- schedFact.setOverwriteExistingJobs(true);
- schedFact.afterPropertiesSet();
- Scheduler sched=(Scheduler) schedFact.getObject();
- sched.deleteJob("heartbeat","system");//clear incase previously loaded
- assertNotNull(sched);
- new QuartzDrawbridgeScheduleLoader(sched);
- Thread.sleep(2000);
- sched.shutdown();
+ private Mock mockJobDao = mock(JobDao.class);
+
+ private Mock mockScheduler = mock(Scheduler.class);
+
+ private QuartzDrawbridgeScheduleLoader target = new QuartzDrawbridgeScheduleLoader((Scheduler) mockScheduler.proxy(), (JobDao) mockJobDao.proxy());
+
+ private List<Job> getJobs(boolean isActive) {
+ List<Job> jobs = new ArrayList<Job>();
+ Job job = new Job();
+ RunAsAccount runAs = new RunAsAccount();
+ runAs.setId(100);
+ job.setRunAsAccount(runAs);
+ job.setId(1L);
+ job.setName("Test job");
+ job.setActive(isActive?"Y":"N");
+ jobs.add(job);
+ Schedule s = new Schedule(1,1,"0/60 * * * * ?", null, null);
+ job.addSchedule(s);
+ return jobs;
}
+
+ public void testShouldScheduleActiveJobs() throws Exception{
+ List<Job> jobs = getJobs(true);
+ mockJobDao.expects(once()).method("getAll").will(returnValue(jobs));
+ mockScheduler.expects(once()).method("scheduleJob");
+ target.loadSchedule();
+ }
+ public void testShouldNotScheduleInActiveJobs() throws Exception{
+ List<Job> jobs = getJobs(false);
+ mockJobDao.expects(once()).method("getAll").will(returnValue(jobs));
+ mockScheduler.expects(never()).method("scheduleJob");
+ target.loadSchedule();
+ }
+
+ public void testShouldLogErrorIfExceptionThrownWhileSchedulingJob() throws Exception {
+ List<Job> jobs = getJobs(true);
+ mockJobDao.expects(once()).method("getAll").will(returnValue(jobs));
+ mockScheduler.expects(once()).method("scheduleJob").will(throwException(new SchedulerException("The Spanish Inquisition!!")));
+ try {
+ target.loadSchedule();
+ } catch (Exception e) {
+ fail("should not throw an exception.");
+ }
+ }
+
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|