Skip to content

Commit

Permalink
Initial implementation with properties configured schedulers
Browse files Browse the repository at this point in the history
  • Loading branch information
maallen committed Aug 23, 2023
1 parent 73d3a22 commit 06c9c21
Show file tree
Hide file tree
Showing 18 changed files with 409 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.box.l10n.mojito.cli.utils.TestingJobListener;
import com.box.l10n.mojito.entity.Repository;
import com.box.l10n.mojito.json.ObjectMapper;
import com.box.l10n.mojito.quartz.QuartzSchedulerManager;
import com.box.l10n.mojito.rest.thirdparty.ThirdPartySyncAction;
import com.box.l10n.mojito.service.thirdparty.ThirdPartySyncJob;
import com.box.l10n.mojito.service.thirdparty.ThirdPartySyncJobInput;
Expand All @@ -19,7 +20,6 @@
import org.junit.Test;
import org.quartz.JobKey;
import org.quartz.Matcher;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
Expand All @@ -30,9 +30,7 @@ public class ThirdPartySyncCommandTest extends CLITestBase {
@Qualifier("fail_on_unknown_properties_false")
ObjectMapper objectMapper;

@Autowired
@Qualifier("defaultScheduler")
Scheduler scheduler;
@Autowired QuartzSchedulerManager schedulerManager;

Matcher<JobKey> jobMatcher;
TestingJobListener testingJobListener;
Expand All @@ -41,13 +39,20 @@ public class ThirdPartySyncCommandTest extends CLITestBase {
public void setUp() throws SchedulerException {
testingJobListener = new TestingJobListener(objectMapper);
jobMatcher = new PollableTaskJobMatcher<>(ThirdPartySyncJob.class);
scheduler.getListenerManager().addJobListener(testingJobListener, jobMatcher);
schedulerManager
.getScheduler(QuartzSchedulerManager.DEFAULT_SCHEDULER_NAME)
.getListenerManager()
.addJobListener(testingJobListener, jobMatcher);
}

@After
public void tearDown() throws SchedulerException {
scheduler.getListenerManager().removeJobListener(testingJobListener.getName());
scheduler
schedulerManager
.getScheduler(QuartzSchedulerManager.DEFAULT_SCHEDULER_NAME)
.getListenerManager()
.removeJobListener(testingJobListener.getName());
schedulerManager
.getScheduler(QuartzSchedulerManager.DEFAULT_SCHEDULER_NAME)
.getListenerManager()
.removeJobListenerMatcher(testingJobListener.getName(), jobMatcher);
}
Expand Down
92 changes: 64 additions & 28 deletions docker/docker-compose-api-worker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,38 @@ services:
"spring.datasource.driverClassName" : "com.mysql.cj.jdbc.Driver",
"spring.jpa.defer-datasource-initialization" : "false",
"l10n.org.quartz.scheduler.enabled" : "true",
"l10n.org.quartz.jobStore.useProperties" : "true",
"l10n.org.quartz.scheduler.instanceId" : "AUTO",
"l10n.org.quartz.jobStore.isClustered" : "true",
"l10n.org.quartz.threadPool.threadCount" : "10",
"l10n.org.quartz.jobStore.class" : "org.quartz.impl.jdbcjobstore.JobStoreTX",
"l10n.org.quartz.jobStore.driverDelegateClass" : "org.quartz.impl.jdbcjobstore.StdJDBCDelegate",
"l10n.org.quartz.jobStore.dataSource" : "myDS",
"l10n.org.quartz.dataSource.myDS.provider" : "hikaricp",
"l10n.org.quartz.dataSource.myDS.driver" : "com.mysql.jdbc.Driver",
"l10n.org.quartz.dataSource.myDS.URL" : "jdbc:mysql://db:3306/mojito?characterEncoding=UTF-8&useUnicode=true",
"l10n.org.quartz.dataSource.myDS.user" : "mojito",
"l10n.org.quartz.dataSource.myDS.password" : "ChangeMe",
"l10n.org.quartz.dataSource.myDS.maxConnections" : "12",
"l10n.org.quartz.dataSource.myDS.validationQuery" : "select 1"
"l10n.org.multi-quartz.enabled" : "true",
"l10n.org.multi-quartz.schedulerConfigs[0].name" : "defaultScheduler",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.jobStore.useProperties" : "true",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.scheduler.instanceId" : "AUTO",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.jobStore.isClustered" : "true",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.threadPool.threadCount" : 10,
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.jobStore.class" : "org.quartz.impl.jdbcjobstore.JobStoreTX",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.jobStore.driverDelegateClass" : "org.quartz.impl.jdbcjobstore.StdJDBCDelegate",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.jobStore.dataSource" : "myDS",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.provider" : "hikaricp",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.driver" : "com.mysql.jdbc.Driver",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.URL" : "jdbc:mysql://db:3306/mojito?characterEncoding=UTF-8&useUnicode=true",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.user" : "mojito",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.password" : "ChangeMe",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.maxConnections" : 12,
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.validationQuery" : "select 1",
"l10n.org.multi-quartz.schedulerConfigs[1].name" : "lowPriority",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.jobStore.useProperties" : "true",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.scheduler.instanceId" : "AUTO",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.jobStore.isClustered" : "true",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.threadPool.threadCount" : 5,
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.jobStore.class" : "org.quartz.impl.jdbcjobstore.JobStoreTX",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.jobStore.driverDelegateClass" : "org.quartz.impl.jdbcjobstore.StdJDBCDelegate",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.jobStore.dataSource" : "myDS",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.provider" : "hikaricp",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.driver" : "com.mysql.jdbc.Driver",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.URL" : "jdbc:mysql://db:3306/mojito?characterEncoding=UTF-8&useUnicode=true",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.user" : "mojito",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.password" : "ChangeMe",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.maxConnections" : 12,
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.validationQuery" : "select 1",
"l10n.assetExtraction.quartz.schedulerName" : "lowPriority"
}'
api:
deploy:
Expand Down Expand Up @@ -114,18 +132,36 @@ services:
"spring.datasource.driverClassName" : "com.mysql.cj.jdbc.Driver",
"spring.jpa.defer-datasource-initialization" : "false",
"l10n.org.quartz.scheduler.enabled" : "false",
"l10n.org.quartz.jobStore.useProperties" : "true",
"l10n.org.quartz.scheduler.instanceId" : "AUTO",
"l10n.org.quartz.jobStore.isClustered" : "true",
"l10n.org.quartz.threadPool.threadCount" : "10",
"l10n.org.quartz.jobStore.class" : "org.quartz.impl.jdbcjobstore.JobStoreTX",
"l10n.org.quartz.jobStore.driverDelegateClass" : "org.quartz.impl.jdbcjobstore.StdJDBCDelegate",
"l10n.org.quartz.jobStore.dataSource" : "myDS",
"l10n.org.quartz.dataSource.myDS.provider" : "hikaricp",
"l10n.org.quartz.dataSource.myDS.driver" : "com.mysql.jdbc.Driver",
"l10n.org.quartz.dataSource.myDS.URL" : "jdbc:mysql://db:3306/mojito?characterEncoding=UTF-8&useUnicode=true",
"l10n.org.quartz.dataSource.myDS.user" : "mojito",
"l10n.org.quartz.dataSource.myDS.password" : "ChangeMe",
"l10n.org.quartz.dataSource.myDS.maxConnections" : "12",
"l10n.org.quartz.dataSource.myDS.validationQuery" : "select 1"
"l10n.org.multi-quartz.enabled" : "true",
"l10n.org.multi-quartz.schedulerConfigs[0].name" : "defaultScheduler",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.jobStore.useProperties" : "true",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.scheduler.instanceId" : "AUTO",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.jobStore.isClustered" : "true",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.threadPool.threadCount" : 10,
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.jobStore.class" : "org.quartz.impl.jdbcjobstore.JobStoreTX",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.jobStore.driverDelegateClass" : "org.quartz.impl.jdbcjobstore.StdJDBCDelegate",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.jobStore.dataSource" : "myDS",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.provider" : "hikaricp",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.driver" : "com.mysql.jdbc.Driver",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.URL" : "jdbc:mysql://db:3306/mojito?characterEncoding=UTF-8&useUnicode=true",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.user" : "mojito",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.password" : "ChangeMe",
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.maxConnections" : 12,
"l10n.org.multi-quartz.schedulerConfigs[0].quartz.dataSource.myDS.validationQuery" : "select 1",
"l10n.org.multi-quartz.schedulerConfigs[1].name" : "lowPriority",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.jobStore.useProperties" : "true",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.scheduler.instanceId" : "AUTO",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.jobStore.isClustered" : "true",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.threadPool.threadCount" : 5,
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.jobStore.class" : "org.quartz.impl.jdbcjobstore.JobStoreTX",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.jobStore.driverDelegateClass" : "org.quartz.impl.jdbcjobstore.StdJDBCDelegate",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.jobStore.dataSource" : "myDS",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.provider" : "hikaricp",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.driver" : "com.mysql.jdbc.Driver",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.URL" : "jdbc:mysql://db:3306/mojito?characterEncoding=UTF-8&useUnicode=true",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.user" : "mojito",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.password" : "ChangeMe",
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.maxConnections" : 12,
"l10n.org.multi-quartz.schedulerConfigs[1].quartz.dataSource.myDS.validationQuery" : "select 1",
"l10n.assetExtraction.quartz.schedulerName" : "lowPriority"
}'
27 changes: 17 additions & 10 deletions webapp/src/main/java/com/box/l10n/mojito/quartz/QuartzConfig.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.box.l10n.mojito.quartz;

