/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community 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://opensource.org/licenses/ecl2.txt
*
* 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.opencastproject.workspace.impl;
import org.opencastproject.workspace.api.Workspace;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
/** Clear outdated workspace files {@link Workspace}. */
public class WorkspaceCleaner {
/** Log facility */
private static final Logger logger = LoggerFactory.getLogger(WorkspaceCleaner.class);
private static final String JOB_NAME = "mh-workspace-cleaner-job";
private static final String JOB_GROUP = "mh-workspace-cleaner-job-group";
private static final String TRIGGER_NAME = "mh-workspace-cleaner-trigger";
private static final String TRIGGER_GROUP = "mh-workspace-cleaner-trigger-group";
private static final String JOB_PARAM_PARENT = "parent";
private final org.quartz.Scheduler quartz;
private final Workspace workspace;
private final int maxAge;
private int schedulerPeriod;
protected WorkspaceCleaner(Workspace workspace, int schedulerPeriod, int maxAge) {
this.workspace = workspace;
this.maxAge = maxAge;
this.schedulerPeriod = schedulerPeriod;
// Continue only if we have a sensible period value
if (schedulerPeriod <= 0) {
logger.debug("No scheduler initialized due to invalid scheduling period ({})", schedulerPeriod);
quartz = null;
return;
}
try {
quartz = new StdSchedulerFactory().getScheduler();
quartz.start();
// create and set the job. To actually run it call schedule(..)
final JobDetail job = new JobDetail(JOB_NAME, JOB_GROUP, Runner.class);
job.setDurability(false);
job.setVolatility(true);
job.getJobDataMap().put(JOB_PARAM_PARENT, this);
quartz.addJob(job, true);
} catch (org.quartz.SchedulerException e) {
throw new RuntimeException(e);
}
}
public Workspace getWorkspace() {
return workspace;
}
public int getMaxAge() {
return maxAge;
}
/**
* Set the schedule and start or restart the scheduler.
*/
public void schedule() {
if (quartz == null || schedulerPeriod <= 0) {
logger.debug("Cancel scheduling of workspace cleaner due to invalid scheduling period");
return;
}
logger.debug("Scheduling workspace cleaner to run every {} seconds.", schedulerPeriod);
try {
final Trigger trigger = TriggerUtils.makeSecondlyTrigger(schedulerPeriod);
trigger.setStartTime(new Date());
trigger.setName(TRIGGER_NAME);
trigger.setGroup(TRIGGER_GROUP);
trigger.setJobName(JOB_NAME);
trigger.setJobGroup(JOB_GROUP);
if (quartz.getTriggersOfJob(JOB_NAME, JOB_GROUP).length == 0) {
quartz.scheduleJob(trigger);
} else {
quartz.rescheduleJob(TRIGGER_NAME, TRIGGER_GROUP, trigger);
}
} catch (Exception e) {
logger.error("Error scheduling Quartz job", e);
}
}
/** Shutdown the scheduler. */
public void shutdown() {
try {
quartz.shutdown();
} catch (org.quartz.SchedulerException ignore) {
}
}
// just to make sure Quartz is being shut down...
@Override
protected void finalize() throws Throwable {
super.finalize();
shutdown();
}
// --
/** Quartz work horse. */
public static class Runner implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
logger.debug("Start workspace cleaner");
try {
execute((WorkspaceCleaner) jobExecutionContext.getJobDetail().getJobDataMap().get(JOB_PARAM_PARENT));
} catch (Exception e) {
throw new JobExecutionException("An error occurred while cleaning workspace", e);
}
logger.debug("Finished workspace cleaner");
}
private void execute(WorkspaceCleaner workspaceCleaner) {
workspaceCleaner.getWorkspace().cleanup(workspaceCleaner.getMaxAge());
}
}
}