001/** 002 * Copyright 2005-2016 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.ksb.messaging.quartz; 017 018import org.kuali.rice.core.api.config.ConfigurationException; 019import org.kuali.rice.core.api.config.property.ConfigContext; 020import org.kuali.rice.ksb.service.KSBServiceLocator; 021import org.kuali.rice.ksb.util.KSBConstants; 022import org.quartz.Scheduler; 023import org.quartz.SchedulerException; 024import org.quartz.SchedulerFactory; 025import org.springframework.scheduling.quartz.SchedulerFactoryBean; 026import org.springframework.transaction.PlatformTransactionManager; 027 028import javax.sql.DataSource; 029import javax.transaction.TransactionManager; 030 031/** 032 * An implementation of the Quartz SchedulerFactoryBean which uses a database-backed quartz if the useQuartzDatabase property 033 * is set. 034 * 035 * @author Kuali Rice Team (rice.collab@kuali.org) 036 */ 037public class KSBSchedulerFactoryBean extends SchedulerFactoryBean { 038 039 private PlatformTransactionManager jtaTransactionManager; 040 private TransactionManager transactionManager; 041 private DataSource dataSource; 042 private DataSource nonTransactionalDataSource; 043 private boolean transactionManagerSet = false; 044 private boolean nonTransactionalDataSourceSet = false; 045 private boolean nonTransactionalDataSourceNull = true; 046 private boolean dataSourceSet = false; 047 private boolean schedulerInjected = false; 048 049 @Override 050 protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String schedulerName) throws SchedulerException { 051 if (ConfigContext.getCurrentContextConfig().getObject(KSBConstants.Config.INJECTED_EXCEPTION_MESSAGE_SCHEDULER_KEY) != null) { 052 try { 053 schedulerInjected = true; 054 Scheduler scheduler = (Scheduler) ConfigContext.getCurrentContextConfig().getObject(KSBConstants.Config.INJECTED_EXCEPTION_MESSAGE_SCHEDULER_KEY); 055 scheduler.addJobListener(new MessageServiceExecutorJobListener()); 056 return scheduler; 057 } catch (Exception e) { 058 throw new ConfigurationException(e); 059 } 060 } 061 return super.createScheduler(schedulerFactory, schedulerName); 062 } 063 064 @Override 065 public void afterPropertiesSet() throws Exception { 066 067 boolean useQuartzDatabase = new Boolean(ConfigContext.getCurrentContextConfig().getProperty(KSBConstants.Config.USE_QUARTZ_DATABASE)); 068 if (useQuartzDatabase && !schedulerInjected) { 069 // require a transaction manager 070 if (jtaTransactionManager == null) { 071 throw new ConfigurationException("No jta transaction manager was configured for the KSB Quartz Scheduler"); 072 } 073 setTransactionManager(jtaTransactionManager); 074 if (!nonTransactionalDataSourceSet) { 075 // since transaction manager is required... require a non transactional datasource 076 nonTransactionalDataSource = KSBServiceLocator.getMessageNonTransactionalDataSource(); 077 if (nonTransactionalDataSource == null) { 078 throw new ConfigurationException("No non-transactional data source was found but is required for the KSB Quartz Scheduler"); 079 } 080 super.setNonTransactionalDataSource(nonTransactionalDataSource); 081 } 082 if (!dataSourceSet) { 083 dataSource = KSBServiceLocator.getMessageDataSource(); 084 } 085 super.setDataSource(dataSource); 086 if (transactionManagerSet && nonTransactionalDataSourceNull) { 087 throw new ConfigurationException("A valid transaction manager was set but no non-transactional data source was found"); 088 } 089 } 090 super.afterPropertiesSet(); 091 } 092 093 /** 094 * This overridden method is used simply to keep track of whether the transactionManager property has been set 095 * 096 * @see org.springframework.scheduling.quartz.SchedulerFactoryBean#setTransactionManager(org.springframework.transaction.PlatformTransactionManager) 097 */ 098 @Override 099 public void setTransactionManager(PlatformTransactionManager jtaTransactionManager) { 100 transactionManagerSet = jtaTransactionManager != null; 101 this.jtaTransactionManager = jtaTransactionManager; 102 } 103 104 /** 105 * This overridden method is used to keep track of whether the non transactional data source is null 106 * 107 * @see org.springframework.scheduling.quartz.SchedulerFactoryBean#setNonTransactionalDataSource(javax.sql.DataSource) 108 */ 109 @Override 110 public void setNonTransactionalDataSource(DataSource nonTransactionalDataSource) { 111 nonTransactionalDataSourceSet = true; 112 nonTransactionalDataSourceNull = (nonTransactionalDataSource == null); 113 this.nonTransactionalDataSource = nonTransactionalDataSource; 114 } 115 116 @Override 117 public void setDataSource(DataSource dataSource) { 118 dataSourceSet = true; 119 this.dataSource = dataSource; 120 } 121}