import static com.box.l10n.mojito.quartz.QuartzSchedulerManager.DEFAULT_SCHEDULER_NAME;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import javax.annotation.PostConstruct;
import org.quartz.JobDetail;
Expand All @@ -16,6 +17,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
Expand All @@ -25,15 +27,16 @@ public class QuartzConfig {

public static final String DYNAMIC_GROUP_NAME = "DYNAMIC";

@Autowired List<Scheduler> schedulers;
@Autowired QuartzSchedulerManager schedulerManager;

@Autowired(required = false)
List<Trigger> triggers = new ArrayList<>();

@Autowired(required = false)
List<JobDetail> jobDetails = new ArrayList<>();

@Autowired QuartzPropertiesConfig quartzPropertiesConfig;
@Value("${l10n.org.quartz.scheduler.enabled:true}")
Boolean schedulerEnabled;

/**
* Starts the scheduler after having removed outdated trigger/jobs
Expand All @@ -42,24 +45,28 @@ public class QuartzConfig {
*/
@PostConstruct
void startSchedulers() throws SchedulerException {
Properties quartzProps = quartzPropertiesConfig.getQuartzProperties();
removeOutdatedJobs();
if (Boolean.parseBoolean(quartzProps.getProperty("org.quartz.scheduler.enabled", "true"))) {
logger.info("Starting schedulers");
for (Scheduler scheduler : schedulers) {
scheduler.startDelayed(2);
int delay = 2;
if (schedulerEnabled) {
for (Scheduler scheduler : schedulerManager.getSchedulers()) {
logger.info("Starting scheduler: {}", scheduler.getSchedulerName());
scheduler.startDelayed(delay);
delay++;
}
}
}

void removeOutdatedJobs() throws SchedulerException {
for (Scheduler scheduler : schedulers) {
scheduler.unscheduleJobs(new ArrayList<TriggerKey>(getOutdatedTriggerKeys(scheduler)));
for (Scheduler scheduler : schedulerManager.getSchedulers()) {
if (scheduler.getSchedulerName().equals(DEFAULT_SCHEDULER_NAME)) {
scheduler.unscheduleJobs(new ArrayList<TriggerKey>(getOutdatedTriggerKeys(scheduler)));
}
scheduler.deleteJobs(new ArrayList<JobKey>(getOutdatedJobKeys(scheduler)));
}
}

Set<JobKey> getOutdatedJobKeys(Scheduler scheduler) throws SchedulerException {

Set<JobKey> jobKeys =
scheduler.getJobKeys(GroupMatcher.jobGroupEquals(Scheduler.DEFAULT_GROUP));
Set<JobKey> newJobKeys = new HashSet<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.box.l10n.mojito.quartz;

import static com.box.l10n.mojito.quartz.QuartzConfig.DYNAMIC_GROUP_NAME;
import static com.box.l10n.mojito.quartz.QuartzQueue.DEFAULT;
import static com.box.l10n.mojito.quartz.QuartzSchedulerManager.DEFAULT_SCHEDULER_NAME;

import com.box.l10n.mojito.entity.PollableTask;
import com.box.l10n.mojito.json.ObjectMapper;
Expand Down Expand Up @@ -42,7 +42,7 @@ public <I, O> PollableFuture<O> scheduleJob(
Class<? extends QuartzPollableJob<I, O>> clazz, I input) {
QuartzJobInfo<I, O> quartzJobInfo =
QuartzJobInfo.newBuilder(clazz).withInput(input).withMessage(clazz.getSimpleName()).build();
return scheduleJob(quartzJobInfo, DEFAULT);
return scheduleJob(quartzJobInfo, DEFAULT_SCHEDULER_NAME);
}

public <I, O> PollableFuture<O> scheduleJobWithCustomTimeout(
Expand All @@ -54,11 +54,11 @@ public <I, O> PollableFuture<O> scheduleJobWithCustomTimeout(
.withMessage(clazz.getSimpleName())
.build();

return scheduleJob(quartzJobInfo, DEFAULT);
return scheduleJob(quartzJobInfo, DEFAULT_SCHEDULER_NAME);
}

public <I, O> PollableFuture<O> scheduleJob(QuartzJobInfo<I, O> quartzJobInfo) {
return scheduleJob(quartzJobInfo, DEFAULT);
return scheduleJob(quartzJobInfo, DEFAULT_SCHEDULER_NAME);
}

/**
Expand All @@ -80,11 +80,11 @@ public <I, O> PollableFuture<O> scheduleJob(QuartzJobInfo<I, O> quartzJobInfo) {
* @return
*/
public <I, O> PollableFuture<O> scheduleJob(
QuartzJobInfo<I, O> quartzJobInfo, QuartzQueue quartzQueue) {
QuartzJobInfo<I, O> quartzJobInfo, String schedulerName) {

Scheduler scheduler = schedulerManager.getScheduler(quartzQueue);
Scheduler scheduler = schedulerManager.getScheduler(schedulerName);

logger.debug("Scheduling job on queue: {}", quartzQueue.getDescription());
logger.debug("Scheduling job on queue: {}", schedulerName);

String pollableTaskName = getPollableTaskName(quartzJobInfo.getClazz());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties("l10n.org")
@ConditionalOnProperty(
name = "l10n.org.multi-quartz.enabled",
havingValue = "false",
matchIfMissing = true)
public class QuartzPropertiesConfig {

static Logger logger = LoggerFactory.getLogger(QuartzPropertiesConfig.class);
Expand All @@ -31,6 +36,9 @@ public Properties getQuartzProperties() {
logger.debug("org.quartz.{}={}", entry.getKey(), entry.getValue());
}

properties.put(
"org.quartz.scheduler.instanceName", QuartzSchedulerManager.DEFAULT_SCHEDULER_NAME);

return properties;
}
}
17 changes: 0 additions & 17 deletions webapp/src/main/java/com/box/l10n/mojito/quartz/QuartzQueue.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.box.l10n.mojito.quartz;

public class QuartzQueueException extends RuntimeException {

public QuartzQueueException(String message) {
super(message);
}

public QuartzQueueException(String message, Throwable cause) {
super(message, cause);
}
}
Loading

0 comments on commit 06c9c21

Please sign in to comment.