001/** 002 * Copyright 2005-2017 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.getListenerManager().addJobListener( new MessageServiceExecutorJobListener()); 056 057 return scheduler; 058 } catch (Exception e) { 059 throw new ConfigurationException(e); 060 } 061 } 062 return super.createScheduler(schedulerFactory, schedulerName); 063 } 064 065 @Override 066 public void afterPropertiesSet() throws Exception { 067 068 boolean useQuartzDatabase = new Boolean(ConfigContext.getCurrentContextConfig().getProperty(KSBConstants.Config.USE_QUARTZ_DATABASE)); 069 if (useQuartzDatabase && !schedulerInjected) { 070 // require a transaction manager 071 if (jtaTransactionManager == null) { 072 throw new ConfigurationException("No jta transaction manager was configured for the KSB Quartz Scheduler"); 073 } 074 setTransactionManager(jtaTransactionManager); 075 if (!nonTransactionalDataSourceSet) { 076 // since transaction manager is required... require a non transactional datasource 077 nonTransactionalDataSource = KSBServiceLocator.getMessageNonTransactionalDataSource(); 078 if (nonTransactionalDataSource == null) { 079 throw new ConfigurationException("No non-transactional data source was found but is required for the KSB Quartz Scheduler"); 080 } 081 super.setNonTransactionalDataSource(nonTransactionalDataSource); 082 } 083 if (!dataSourceSet) { 084 dataSource = KSBServiceLocator.getMessageDataSource(); 085 } 086 super.setDataSource(dataSource); 087 if (transactionManagerSet && nonTransactionalDataSourceNull) { 088 throw new ConfigurationException("A valid transaction manager was set but no non-transactional data source was found"); 089 } 090 } 091 super.afterPropertiesSet(); 092 } 093 094 /** 095 * This overridden method is used simply to keep track of whether the transactionManager property has been set 096 * 097 * @see org.springframework.scheduling.quartz.SchedulerFactoryBean#setTransactionManager(org.springframework.transaction.PlatformTransactionManager) 098 */ 099 @Override 100 public void setTransactionManager(PlatformTransactionManager jtaTransactionManager) { 101 transactionManagerSet = jtaTransactionManager != null; 102 this.jtaTransactionManager = jtaTransactionManager; 103 } 104 105 /** 106 * This overridden method is used to keep track of whether the non transactional data source is null 107 * 108 * @see org.springframework.scheduling.quartz.SchedulerFactoryBean#setNonTransactionalDataSource(javax.sql.DataSource) 109 */ 110 @Override 111 public void setNonTransactionalDataSource(DataSource nonTransactionalDataSource) { 112 nonTransactionalDataSourceSet = true; 113 nonTransactionalDataSourceNull = (nonTransactionalDataSource == null); 114 this.nonTransactionalDataSource = nonTransactionalDataSource; 115 } 116 117 @Override 118 public void setDataSource(DataSource dataSource) { 119 dataSourceSet = true; 120 this.dataSource = dataSource; 121 } 122}