QuartzSchedulerResources.java
/*
* All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
* Copyright IBM Corp. 2024, 2025
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
package org.quartz.core;
import java.util.ArrayList;
import java.util.List;
import org.quartz.management.ManagementRESTServiceConfiguration;
import org.quartz.spi.JobStore;
import org.quartz.spi.SchedulerPlugin;
import org.quartz.spi.ThreadExecutor;
import org.quartz.spi.ThreadPool;
/**
* <p>
* Contains all of the resources (<code>JobStore</code>,<code>ThreadPool</code>,
* etc.) necessary to create a <code>{@link QuartzScheduler}</code> instance.
* </p>
*
* @see QuartzScheduler
*
* @author James House
*/
public class QuartzSchedulerResources {
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Data members.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
public static final String CREATE_REGISTRY_NEVER = "never";
public static final String CREATE_REGISTRY_ALWAYS = "always";
public static final String CREATE_REGISTRY_AS_NEEDED = "as_needed";
private String name;
private String instanceId;
private String threadName;
private String rmiRegistryHost = null;
private int rmiRegistryPort = 1099;
private int rmiServerPort = -1;
private String rmiCreateRegistryStrategy = CREATE_REGISTRY_NEVER;
private ThreadPool threadPool;
private JobStore jobStore;
private JobRunShellFactory jobRunShellFactory;
private final List<SchedulerPlugin> schedulerPlugins = new ArrayList<>(10);
private boolean makeSchedulerThreadDaemon = false;
private boolean threadsInheritInitializersClassLoadContext = false;
private String rmiBindName;
private boolean jmxExport;
private String jmxObjectName;
private ManagementRESTServiceConfiguration managementRESTServiceConfiguration;
private ThreadExecutor threadExecutor;
private long batchTimeWindow = 0;
private int maxBatchSize = 1;
private boolean interruptJobsOnShutdown = false;
private boolean interruptJobsOnShutdownWithWait = false;
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Constructors.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/**
* <p>
* Create an instance with no properties initialized.
* </p>
*/
public QuartzSchedulerResources() {
// do nothing...
}
/*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Interface.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/**
* <p>
* Get the name for the <code>{@link QuartzScheduler}</code>.
* </p>
*/
public String getName() {
return name;
}
/**
* <p>
* Set the name for the <code>{@link QuartzScheduler}</code>.
* </p>
*
* @exception IllegalArgumentException
* if name is null or empty.
*/
public void setName(String name) {
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException(
"Scheduler name cannot be empty.");
}
this.name = name;
if (threadName == null) {
// thread name not already set, use default thread name
setThreadName(name + "_QuartzSchedulerThread");
}
}
/**
* <p>
* Get the instance Id for the <code>{@link QuartzScheduler}</code>.
* </p>
*/
public String getInstanceId() {
return instanceId;
}
/**
* <p>
* Set the name for the <code>{@link QuartzScheduler}</code>.
* </p>
*
* @exception IllegalArgumentException
* if name is null or empty.
*/
public void setInstanceId(String instanceId) {
if (instanceId == null || instanceId.trim().isEmpty()) {
throw new IllegalArgumentException(
"Scheduler instanceId cannot be empty.");
}
this.instanceId = instanceId;
}
public static String getUniqueIdentifier(String schedName,
String schedInstId) {
return schedName + "_$_" + schedInstId;
}
public String getUniqueIdentifier() {
return getUniqueIdentifier(name, instanceId);
}
/**
* <p>
* Get the host name of the RMI Registry that the scheduler should export
* itself to.
* </p>
*/
public String getRMIRegistryHost() {
return rmiRegistryHost;
}
/**
* <p>
* Set the host name of the RMI Registry that the scheduler should export
* itself to.
* </p>
*/
public void setRMIRegistryHost(String hostName) {
this.rmiRegistryHost = hostName;
}
/**
* <p>
* Get the port number of the RMI Registry that the scheduler should export
* itself to.
* </p>
*/
public int getRMIRegistryPort() {
return rmiRegistryPort;
}
/**
* <p>
* Set the port number of the RMI Registry that the scheduler should export
* itself to.
* </p>
*/
public void setRMIRegistryPort(int port) {
this.rmiRegistryPort = port;
}
/**
* <p>
* Get the port number the scheduler server will be bound to.
* </p>
*/
public int getRMIServerPort() {
return rmiServerPort;
}
/**
* <p>
* Set the port number the scheduler server will be bound to.
* </p>
*/
public void setRMIServerPort(int port) {
this.rmiServerPort = port;
}
/**
* <p>
* Get the setting of whether or not Quartz should create an RMI Registry,
* and if so, how.
* </p>
*/
public String getRMICreateRegistryStrategy() {
return rmiCreateRegistryStrategy;
}
/**
* <p>
* Get the name for the <code>{@link QuartzSchedulerThread}</code>.
* </p>
*/
public String getThreadName() {
return threadName;
}
/**
* <p>
* Set the name for the <code>{@link QuartzSchedulerThread}</code>.
* </p>
*
* @exception IllegalArgumentException
* if name is null or empty.
*/
public void setThreadName(String threadName) {
if (threadName == null || threadName.trim().isEmpty()) {
throw new IllegalArgumentException(
"Scheduler thread name cannot be empty.");
}
this.threadName = threadName;
}
/**
* <p>
* Set whether or not Quartz should create an RMI Registry, and if so, how.
* </p>
*
* @see #CREATE_REGISTRY_ALWAYS
* @see #CREATE_REGISTRY_AS_NEEDED
* @see #CREATE_REGISTRY_NEVER
*/
public void setRMICreateRegistryStrategy(String rmiCreateRegistryStrategy) {
if (rmiCreateRegistryStrategy == null
|| rmiCreateRegistryStrategy.trim().isEmpty()) {
rmiCreateRegistryStrategy = CREATE_REGISTRY_NEVER;
} else if (rmiCreateRegistryStrategy.equalsIgnoreCase("true")) {
rmiCreateRegistryStrategy = CREATE_REGISTRY_AS_NEEDED;
} else if (rmiCreateRegistryStrategy.equalsIgnoreCase("false")) {
rmiCreateRegistryStrategy = CREATE_REGISTRY_NEVER;
} else if (rmiCreateRegistryStrategy.equalsIgnoreCase(CREATE_REGISTRY_ALWAYS)) {
rmiCreateRegistryStrategy = CREATE_REGISTRY_ALWAYS;
} else if (rmiCreateRegistryStrategy.equalsIgnoreCase(CREATE_REGISTRY_AS_NEEDED)) {
rmiCreateRegistryStrategy = CREATE_REGISTRY_AS_NEEDED;
} else if (rmiCreateRegistryStrategy.equalsIgnoreCase(CREATE_REGISTRY_NEVER)) {
rmiCreateRegistryStrategy = CREATE_REGISTRY_NEVER;
} else {
throw new IllegalArgumentException(
"Failed to set RMICreateRegistryStrategy - strategy unknown: '"
+ rmiCreateRegistryStrategy + "'");
}
this.rmiCreateRegistryStrategy = rmiCreateRegistryStrategy;
}
/**
* <p>
* Get the <code>{@link ThreadPool}</code> for the <code>{@link QuartzScheduler}</code>
* to use.
* </p>
*/
public ThreadPool getThreadPool() {
return threadPool;
}
/**
* <p>
* Set the <code>{@link ThreadPool}</code> for the <code>{@link QuartzScheduler}</code>
* to use.
* </p>
*
* @exception IllegalArgumentException
* if threadPool is null.
*/
public void setThreadPool(ThreadPool threadPool) {
if (threadPool == null) {
throw new IllegalArgumentException("ThreadPool cannot be null.");
}
this.threadPool = threadPool;
}
/**
* <p>
* Get the <code>{@link JobStore}</code> for the <code>{@link QuartzScheduler}</code>
* to use.
* </p>
*/
public JobStore getJobStore() {
return jobStore;
}
/**
* <p>
* Set the <code>{@link JobStore}</code> for the <code>{@link QuartzScheduler}</code>
* to use.
* </p>
*
* @exception IllegalArgumentException
* if jobStore is null.
*/
public void setJobStore(JobStore jobStore) {
if (jobStore == null) {
throw new IllegalArgumentException("JobStore cannot be null.");
}
this.jobStore = jobStore;
}
/**
* <p>
* Get the <code>{@link JobRunShellFactory}</code> for the <code>{@link QuartzScheduler}</code>
* to use.
* </p>
*/
public JobRunShellFactory getJobRunShellFactory() {
return jobRunShellFactory;
}
/**
* <p>
* Set the <code>{@link JobRunShellFactory}</code> for the <code>{@link QuartzScheduler}</code>
* to use.
* </p>
*
* @exception IllegalArgumentException
* if jobRunShellFactory is null.
*/
public void setJobRunShellFactory(JobRunShellFactory jobRunShellFactory) {
if (jobRunShellFactory == null) {
throw new IllegalArgumentException(
"JobRunShellFactory cannot be null.");
}
this.jobRunShellFactory = jobRunShellFactory;
}
/**
* <p>
* Add the given <code>{@link org.quartz.spi.SchedulerPlugin}</code> for the
* <code>{@link QuartzScheduler}</code> to use. This method expects the plugin's
* "initialize" method to be invoked externally (either before or after
* this method is called).
* </p>
*/
public void addSchedulerPlugin(SchedulerPlugin plugin) {
schedulerPlugins.add(plugin);
}
/**
* <p>
* Get the <code>List</code> of all
* <code>{@link org.quartz.spi.SchedulerPlugin}</code>s for the
* <code>{@link QuartzScheduler}</code> to use.
* </p>
*/
public List<SchedulerPlugin> getSchedulerPlugins() {
return schedulerPlugins;
}
/**
* Get whether to mark the Quartz scheduling thread as daemon.
*
* @see Thread#setDaemon(boolean)
*/
public boolean getMakeSchedulerThreadDaemon() {
return makeSchedulerThreadDaemon;
}
/**
* Set whether to mark the Quartz scheduling thread as daemon.
*
* @see Thread#setDaemon(boolean)
*/
public void setMakeSchedulerThreadDaemon(boolean makeSchedulerThreadDaemon) {
this.makeSchedulerThreadDaemon = makeSchedulerThreadDaemon;
}
/**
* Get whether to set the class load context of spawned threads to that
* of the initializing thread.
*/
public boolean isThreadsInheritInitializersClassLoadContext() {
return threadsInheritInitializersClassLoadContext;
}
/**
* Set whether to set the class load context of spawned threads to that
* of the initializing thread.
*/
public void setThreadsInheritInitializersClassLoadContext(
boolean threadsInheritInitializersClassLoadContext) {
this.threadsInheritInitializersClassLoadContext = threadsInheritInitializersClassLoadContext;
}
/**
* Get the name under which to bind the QuartzScheduler in RMI. Will
* return the value of the uniqueIdentifier property if explicit RMI bind
* name was never set.
*
* @see #getUniqueIdentifier()
*/
public String getRMIBindName() {
return (rmiBindName == null) ? getUniqueIdentifier() : rmiBindName;
}
/**
* Set the name under which to bind the QuartzScheduler in RMI. If unset,
* defaults to the value of the uniqueIdentifier property.
*
* @see #getUniqueIdentifier()
*/
public void setRMIBindName(String rmiBindName) {
this.rmiBindName = rmiBindName;
}
/**
* Get whether the QuartzScheduler should be registered with the local
* MBeanServer.
*/
public boolean getJMXExport() {
return jmxExport;
}
/**
* Set whether the QuartzScheduler should be registered with the local
* MBeanServer.
*/
public void setJMXExport(boolean jmxExport) {
this.jmxExport = jmxExport;
}
/**
* Get the name under which the QuartzScheduler should be registered with
* the local MBeanServer. If unset, defaults to the value calculated by
* <code>generateJMXObjectName</code>.
*
* @see #generateJMXObjectName(String, String)
*/
public String getJMXObjectName() {
return (jmxObjectName == null) ? generateJMXObjectName(name, instanceId) : jmxObjectName;
}
/**
* Set the name under which the QuartzScheduler should be registered with
* the local MBeanServer. If unset, defaults to the value calculated by
* <code>generateJMXObjectName</code>.
*
* @see #generateJMXObjectName(String, String)
*/
public void setJMXObjectName(String jmxObjectName) {
this.jmxObjectName = jmxObjectName;
}
/**
* Get the ThreadExecutor which runs the QuartzSchedulerThread
*/
public ThreadExecutor getThreadExecutor() {
return threadExecutor;
}
/**
* Set the ThreadExecutor which runs the QuartzSchedulerThread
*/
public void setThreadExecutor(ThreadExecutor threadExecutor) {
this.threadExecutor = threadExecutor;
}
/**
* Create the name under which this scheduler should be registered in JMX.
* <p>
* The name is composed as:
* quartz:type=QuartzScheduler,name=<i>[schedName]</i>,instance=<i>[schedInstId]</i>
* </p>
*/
public static String generateJMXObjectName(String schedName, String schedInstId) {
return "quartz:type=QuartzScheduler" + ",name="
+ schedName.replaceAll(":|=|\n", ".")
+ ",instance=" + schedInstId;
}
public long getBatchTimeWindow() {
return batchTimeWindow;
}
public void setBatchTimeWindow(long batchTimeWindow) {
this.batchTimeWindow = batchTimeWindow;
}
public int getMaxBatchSize() {
return maxBatchSize;
}
public void setMaxBatchSize(int maxBatchSize) {
this.maxBatchSize = maxBatchSize;
}
public boolean isInterruptJobsOnShutdown() {
return interruptJobsOnShutdown;
}
public void setInterruptJobsOnShutdown(boolean interruptJobsOnShutdown) {
this.interruptJobsOnShutdown = interruptJobsOnShutdown;
}
public boolean isInterruptJobsOnShutdownWithWait() {
return interruptJobsOnShutdownWithWait;
}
public void setInterruptJobsOnShutdownWithWait(
boolean interruptJobsOnShutdownWithWait) {
this.interruptJobsOnShutdownWithWait = interruptJobsOnShutdownWithWait;
}
public ManagementRESTServiceConfiguration getManagementRESTServiceConfiguration() {
return managementRESTServiceConfiguration;
}
public void setManagementRESTServiceConfiguration(ManagementRESTServiceConfiguration managementRESTServiceConfiguration) {
this.managementRESTServiceConfiguration = managementRESTServiceConfiguration;
}
}