public void TestGetPropertyGroupStringBooleanStringArray() { // Test that an empty property does not cause an exception NameValueCollection props = new NameValueCollection(); props.Add("x.y.z", ""); PropertiesParser propertiesParser = new PropertiesParser(props); NameValueCollection propGroup = propertiesParser.GetPropertyGroup("x.y", true); Assert.AreEqual("", propGroup.Get("z")); }
/// <summary> </summary> private IScheduler Instantiate() { if (cfg == null) { Initialize(); } if (initException != null) { throw initException; } ISchedulerExporter exporter = null; IJobStore js; IThreadPool tp; QuartzScheduler qs = null; DBConnectionManager dbMgr = null; Type instanceIdGeneratorType = null; NameValueCollection tProps; bool autoId = false; TimeSpan idleWaitTime = TimeSpan.Zero; TimeSpan dbFailureRetry = TimeSpan.FromSeconds(15); IThreadExecutor threadExecutor; SchedulerRepository schedRep = SchedulerRepository.Instance; // Get Scheduler Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string schedName = cfg.GetStringProperty(PropertySchedulerInstanceName, "QuartzScheduler"); string threadName = cfg.GetStringProperty(PropertySchedulerThreadName, "{0}_QuartzSchedulerThread".FormatInvariant(schedName)); string schedInstId = cfg.GetStringProperty(PropertySchedulerInstanceId, DefaultInstanceId); if (schedInstId.Equals(AutoGenerateInstanceId)) { autoId = true; instanceIdGeneratorType = LoadType(cfg.GetStringProperty(PropertySchedulerInstanceIdGeneratorType)) ?? typeof(SimpleInstanceIdGenerator); } else if (schedInstId.Equals(SystemPropertyAsInstanceId)) { autoId = true; instanceIdGeneratorType = typeof(SystemPropertyInstanceIdGenerator); } Type typeLoadHelperType = LoadType(cfg.GetStringProperty(PropertySchedulerTypeLoadHelperType)); Type jobFactoryType = LoadType(cfg.GetStringProperty(PropertySchedulerJobFactoryType, null)); idleWaitTime = cfg.GetTimeSpanProperty(PropertySchedulerIdleWaitTime, idleWaitTime); if (idleWaitTime > TimeSpan.Zero && idleWaitTime < TimeSpan.FromMilliseconds(1000)) { throw new SchedulerException("quartz.scheduler.idleWaitTime of less than 1000ms is not legal."); } dbFailureRetry = cfg.GetTimeSpanProperty(PropertySchedulerDbFailureRetryInterval, dbFailureRetry); if (dbFailureRetry < TimeSpan.Zero) { throw new SchedulerException(PropertySchedulerDbFailureRetryInterval + " of less than 0 ms is not legal."); } bool makeSchedulerThreadDaemon = cfg.GetBooleanProperty(PropertySchedulerMakeSchedulerThreadDaemon); long batchTimeWindow = cfg.GetLongProperty(PropertySchedulerBatchTimeWindow, 0L); int maxBatchSize = cfg.GetIntProperty(PropertySchedulerMaxBatchSize, 1); bool interruptJobsOnShutdown = cfg.GetBooleanProperty(PropertySchedulerInterruptJobsOnShutdown, false); bool interruptJobsOnShutdownWithWait = cfg.GetBooleanProperty(PropertySchedulerInterruptJobsOnShutdownWithWait, false); NameValueCollection schedCtxtProps = cfg.GetPropertyGroup(PropertySchedulerContextPrefix, true); bool proxyScheduler = cfg.GetBooleanProperty(PropertySchedulerProxy, false); // Create type load helper ITypeLoadHelper loadHelper; try { loadHelper = ObjectUtils.InstantiateType<ITypeLoadHelper>(typeLoadHelperType ?? typeof(SimpleTypeLoadHelper)); } catch (Exception e) { throw new SchedulerConfigException("Unable to instantiate type load helper: {0}".FormatInvariant(e.Message), e); } loadHelper.Initialize(); // If Proxying to remote scheduler, short-circuit here... // ~~~~~~~~~~~~~~~~~~ if (proxyScheduler) { if (autoId) { schedInstId = DefaultInstanceId; } Type proxyType = loadHelper.LoadType(cfg.GetStringProperty(PropertySchedulerProxyType)) ?? typeof(RemotingSchedulerProxyFactory); IRemotableSchedulerProxyFactory factory; try { factory = ObjectUtils.InstantiateType<IRemotableSchedulerProxyFactory>(proxyType); ObjectUtils.SetObjectProperties(factory, cfg.GetPropertyGroup(PropertySchedulerProxy, true)); } catch (Exception e) { initException = new SchedulerException("Remotable proxy factory '{0}' could not be instantiated.".FormatInvariant(proxyType), e); throw initException; } string uid = QuartzSchedulerResources.GetUniqueIdentifier(schedName, schedInstId); RemoteScheduler remoteScheduler = new RemoteScheduler(uid, factory); schedRep.Bind(remoteScheduler); return remoteScheduler; } IJobFactory jobFactory = null; if (jobFactoryType != null) { try { jobFactory = ObjectUtils.InstantiateType<IJobFactory>(jobFactoryType); } catch (Exception e) { throw new SchedulerConfigException("Unable to Instantiate JobFactory: {0}".FormatInvariant(e.Message), e); } tProps = cfg.GetPropertyGroup(PropertySchedulerJobFactoryPrefix, true); try { ObjectUtils.SetObjectProperties(jobFactory, tProps); } catch (Exception e) { initException = new SchedulerException("JobFactory of type '{0}' props could not be configured.".FormatInvariant(jobFactoryType), e); throw initException; } } IInstanceIdGenerator instanceIdGenerator = null; if (instanceIdGeneratorType != null) { try { instanceIdGenerator = ObjectUtils.InstantiateType<IInstanceIdGenerator>(instanceIdGeneratorType); } catch (Exception e) { throw new SchedulerConfigException("Unable to Instantiate InstanceIdGenerator: {0}".FormatInvariant(e.Message), e); } tProps = cfg.GetPropertyGroup(PropertySchedulerInstanceIdGeneratorPrefix, true); try { ObjectUtils.SetObjectProperties(instanceIdGenerator, tProps); } catch (Exception e) { initException = new SchedulerException("InstanceIdGenerator of type '{0}' props could not be configured.".FormatInvariant(instanceIdGeneratorType), e); throw initException; } } // Get ThreadPool Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Type tpType = loadHelper.LoadType(cfg.GetStringProperty(PropertyThreadPoolType)) ?? typeof(SimpleThreadPool); try { tp = ObjectUtils.InstantiateType<IThreadPool>(tpType); } catch (Exception e) { initException = new SchedulerException("ThreadPool type '{0}' could not be instantiated.".FormatInvariant(tpType), e); throw initException; } tProps = cfg.GetPropertyGroup(PropertyThreadPoolPrefix, true); try { ObjectUtils.SetObjectProperties(tp, tProps); } catch (Exception e) { initException = new SchedulerException("ThreadPool type '{0}' props could not be configured.".FormatInvariant(tpType), e); throw initException; } // Set up any DataSources // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] dsNames = cfg.GetPropertyGroups(PropertyDataSourcePrefix); for (int i = 0; i < dsNames.Length; i++) { string datasourceKey = "{0}.{1}".FormatInvariant( PropertyDataSourcePrefix, dsNames[i]); NameValueCollection propertyGroup = cfg.GetPropertyGroup(datasourceKey, true); PropertiesParser pp = new PropertiesParser(propertyGroup); Type cpType = loadHelper.LoadType(pp.GetStringProperty(PropertyDbProviderType, null)); // custom connectionProvider... if (cpType != null) { IDbProvider cp; try { cp = ObjectUtils.InstantiateType<IDbProvider>(cpType); } catch (Exception e) { initException = new SchedulerException("ConnectionProvider of type '{0}' could not be instantiated.".FormatInvariant(cpType), e); throw initException; } try { // remove the type name, so it isn't attempted to be set pp.UnderlyingProperties.Remove(PropertyDbProviderType); ObjectUtils.SetObjectProperties(cp, pp.UnderlyingProperties); cp.Initialize(); } catch (Exception e) { initException = new SchedulerException("ConnectionProvider type '{0}' props could not be configured.".FormatInvariant(cpType), e); throw initException; } dbMgr = DBConnectionManager.Instance; dbMgr.AddConnectionProvider(dsNames[i], cp); } else { string dsProvider = pp.GetStringProperty(PropertyDataSourceProvider, null); string dsConnectionString = pp.GetStringProperty(PropertyDataSourceConnectionString, null); string dsConnectionStringName = pp.GetStringProperty(PropertyDataSourceConnectionStringName, null); if (dsConnectionString == null && !String.IsNullOrEmpty(dsConnectionStringName)) { ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings[dsConnectionStringName]; if (connectionStringSettings == null) { initException = new SchedulerException("Named connection string '{0}' not found for DataSource: {1}".FormatInvariant(dsConnectionStringName, dsNames[i])); throw initException; } dsConnectionString = connectionStringSettings.ConnectionString; } if (dsProvider == null) { initException = new SchedulerException("Provider not specified for DataSource: {0}".FormatInvariant(dsNames[i])); throw initException; } if (dsConnectionString == null) { initException = new SchedulerException("Connection string not specified for DataSource: {0}".FormatInvariant(dsNames[i])); throw initException; } try { DbProvider dbp = new DbProvider(dsProvider, dsConnectionString); dbp.Initialize(); dbMgr = DBConnectionManager.Instance; dbMgr.AddConnectionProvider(dsNames[i], dbp); } catch (Exception exception) { initException = new SchedulerException("Could not Initialize DataSource: {0}".FormatInvariant(dsNames[i]), exception); throw initException; } } } // Get object serializer properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IObjectSerializer objectSerializer; string objectSerializerType = cfg.GetStringProperty("quartz.serializer.type"); if (objectSerializerType != null) { tProps = cfg.GetPropertyGroup(PropertyObjectSerializer, true); try { objectSerializer = ObjectUtils.InstantiateType<IObjectSerializer>(loadHelper.LoadType(objectSerializerType)); log.Info("Using custom implementation for object serializer: " + objectSerializerType); ObjectUtils.SetObjectProperties(objectSerializer, tProps); } catch (Exception e) { initException = new SchedulerException("Object serializer type '" + objectSerializerType + "' could not be instantiated.", e); throw initException; } } else { log.Info("Using default implementation for object serializer"); objectSerializer = new DefaultObjectSerializer(); } // Get JobStore Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Type jsType = loadHelper.LoadType(cfg.GetStringProperty(PropertyJobStoreType)); try { js = ObjectUtils.InstantiateType<IJobStore>(jsType ?? typeof(RAMJobStore)); } catch (Exception e) { initException = new SchedulerException("JobStore of type '{0}' could not be instantiated.".FormatInvariant(jsType), e); throw initException; } SchedulerDetailsSetter.SetDetails(js, schedName, schedInstId); tProps = cfg.GetPropertyGroup(PropertyJobStorePrefix, true, new string[] {PropertyJobStoreLockHandlerPrefix}); try { ObjectUtils.SetObjectProperties(js, tProps); } catch (Exception e) { initException = new SchedulerException("JobStore type '{0}' props could not be configured.".FormatInvariant(jsType), e); throw initException; } if (js is JobStoreSupport) { // Install custom lock handler (Semaphore) Type lockHandlerType = loadHelper.LoadType(cfg.GetStringProperty(PropertyJobStoreLockHandlerType)); if (lockHandlerType != null) { try { ISemaphore lockHandler; ConstructorInfo cWithDbProvider = lockHandlerType.GetConstructor(new Type[] {typeof (DbProvider)}); if (cWithDbProvider != null) { // takes db provider IDbProvider dbProvider = DBConnectionManager.Instance.GetDbProvider(((JobStoreSupport) js).DataSource); lockHandler = (ISemaphore) cWithDbProvider.Invoke(new object[] { dbProvider }); } else { lockHandler = ObjectUtils.InstantiateType<ISemaphore>(lockHandlerType); } tProps = cfg.GetPropertyGroup(PropertyJobStoreLockHandlerPrefix, true); // If this lock handler requires the table prefix, add it to its properties. if (lockHandler is ITablePrefixAware) { tProps[PropertyTablePrefix] = ((JobStoreSupport) js).TablePrefix; tProps[PropertySchedulerName] = schedName; } try { ObjectUtils.SetObjectProperties(lockHandler, tProps); } catch (Exception e) { initException = new SchedulerException("JobStore LockHandler type '{0}' props could not be configured.".FormatInvariant(lockHandlerType), e); throw initException; } ((JobStoreSupport) js).LockHandler = lockHandler; Log.Info("Using custom data access locking (synchronization): " + lockHandlerType); } catch (Exception e) { initException = new SchedulerException("JobStore LockHandler type '{0}' could not be instantiated.".FormatInvariant(lockHandlerType), e); throw initException; } } } // Set up any SchedulerPlugins // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] pluginNames = cfg.GetPropertyGroups(PropertyPluginPrefix); ISchedulerPlugin[] plugins = new ISchedulerPlugin[pluginNames.Length]; for (int i = 0; i < pluginNames.Length; i++) { NameValueCollection pp = cfg.GetPropertyGroup("{0}.{1}".FormatInvariant(PropertyPluginPrefix, pluginNames[i]), true); string plugInType = pp[PropertyPluginType] ?? null; if (plugInType == null) { initException = new SchedulerException("SchedulerPlugin type not specified for plugin '{0}'".FormatInvariant(pluginNames[i])); throw initException; } ISchedulerPlugin plugin; try { plugin = ObjectUtils.InstantiateType<ISchedulerPlugin>(LoadType(plugInType)); } catch (Exception e) { initException = new SchedulerException("SchedulerPlugin of type '{0}' could not be instantiated.".FormatInvariant(plugInType), e); throw initException; } try { ObjectUtils.SetObjectProperties(plugin, pp); } catch (Exception e) { initException = new SchedulerException("JobStore SchedulerPlugin '{0}' props could not be configured.".FormatInvariant(plugInType), e); throw initException; } plugins[i] = plugin; } // Set up any JobListeners // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] jobListenerNames = cfg.GetPropertyGroups(PropertyJobListenerPrefix); IJobListener[] jobListeners = new IJobListener[jobListenerNames.Length]; for (int i = 0; i < jobListenerNames.Length; i++) { NameValueCollection lp = cfg.GetPropertyGroup("{0}.{1}".FormatInvariant(PropertyJobListenerPrefix, jobListenerNames[i]), true); string listenerType = lp[PropertyListenerType]; if (listenerType == null) { initException = new SchedulerException("JobListener type not specified for listener '{0}'".FormatInvariant(jobListenerNames[i])); throw initException; } IJobListener listener; try { listener = ObjectUtils.InstantiateType<IJobListener>(loadHelper.LoadType(listenerType)); } catch (Exception e) { initException = new SchedulerException("JobListener of type '{0}' could not be instantiated.".FormatInvariant(listenerType), e); throw initException; } try { PropertyInfo nameProperty = listener.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance); if (nameProperty != null && nameProperty.CanWrite) { nameProperty.GetSetMethod().Invoke(listener, new object[] {jobListenerNames[i]}); } ObjectUtils.SetObjectProperties(listener, lp); } catch (Exception e) { initException = new SchedulerException("JobListener '{0}' props could not be configured.".FormatInvariant(listenerType), e); throw initException; } jobListeners[i] = listener; } // Set up any TriggerListeners // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] triggerListenerNames = cfg.GetPropertyGroups(PropertyTriggerListenerPrefix); ITriggerListener[] triggerListeners = new ITriggerListener[triggerListenerNames.Length]; for (int i = 0; i < triggerListenerNames.Length; i++) { NameValueCollection lp = cfg.GetPropertyGroup("{0}.{1}".FormatInvariant(PropertyTriggerListenerPrefix, triggerListenerNames[i]), true); string listenerType = lp[PropertyListenerType]; if (listenerType == null) { initException = new SchedulerException("TriggerListener type not specified for listener '{0}'".FormatInvariant(triggerListenerNames[i])); throw initException; } ITriggerListener listener; try { listener = ObjectUtils.InstantiateType<ITriggerListener>(loadHelper.LoadType(listenerType)); } catch (Exception e) { initException = new SchedulerException("TriggerListener of type '{0}' could not be instantiated.".FormatInvariant(listenerType), e); throw initException; } try { PropertyInfo nameProperty = listener.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance); if (nameProperty != null && nameProperty.CanWrite) { nameProperty.GetSetMethod().Invoke(listener, new object[] {triggerListenerNames[i]}); } ObjectUtils.SetObjectProperties(listener, lp); } catch (Exception e) { initException = new SchedulerException("TriggerListener '{0}' props could not be configured.".FormatInvariant(listenerType), e); throw initException; } triggerListeners[i] = listener; } // Get exporter // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string exporterType = cfg.GetStringProperty(PropertySchedulerExporterType, null); if (exporterType != null) { try { exporter = ObjectUtils.InstantiateType<ISchedulerExporter>(loadHelper.LoadType(exporterType)); } catch (Exception e) { initException = new SchedulerException("Scheduler exporter of type '{0}' could not be instantiated.".FormatInvariant(exporterType), e); throw initException; } tProps = cfg.GetPropertyGroup(PropertySchedulerExporterPrefix, true); try { ObjectUtils.SetObjectProperties(exporter, tProps); } catch (Exception e) { initException = new SchedulerException("Scheduler exporter type '{0}' props could not be configured.".FormatInvariant(exporterType), e); throw initException; } } bool tpInited = false; bool qsInited = false; // Get ThreadExecutor Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string threadExecutorClass = cfg.GetStringProperty(PropertyThreadExecutorType); if (threadExecutorClass != null) { tProps = cfg.GetPropertyGroup(PropertyThreadExecutor, true); try { threadExecutor = ObjectUtils.InstantiateType<IThreadExecutor>(loadHelper.LoadType(threadExecutorClass)); log.Info("Using custom implementation for ThreadExecutor: " + threadExecutorClass); ObjectUtils.SetObjectProperties(threadExecutor, tProps); } catch (Exception e) { initException = new SchedulerException( "ThreadExecutor class '" + threadExecutorClass + "' could not be instantiated.", e); throw initException; } } else { log.Info("Using default implementation for ThreadExecutor"); threadExecutor = new DefaultThreadExecutor(); } // Fire everything up // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ try { IJobRunShellFactory jrsf = new StdJobRunShellFactory(); if (autoId) { try { schedInstId = DefaultInstanceId; if (js.Clustered) { schedInstId = instanceIdGenerator.GenerateInstanceId(); } } catch (Exception e) { Log.Error("Couldn't generate instance Id!", e); throw new SystemException("Cannot run without an instance id."); } } if (js is JobStoreSupport) { JobStoreSupport jjs = (JobStoreSupport) js; jjs.DbRetryInterval = dbFailureRetry; jjs.ThreadExecutor = threadExecutor; // object serializer jjs.ObjectSerializer = objectSerializer; } QuartzSchedulerResources rsrcs = new QuartzSchedulerResources(); rsrcs.Name = schedName; rsrcs.ThreadName = threadName; rsrcs.InstanceId = schedInstId; rsrcs.JobRunShellFactory = jrsf; rsrcs.MakeSchedulerThreadDaemon = makeSchedulerThreadDaemon; rsrcs.BatchTimeWindow = TimeSpan.FromMilliseconds(batchTimeWindow); rsrcs.MaxBatchSize = maxBatchSize; rsrcs.InterruptJobsOnShutdown = interruptJobsOnShutdown; rsrcs.InterruptJobsOnShutdownWithWait = interruptJobsOnShutdownWithWait; rsrcs.SchedulerExporter = exporter; SchedulerDetailsSetter.SetDetails(tp, schedName, schedInstId); rsrcs.ThreadExecutor = threadExecutor; threadExecutor.Initialize(); rsrcs.ThreadPool = tp; if (tp is SimpleThreadPool) { ((SimpleThreadPool) tp).ThreadNamePrefix = schedName + "_Worker"; } tp.Initialize(); tpInited = true; rsrcs.JobStore = js; // add plugins for (int i = 0; i < plugins.Length; i++) { rsrcs.AddSchedulerPlugin(plugins[i]); } qs = new QuartzScheduler(rsrcs, idleWaitTime, dbFailureRetry); qsInited = true; // Create Scheduler ref... IScheduler sched = Instantiate(rsrcs, qs); // set job factory if specified if (jobFactory != null) { qs.JobFactory = jobFactory; } // Initialize plugins now that we have a Scheduler instance. for (int i = 0; i < plugins.Length; i++) { plugins[i].Initialize(pluginNames[i], sched); } // add listeners for (int i = 0; i < jobListeners.Length; i++) { qs.ListenerManager.AddJobListener(jobListeners[i], EverythingMatcher<JobKey>.AllJobs()); } for (int i = 0; i < triggerListeners.Length; i++) { qs.ListenerManager.AddTriggerListener(triggerListeners[i], EverythingMatcher<TriggerKey>.AllTriggers()); } // set scheduler context data... foreach (string key in schedCtxtProps) { string val = schedCtxtProps.Get(key); sched.Context.Put(key, val); } // fire up job store, and runshell factory js.InstanceId = schedInstId; js.InstanceName = schedName; js.ThreadPoolSize = tp.PoolSize; js.Initialize(loadHelper, qs.SchedulerSignaler); jrsf.Initialize(sched); qs.Initialize(); Log.Info("Quartz scheduler '{0}' initialized".FormatInvariant(sched.SchedulerName)); Log.Info("Quartz scheduler version: {0}".FormatInvariant(qs.Version)); // prevents the repository from being garbage collected qs.AddNoGCObject(schedRep); // prevents the db manager from being garbage collected if (dbMgr != null) { qs.AddNoGCObject(dbMgr); } schedRep.Bind(sched); return sched; } catch (SchedulerException) { if (qsInited) { qs.Shutdown(false); } else if (tpInited) { tp.Shutdown(false); } throw; } catch { if (qsInited) { qs.Shutdown(false); } else if (tpInited) { tp.Shutdown(false); } throw; } }
/// <summary> /// Initialize the <see cref="ISchedulerFactory" /> with /// the contents of the given key value collection object. /// </summary> public virtual void Initialize(NameValueCollection props) { cfg = new PropertiesParser(props); ValidateConfiguration(); }
/// <summary> </summary> private IScheduler Instantiate() { if (cfg == null) { Initialize(); } if (initException != null) { throw initException; } ISchedulerExporter exporter = null; IJobStore js; IThreadPool tp; QuartzScheduler qs; SchedulingContext schedCtxt; DBConnectionManager dbMgr = null; string instanceIdGeneratorType = null; NameValueCollection tProps; bool autoId = false; TimeSpan idleWaitTime = TimeSpan.Zero; TimeSpan dbFailureRetry = TimeSpan.Zero; string typeLoadHelperType; string jobFactoryType; SchedulerRepository schedRep = SchedulerRepository.Instance; // Get Scheduler Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string schedName = cfg.GetStringProperty(PropertySchedulerInstanceName, "QuartzScheduler"); string threadName = cfg.GetStringProperty(PropertySchedulerThreadName, string.Format(CultureInfo.InvariantCulture, "{0}_QuartzSchedulerThread", schedName)); string schedInstId = cfg.GetStringProperty(PropertySchedulerInstanceId, DefaultInstanceId); if (schedInstId.Equals(AutoGenerateInstanceId)) { autoId = true; instanceIdGeneratorType = cfg.GetStringProperty(PropertySchedulerInstanceIdGeneratorType, "Quartz.Simpl.SimpleInstanceIdGenerator, Quartz"); } typeLoadHelperType = cfg.GetStringProperty(PropertySchedulerTypeLoadHelperType, "Quartz.Simpl.CascadingClassLoadHelper, Quartz"); jobFactoryType = cfg.GetStringProperty(PropertySchedulerJobFactoryType, null); idleWaitTime = cfg.GetTimeSpanProperty(PropertySchedulerIdleWaitTime, idleWaitTime); dbFailureRetry = cfg.GetTimeSpanProperty(PropertySchedulerDbFailureRetryInterval, dbFailureRetry); bool makeSchedulerThreadDaemon = cfg.GetBooleanProperty(PropertySchedulerMakeSchedulerThreadDaemon); NameValueCollection schedCtxtProps = cfg.GetPropertyGroup(PropertySchedulerContextPrefix, true); bool proxyScheduler = cfg.GetBooleanProperty(PropertySchedulerProxy, false); // If Proxying to remote scheduler, short-circuit here... // ~~~~~~~~~~~~~~~~~~ if (proxyScheduler) { if (autoId) { schedInstId = DefaultInstanceId; } schedCtxt = new SchedulingContext(); schedCtxt.InstanceId = schedInstId; string uid = QuartzSchedulerResources.GetUniqueIdentifier(schedName, schedInstId); RemoteScheduler remoteScheduler = new RemoteScheduler(schedCtxt, uid); string remoteSchedulerAddress = cfg.GetStringProperty(PropertySchedulerProxyAddress); remoteScheduler.RemoteSchedulerAddress = remoteSchedulerAddress; schedRep.Bind(remoteScheduler); return remoteScheduler; } // Create type load helper ITypeLoadHelper loadHelper; try { loadHelper = (ITypeLoadHelper)ObjectUtils.InstantiateType(LoadType(typeLoadHelperType)); } catch (Exception e) { throw new SchedulerConfigException( string.Format(CultureInfo.InvariantCulture, "Unable to instantiate type load helper: {0}", e.Message), e); } loadHelper.Initialize(); IJobFactory jobFactory = null; if (jobFactoryType != null) { try { jobFactory = (IJobFactory) ObjectUtils.InstantiateType(loadHelper.LoadType(jobFactoryType)); } catch (Exception e) { throw new SchedulerConfigException( string.Format(CultureInfo.InvariantCulture, "Unable to Instantiate JobFactory: {0}", e.Message), e); } tProps = cfg.GetPropertyGroup(PropertySchedulerJobFactoryPrefix, true); try { ObjectUtils.SetObjectProperties(jobFactory, tProps); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "JobFactory of type '{0}' props could not be configured.", jobFactoryType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } } IInstanceIdGenerator instanceIdGenerator = null; if (instanceIdGeneratorType != null) { try { instanceIdGenerator = (IInstanceIdGenerator) ObjectUtils.InstantiateType(loadHelper.LoadType(instanceIdGeneratorType)); } catch (Exception e) { throw new SchedulerConfigException( string.Format(CultureInfo.InvariantCulture, "Unable to Instantiate InstanceIdGenerator: {0}", e.Message), e); } tProps = cfg.GetPropertyGroup(PropertySchedulerInstanceIdGeneratorPrefix, true); try { ObjectUtils.SetObjectProperties(instanceIdGenerator, tProps); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "InstanceIdGenerator of type '{0}' props could not be configured.", instanceIdGeneratorType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } } // Get ThreadPool Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string tpType = cfg.GetStringProperty(PropertyThreadPoolType, typeof(SimpleThreadPool).AssemblyQualifiedName); if (tpType == null) { initException = new SchedulerException("ThreadPool type not specified. ", SchedulerException.ErrorBadConfiguration); throw initException; } try { tp = (IThreadPool) ObjectUtils.InstantiateType(loadHelper.LoadType(tpType)); } catch (Exception e) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "ThreadPool type '{0}' could not be instantiated.", tpType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } tProps = cfg.GetPropertyGroup(PropertyThreadPoolPrefix, true); try { ObjectUtils.SetObjectProperties(tp, tProps); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "ThreadPool type '{0}' props could not be configured.", tpType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } // Set up any DataSources // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] dsNames = cfg.GetPropertyGroups(PropertyDataSourcePrefix); for (int i = 0; i < dsNames.Length; i++) { PropertiesParser pp = new PropertiesParser( cfg.GetPropertyGroup(string.Format(CultureInfo.InvariantCulture, "{0}.{1}", PropertyDataSourcePrefix, dsNames[i]), true)); string cpType = pp.GetStringProperty(PropertyDbProviderType, null); // custom connectionProvider... if (cpType != null) { IDbProvider cp; try { cp = (IDbProvider) ObjectUtils.InstantiateType(loadHelper.LoadType(cpType)); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "ConnectionProvider of type '{0}' could not be instantiated.", cpType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } try { // remove the type name, so it isn't attempted to be set pp.UnderlyingProperties.Remove(PropertyDbProviderType); ObjectUtils.SetObjectProperties(cp, pp.UnderlyingProperties); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "ConnectionProvider type '{0}' props could not be configured.", cpType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } dbMgr = DBConnectionManager.Instance; dbMgr.AddConnectionProvider(dsNames[i], cp); } else { string dsProvider = pp.GetStringProperty(PropertyDataSourceProvider, null); string dsConnectionString = pp.GetStringProperty(PropertyDataSourceConnectionString, null); string dsConnectionStringName = pp.GetStringProperty(PropertyDataSourceConnectionStringName, null); if (dsConnectionString == null && dsConnectionStringName != null && dsConnectionStringName.Length > 0) { #if NET_20 ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings[dsConnectionStringName]; if (connectionStringSettings == null) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "Named connection string '{0}' not found for DataSource: {1}", dsConnectionStringName, dsNames[i])); throw initException; } dsConnectionString = connectionStringSettings.ConnectionString; #endif } if (dsProvider == null) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "Provider not specified for DataSource: {0}", dsNames[i])); throw initException; } if (dsConnectionString == null) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "Connection string not specified for DataSource: {0}", dsNames[i])); throw initException; } try { DbProvider dbp = new DbProvider(dsProvider, dsConnectionString); dbMgr = DBConnectionManager.Instance; dbMgr.AddConnectionProvider(dsNames[i], dbp); } catch (Exception exception) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "Could not Initialize DataSource: {0}", dsNames[i]), exception); throw initException; } } } // Get JobStore Properties // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string jsType = cfg.GetStringProperty(PropertyJobStoreType, typeof (RAMJobStore).FullName); if (jsType == null) { initException = new SchedulerException("JobStore type not specified. ", SchedulerException.ErrorBadConfiguration); throw initException; } try { js = (IJobStore) ObjectUtils.InstantiateType(loadHelper.LoadType(jsType)); } catch (Exception e) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "JobStore of type '{0}' could not be instantiated.", jsType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } tProps = cfg.GetPropertyGroup(PropertyJobStorePrefix, true, new string[] {PropertyJobStoreLockHandlerPrefix}); try { ObjectUtils.SetObjectProperties(js, tProps); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "JobStore type '{0}' props could not be configured.", jsType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } if (js is JobStoreSupport) { ((JobStoreSupport) js).InstanceId = schedInstId; ((JobStoreSupport) js).InstanceName = schedName; // Install custom lock handler (Semaphore) string lockHandlerTypeName = cfg.GetStringProperty(PropertyJobStoreLockHandlerType); if (lockHandlerTypeName != null) { try { Type lockHandlerType = loadHelper.LoadType(lockHandlerTypeName); ISemaphore lockHandler; ConstructorInfo cWithDbProvider = lockHandlerType.GetConstructor(new Type[] {typeof (DbProvider)}); if (cWithDbProvider != null) { // takes db provider IDbProvider dbProvider = DBConnectionManager.Instance.GetDbProvider(((JobStoreSupport) js).DataSource); lockHandler = (ISemaphore) cWithDbProvider.Invoke(new object[] { dbProvider }); } else { lockHandler = (ISemaphore)ObjectUtils.InstantiateType(lockHandlerType); } tProps = cfg.GetPropertyGroup(PropertyJobStoreLockHandlerPrefix, true); // If this lock handler requires the table prefix, add it to its properties. if (lockHandler is ITablePrefixAware) { tProps[PropertyTablePrefix] = ((JobStoreSupport) js).TablePrefix; } try { ObjectUtils.SetObjectProperties(lockHandler, tProps); } catch (Exception e) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "JobStore LockHandler type '{0}' props could not be configured.", lockHandlerTypeName), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } ((JobStoreSupport) js).LockHandler = lockHandler; Log.Info("Using custom data access locking (synchronization): " + lockHandlerType); } catch (Exception e) { initException = new SchedulerException(string.Format(CultureInfo.InvariantCulture, "JobStore LockHandler type '{0}' could not be instantiated.", lockHandlerTypeName), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } } } // Set up any SchedulerPlugins // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] pluginNames = cfg.GetPropertyGroups(PropertyPluginPrefix); ISchedulerPlugin[] plugins = new ISchedulerPlugin[pluginNames.Length]; for (int i = 0; i < pluginNames.Length; i++) { NameValueCollection pp = cfg.GetPropertyGroup(string.Format(CultureInfo.InvariantCulture, "{0}.{1}", PropertyPluginPrefix, pluginNames[i]), true); string plugInType = pp[PropertyPluginType] == null ? null : pp[PropertyPluginType]; if (plugInType == null) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "SchedulerPlugin type not specified for plugin '{0}'", pluginNames[i]), SchedulerException.ErrorBadConfiguration); throw initException; } ISchedulerPlugin plugin; try { plugin = (ISchedulerPlugin) ObjectUtils.InstantiateType(LoadType(plugInType)); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "SchedulerPlugin of type '{0}' could not be instantiated.", plugInType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } try { ObjectUtils.SetObjectProperties(plugin, pp); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "JobStore SchedulerPlugin '{0}' props could not be configured.", plugInType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } plugins[i] = plugin; } // Set up any JobListeners // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Type[] strArg = new Type[] {typeof (string)}; string[] jobListenerNames = cfg.GetPropertyGroups(PropertyJobListenerPrefix); IJobListener[] jobListeners = new IJobListener[jobListenerNames.Length]; for (int i = 0; i < jobListenerNames.Length; i++) { NameValueCollection lp = cfg.GetPropertyGroup(string.Format(CultureInfo.InvariantCulture, "{0}.{1}", PropertyJobListenerPrefix, jobListenerNames[i]), true); string listenerType = lp[PropertyListenerType] == null ? null : lp[PropertyListenerType]; if (listenerType == null) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "JobListener type not specified for listener '{0}'", jobListenerNames[i]), SchedulerException.ErrorBadConfiguration); throw initException; } IJobListener listener; try { listener = (IJobListener) ObjectUtils.InstantiateType(loadHelper.LoadType(listenerType)); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "JobListener of type '{0}' could not be instantiated.", listenerType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } try { MethodInfo nameSetter = listener.GetType().GetMethod("setName", (strArg == null) ? new Type[0] : strArg); if (nameSetter != null) { nameSetter.Invoke(listener, new object[] {jobListenerNames[i]}); } ObjectUtils.SetObjectProperties(listener, lp); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "JobListener '{0}' props could not be configured.", listenerType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } jobListeners[i] = listener; } // Set up any TriggerListeners // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string[] triggerListenerNames = cfg.GetPropertyGroups(PropertyTriggerListenerPrefix); ITriggerListener[] triggerListeners = new ITriggerListener[triggerListenerNames.Length]; for (int i = 0; i < triggerListenerNames.Length; i++) { NameValueCollection lp = cfg.GetPropertyGroup( string.Format(CultureInfo.InvariantCulture, "{0}.{1}", PropertyTriggerListenerPrefix, triggerListenerNames[i]), true); string listenerType = lp[PropertyListenerType] == null ? null : lp[PropertyListenerType]; if (listenerType == null) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "TriggerListener type not specified for listener '{0}'", triggerListenerNames[i]), SchedulerException.ErrorBadConfiguration); throw initException; } ITriggerListener listener; try { listener = (ITriggerListener) ObjectUtils.InstantiateType(loadHelper.LoadType(listenerType)); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "TriggerListener of type '{0}' could not be instantiated.", listenerType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } try { MethodInfo nameSetter = listener.GetType().GetMethod("setName", (strArg == null) ? new Type[0] : strArg); if (nameSetter != null) { nameSetter.Invoke(listener, (new object[] {triggerListenerNames[i]})); } ObjectUtils.SetObjectProperties(listener, lp); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "TriggerListener '{0}' props could not be configured.", listenerType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } triggerListeners[i] = listener; } // Get exporter // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ string exporterType = cfg.GetStringProperty(PropertySchedulerExporterType, null); if (exporterType != null) { try { exporter = (ISchedulerExporter)ObjectUtils.InstantiateType(loadHelper.LoadType(exporterType)); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "Scheduler exporter of type '{0}' could not be instantiated.", exporterType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } tProps = cfg.GetPropertyGroup(PropertySchedulerExporterPrefix, true); try { ObjectUtils.SetObjectProperties(exporter, tProps); } catch (Exception e) { initException = new SchedulerException( string.Format(CultureInfo.InvariantCulture, "Scheduler exporter type '{0}' props could not be configured.", exporterType), e); initException.ErrorCode = SchedulerException.ErrorBadConfiguration; throw initException; } } // Fire everything up // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IJobRunShellFactory jrsf = new StdJobRunShellFactory(); if (autoId) { try { schedInstId = DefaultInstanceId; if (js is JobStoreSupport) { if (((JobStoreSupport) js).Clustered) { schedInstId = instanceIdGenerator.GenerateInstanceId(); } } } catch (Exception e) { Log.Error("Couldn't generate instance Id!", e); throw new SystemException("Cannot run without an instance id."); } } if (js is JobStoreSupport) { JobStoreSupport jjs = (JobStoreSupport) js; jjs.InstanceId = schedInstId; jjs.DbRetryInterval = dbFailureRetry; } QuartzSchedulerResources rsrcs = new QuartzSchedulerResources(); rsrcs.Name = schedName; rsrcs.ThreadName = threadName; rsrcs.InstanceId = schedInstId; rsrcs.JobRunShellFactory = jrsf; rsrcs.MakeSchedulerThreadDaemon = makeSchedulerThreadDaemon; rsrcs.ThreadPool = tp; rsrcs.SchedulerExporter = exporter; if (tp is SimpleThreadPool) { ((SimpleThreadPool) tp).ThreadNamePrefix = schedName + "_Worker"; } tp.Initialize(); rsrcs.JobStore = js; // add plugins for (int i = 0; i < plugins.Length; i++) { rsrcs.AddSchedulerPlugin(plugins[i]); } schedCtxt = new SchedulingContext(); schedCtxt.InstanceId = rsrcs.InstanceId; qs = new QuartzScheduler(rsrcs, schedCtxt, idleWaitTime, dbFailureRetry); // Create Scheduler ref... IScheduler sched = Instantiate(rsrcs, qs); // set job factory if specified if (jobFactory != null) { qs.JobFactory = jobFactory; } // Initialize plugins now that we have a Scheduler instance. for (int i = 0; i < plugins.Length; i++) { plugins[i].Initialize(pluginNames[i], sched); } // add listeners for (int i = 0; i < jobListeners.Length; i++) { qs.AddGlobalJobListener(jobListeners[i]); } for (int i = 0; i < triggerListeners.Length; i++) { qs.AddGlobalTriggerListener(triggerListeners[i]); } // set scheduler context data... IEnumerator itr = new HashSet(schedCtxtProps).GetEnumerator(); while (itr.MoveNext()) { string key = (String) itr.Current; string val = schedCtxtProps.Get(key); sched.Context.Put(key, val); } // fire up job store, and runshell factory js.Initialize(loadHelper, qs.SchedulerSignaler); jrsf.Initialize(sched, schedCtxt); Log.Info(string.Format(CultureInfo.InvariantCulture, "Quartz scheduler '{0}' initialized", sched.SchedulerName)); Log.Info(string.Format(CultureInfo.InvariantCulture, "Quartz scheduler version: {0}", qs.Version)); // prevents the repository from being garbage collected qs.AddNoGCObject(schedRep); // prevents the db manager from being garbage collected if (dbMgr != null) { qs.AddNoGCObject(dbMgr); } schedRep.Bind(sched); return sched; }
/// <summary> /// Gets the properties parser. /// </summary> /// <returns>The properties parser</returns> protected virtual PropertiesParser GetPropertiesParser() { NameValueCollection settings = (NameValueCollection)ConfigurationManager.GetSection(sectionName) ?? new NameValueCollection(); PropertiesParser result = new PropertiesParser(settings); return result; }