Skip to content

Commit

Permalink
#22033 Start The PruneTimeMachineJob
Browse files Browse the repository at this point in the history
  • Loading branch information
freddyDOTCMS committed May 16, 2024
1 parent 9043f3d commit ac2b0e8
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.dotcms.timemachine.business;

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.time.Instant;
Expand All @@ -27,16 +26,19 @@
import com.dotmarketing.quartz.CronScheduledTask;
import com.dotmarketing.quartz.QuartzUtils;
import com.dotmarketing.quartz.ScheduledTask;
import com.dotmarketing.quartz.job.PruneTimeMachineBackupJob;
import com.dotmarketing.quartz.job.TimeMachineJob;
import com.dotmarketing.util.*;
import io.vavr.Lazy;

public class TimeMachineAPIImpl implements TimeMachineAPI {

private static final Lazy<String> PRUNE_TIME_MACHINE_SCHEDULE = Lazy.of(() -> Config.getStringProperty(
"PRUNE_TIME_MACHINE_SCHEDULE", "0 0 0 ? * SUN *"));
private static final FilenameFilter TIME_MACHINE_FOLDER_FILTER = new TimeMachineFolderFilter();
public static final String TM_BUNDLE_PREFFIX = "tm_";

public Lazy<Long> PRUNE_TIMEMACHINE_OLDER_THAN_DAYS = Lazy.of(
private static final Lazy<Long> PRUNE_TIMEMACHINE_OLDER_THAN_DAYS = Lazy.of(
() -> Config.getLongProperty("PRUNE_TIMEMACHINE_OLDER_THAN_DAYS", 90)
);

Expand Down Expand Up @@ -131,7 +133,8 @@ public ScheduledTask getQuartzJob() {
return null;
}
else {
return sched.get(0);
return sched.stream().filter(task -> "timemachine".equals(task.getJobName()))
.findFirst().orElse(null);
}
}
catch(Exception ex) {
Expand Down Expand Up @@ -166,6 +169,17 @@ public void removeQuartzJob() throws DotRuntimeException {
}
}

/**
* Start the {@link TimeMachineJob}, if it is already running the restart it with the new values.
*
* Also Start the {@link PruneTimeMachineBackupJob} is it is not running already
*
* @param cronExp
* @param hosts
* @param allhost
* @param langs
* @param incremental
*/
@Override
public void setQuartzJobConfig(String cronExp, List<Host> hosts, boolean allhost, List<Language> langs, boolean incremental) {
Map<String,Object> config=new HashMap<>();
Expand All @@ -175,10 +189,12 @@ public void setQuartzJobConfig(String cronExp, List<Host> hosts, boolean allhost
config.put("allhosts", allhost);
config.put("incremental", incremental);
ScheduledTask task=getQuartzJob();

if(task!=null) {
// delete the old one
removeQuartzJob();
}

// create it
task = new CronScheduledTask("timemachine", "timemachine", "Time Machine",
TimeMachineJob.class.getName(), new Date(), null, 1, config, cronExp);
Expand All @@ -187,8 +203,29 @@ public void setQuartzJobConfig(String cronExp, List<Host> hosts, boolean allhost
} catch (Exception ex) {
throw new RuntimeException(ex);
}

runPruneTimeMachineJo();
}

/**
* Start the PruneTimeMachineBackupJob. If it's already running, restart it.
* By default, the Job's Cron Expression is set to '0 0 0 ? * SUN *', which means every Sunday at midnight.
* However, you can override this default by using the config property PRUNE_TIMEMACHINE_SCHEDULE.
*/
private void runPruneTimeMachineJo() {
Map<String,Object> config = new HashMap<>();
config.put("JOB_NAME", "prune-timemachine");

ScheduledTask task = new CronScheduledTask("prune-timemachine", "timemachine",
"Time Machine Prune Job", PruneTimeMachineBackupJob.class.getName(), new Date(),
null, 1, config, PRUNE_TIME_MACHINE_SCHEDULE.get());

try {
QuartzUtils.scheduleTask(task);
} catch (Exception ex) {
throw new DotRuntimeException(ex);
}
}

private class TimeMachineFileNameFilter implements FilenameFilter{

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ private static List<ScheduledTask> getScheduledTasks(final Scheduler scheduler,
task.setStartDate(t.getStartTime());
task.setEndDate(t.getStartTime());
task.setSequentialScheduled(sequential);
task.setJavaClassName(jobDetail.getJobClass().getName());

result.add(task);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@
import com.dotmarketing.portlets.htmlpageasset.model.HTMLPageAsset;
import com.dotmarketing.portlets.languagesmanager.model.Language;
import com.dotmarketing.portlets.templates.model.Template;
import com.dotmarketing.quartz.CronScheduledTask;
import com.dotmarketing.quartz.QuartzUtils;
import com.dotmarketing.quartz.ScheduledTask;
import com.dotmarketing.quartz.job.AccessTokenRenewJob;
import com.dotmarketing.quartz.job.TestJobExecutor;
import com.dotmarketing.quartz.job.PruneTimeMachineBackupJob;
import com.dotmarketing.quartz.job.TimeMachineJob;
import com.dotmarketing.util.Config;
import com.dotmarketing.util.FileUtil;
import io.vavr.API;
import org.junit.BeforeClass;
import org.junit.Test;
import org.quartz.*;
import org.quartz.spi.TriggerFiredBundle;

import java.io.File;
import java.io.IOException;
Expand All @@ -29,8 +32,7 @@

import static com.dotcms.util.CollectionsUtils.list;
import static com.dotmarketing.quartz.job.AccessTokenRenewJob.ANALYTICS_ACCESS_TOKEN_RENEW_JOB;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;

public class TimeMachineAPITest {

Expand Down Expand Up @@ -198,4 +200,126 @@ public void getAvailableTimeMachineFolder() throws IOException {
Config.setProperty("TIMEMACHINE_PATH", timemachinePathPreviousValue);
}
}

/**
* Method to test: {@link TimeMachineAPIImpl#setQuartzJobConfig(String, List, boolean, List, boolean)}
* When: Called this method and any of this job are not running: {@link com.dotmarketing.quartz.job.TimeMachineJob} and
* {@link com.dotmarketing.quartz.job.PruneTimeMachineBackupJob}
* Should: start both
*/
@Test
public void startTimeMachineJob() throws SchedulerException {
try {
final Language defaultLanguage = APILocator.getLanguageAPI().getDefaultLanguage();
final Host host = new SiteDataGen().nextPersisted();
final Template template = new TemplateDataGen().host(host).nextPersisted();
final HTMLPageAsset htmlPageAsset = new HTMLPageDataGen(host, template)
.languageId(defaultLanguage.getId())
.nextPersisted();

assertTrue(QuartzUtils.getScheduledTasks("timemachine").isEmpty());

final List<Host> hosts = list(host);
final List<Language> langs = list(defaultLanguage);

APILocator.getTimeMachineAPI().setQuartzJobConfig("0 0 0 ? * * *", hosts, false,
langs, false);

assertJobsRunnings(hosts, langs, "0 0 0 ? * * *", "0 0 0 ? * SUN *");
} finally {
removeJobs();
}
}

/**
* Stop and remove the jobs: {@link TimeMachineJob} and {@link PruneTimeMachineBackupJob}
*/
private void removeJobs() throws SchedulerException {
QuartzUtils.pauseJob("timemachine","timemachine");
QuartzUtils.removeTaskRuntimeValues("timemachine","timemachine");
QuartzUtils.removeJob("timemachine","timemachine");

QuartzUtils.pauseJob("prune-timemachine","timemachine");
QuartzUtils.removeTaskRuntimeValues("prune-timemachine","timemachine");
QuartzUtils.removeJob("prune-timemachine","timemachine");
}

/**
* Check if {@link TimeMachineJob} and {@link PruneTimeMachineBackupJob} are running
* @param hosts
* @param langs
*/
private static void assertJobsRunnings(final List<Host> hosts, final List<Language> langs, final String tmJonCron,
final String pruneTMCron) throws SchedulerException {
final List<ScheduledTask> taskList = QuartzUtils.getScheduledTasks("timemachine");

assertEquals(2, taskList.size());

for (final ScheduledTask scheduledTask : taskList) {
if (scheduledTask.getJobName().equals("timemachine")) {
assertEquals("timemachine", scheduledTask.getJobName());
assertEquals("timemachine", scheduledTask.getJobGroup());
assertEquals("Time Machine", scheduledTask.getJobDescription());
assertEquals(TimeMachineJob.class.getName(), scheduledTask.getJavaClassName());
assertEquals(tmJonCron, ((CronScheduledTask) scheduledTask).getCronExpression());

final Map<String, Object> jobProperties = scheduledTask.getProperties();

assertEquals(jobProperties.get("CRON_EXPRESSION"), tmJonCron);
assertEquals(jobProperties.get("hosts"), hosts);
assertEquals(jobProperties.get("langs"), langs);
assertEquals(false, jobProperties.get("allhosts"));
assertEquals(false, jobProperties.get("incremental"));
} else if (scheduledTask.getJobName().equals("prune-timemachine")) {
assertEquals("prune-timemachine", scheduledTask.getJobName());
assertEquals("timemachine", scheduledTask.getJobGroup());
assertEquals("Time Machine Prune Job", scheduledTask.getJobDescription());
assertEquals(PruneTimeMachineBackupJob.class.getName(), scheduledTask.getJavaClassName());
assertEquals(pruneTMCron, ((CronScheduledTask) scheduledTask).getCronExpression());

final Map<String, Object> jobProperties = scheduledTask.getProperties();

assertEquals("prune-timemachine", jobProperties.get("JOB_NAME").toString());
} else {
throw new AssertionError("Not expected Task called " + scheduledTask.getJobName());
}
}
}

/**
* Method to test: {@link TimeMachineAPIImpl#startTimeMachine(List, List, boolean)}
* When: Called this method and the {@link com.dotmarketing.quartz.job.PruneTimeMachineBackupJob} is already running
* Should: Restart just the {@link com.dotmarketing.quartz.job.TimeMachineJob}
*/
@Test
public void startTimeMachineJobWhenPruneJobIsAlreadyRunning() throws SchedulerException {
try {
final Language defaultLanguage = APILocator.getLanguageAPI().getDefaultLanguage();
final Host host = new SiteDataGen().nextPersisted();
final Template template = new TemplateDataGen().host(host).nextPersisted();
final HTMLPageAsset htmlPageAsset = new HTMLPageDataGen(host, template)
.languageId(defaultLanguage.getId())
.nextPersisted();

assertTrue(QuartzUtils.getScheduledTasks("timemachine").isEmpty());

final List<Host> hosts = list(host);
final List<Language> langs = list(defaultLanguage);

APILocator.getTimeMachineAPI().setQuartzJobConfig("0 0 0 ? * * *", hosts, false,
langs, false);

APILocator.getTimeMachineAPI().removeQuartzJob();

assertFalse(QuartzUtils.getScheduledTask("prune-timemachine", "timemachine").isEmpty());
assertTrue(QuartzUtils.getScheduledTask("timemachine", "timemachine").isEmpty());

APILocator.getTimeMachineAPI().setQuartzJobConfig("0 0 1 ? * * *", hosts, false,
langs, false);

assertJobsRunnings(hosts, langs, "0 0 1 ? * * *", "0 0 0 ? * SUN *");
} finally {
removeJobs();
}
}
}

0 comments on commit ac2b0e8

Please sign in to comment.