Abstract
We all know the capability of AEM scheduler and most of the cases we use Runnable interface to develop the scheduler.
Recently I had a discussion with my friend about one use case associates with AEM scheduler and here we need to develop a scheduler which will purge the assets from different sub folders at different time.
Earlier I have heard about following interface : org.apache.sling.commons.scheduler.Job .
This interface perfectly applicable for this type of scenario, where we need to run the scheduled job at different time.
Now, let’s jump into the coding.
First I have defined a configuration interface for my scheduler and here we will not see any difference -
/**
*
*/
package com.aem.demo.core.configurations;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
/**
* @author debal
* This is the configuration interface that takes properties for a
* scheduler to run on country specific asset folders at different time
*
*/
@ObjectClassDefinition(name = “Digital Asset Purge Schduler Configuration”, description =”Digital Asset Purge Schduler Configuration”)
public @interface DigitalAssetPurgeSchedulerConfiguration {
@AttributeDefinition(name = “Scheduler name”, description = “Name of the scheduler”, type = AttributeType.STRING)
public String updateSchdulerName() default “Digital Asset Purge Scheduler Configuration”;
@AttributeDefinition(name = “Enabled”, description = “True, if scheduler service is enabled”, type = AttributeType.BOOLEAN)
public boolean enabled() default false;
@AttributeDefinition(name = “Cron Expression Associates With English folder Assets”, description = “Cron expression used by the scheduler on English folder Assets”, type = AttributeType.STRING)
public String enCronExpression() default “0 * * * * ?”;
@AttributeDefinition(name = “Asset Path of English Assets”, description = “Asset Path of English Assets”, type = AttributeType.STRING)
public String enAssetPath() default “”;
@AttributeDefinition(name = “Cron Expression Associates With French folder Assets”, description = “Cron expression used by the scheduler on French folder Assets”, type = AttributeType.STRING)
public String frCronExpression() default “0 * * * * ?”;
@AttributeDefinition(name = “Asset Path of French Assets”, description = “Asset Path of French Assets”, type = AttributeType.STRING)
public String frAssetPath() default “”;
@AttributeDefinition(name = “Cron Expression Associates With India folder Assets”, description = “Cron expression used by the scheduler on India folder Assets”, type = AttributeType.STRING)
public String inCronExpression() default “0 * * * * ?”;
@AttributeDefinition(name = “Asset Path of India Assets”, description = “Asset Path of India Assets”, type = AttributeType.STRING)
public String inAssetPath() default “”;
}
Now I will talk about the scheduler and here we could see my scheduler implements org.apache.sling.commons.scheduler.Job interface -
/**
*
*/
package com.aem.demo.core.schedulers;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.apache.sling.commons.scheduler.Job;
import org.apache.sling.commons.scheduler.JobContext;
import org.apache.sling.commons.scheduler.ScheduleOptions;
import org.apache.sling.commons.scheduler.Scheduler;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.aem.demo.core.configurations.DigitalAssetPurgeSchedulerConfiguration;
/**
* @author debal
*
*/
@Component(service = Job.class, immediate = true)
@Designate(ocd = DigitalAssetPurgeSchedulerConfiguration.class)
public class AssetPurgeScheduler implements Job {
private final Logger logger = LoggerFactory.getLogger(AssetPurgeScheduler.class);
@Reference
Scheduler scheduler;
String schedulerName;
@Activate
private void activate(DigitalAssetPurgeSchedulerConfiguration configuration) {
this.schedulerName = configuration.updateSchdulerName();
logger.info(“**** Asset Update Scheduler ****”);
// This scheduler will continue to run automatically even after the server
// reboot, otherwise the scheduled tasks will stop running after the server
// reboot.
addScheduler(configuration);
}
@Modified
protected void modified(DigitalAssetPurgeSchedulerConfiguration configuration) {
// Remove the scheduler registered with old configuration
removeScheduler(configuration);
// Add the scheduler registered with new configuration
addScheduler(configuration);
}
@Deactivate
protected void deactivated(DigitalAssetPurgeSchedulerConfiguration configuration) {
logger.info(“**** Removing Scheduler Successfully on deactivation ****”);
removeScheduler(configuration);
}
private void removeScheduler(DigitalAssetPurgeSchedulerConfiguration configuration) {
logger.info(“**** Removing Scheduler Successfully **** {}”, schedulerName);
scheduler.unschedule(schedulerName);
}
private void addScheduler(DigitalAssetPurgeSchedulerConfiguration configuration) {
boolean enabled = configuration.enabled();
if (enabled) {
/**
* Create a schedule options to schedule the job for English locale
*/
String enCronExpression = configuration.enCronExpression();
ScheduleOptions enscheduleOptions = scheduler.EXPR(enCronExpression);
Map<String, Serializable> enMap = new HashMap<String, Serializable>();
String enAssetPath = configuration.enAssetPath();
enMap.put(“assetPath”, enAssetPath);
enscheduleOptions.config(enMap);
enscheduleOptions.canRunConcurrently(false);
scheduler.schedule(this, enscheduleOptions);
/**
* Create a schedule options to schedule the job for French locale
*/
String frCronExpression = configuration.frCronExpression();
ScheduleOptions frscheduleOptions = scheduler.EXPR(frCronExpression);
Map<String, Serializable> frMap = new HashMap<String, Serializable>();
String frAssetPath = configuration.frAssetPath();
frMap.put(“assetPath”, frAssetPath);
frscheduleOptions.config(frMap);
frscheduleOptions.canRunConcurrently(false);
scheduler.schedule(this, frscheduleOptions);
/**
* Create a schedule options to schedule the job for India
*/
String inCronExpression = configuration.inCronExpression();
ScheduleOptions inscheduleOptions = scheduler.EXPR(inCronExpression);
Map<String, Serializable> inMap = new HashMap<String, Serializable>();
String inAssetPath = configuration.inAssetPath();
inMap.put(“assetPath”, inAssetPath);
inscheduleOptions.config(inMap);
inscheduleOptions.canRunConcurrently(false);
scheduler.schedule(this, inscheduleOptions);
}
}
@Override
public void execute(JobContext jobContext) {
logger.info(“**** Asset Path****{}”, jobContext.getConfiguration().get(“assetPath”));
/**
* Purge business logic will be included here
*/
}
}
Here execute method knows which scheduled job will be executing at specific time.
Read Full Blog
Q&A
Please use this thread to ask the related questions.
Kautuk Sahni