package org.onehippo.forge.konakart.cms.replication.service; import org.apache.commons.lang.StringUtils; import org.hippoecm.frontend.plugin.IPluginContext; import org.hippoecm.frontend.plugin.Plugin; import org.hippoecm.frontend.plugin.config.IPluginConfig; import org.onehippo.forge.konakart.cms.replication.synchronization.HippoKonakartDaemonModule; import org.onehippo.forge.konakart.common.engine.KKStoreConfig; import org.onehippo.forge.konakart.common.jcr.HippoModuleConfig; import org.quartz.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.jcr.Session; import java.text.ParseException; import java.util.Collection; import java.util.Date; public class KonakartSynchronizationService extends Plugin { private static Logger log = LoggerFactory.getLogger(KonakartSynchronizationService.class); private static final String MASS_SYNC_JOB_ONCE = "KonkartMassSyncJobOnce"; private static final String MASS_SYNC_JOB = "KonkartMassSyncJob"; private static final String MASS_SYNC_JOB_TRIGGER_ONCE = MASS_SYNC_JOB + "TriggerOnce"; private static final String MASS_SYNC_JOB_TRIGGER = MASS_SYNC_JOB + "Trigger"; private static final String MASS_SYNC_JOB_TRIGGER_GROUP = MASS_SYNC_JOB_TRIGGER + "Group"; private static final String MASS_SYNC_JOB_GROUP = MASS_SYNC_JOB + "Group"; protected Scheduler resourceScheduler; public KonakartSynchronizationService(IPluginContext context, IPluginConfig config) { super(context, config); init(); } protected void init() { initScheduler(); Session jcrSession = HippoKonakartDaemonModule.getSession(); initializeKonakartModules(jcrSession); initializeJobs(jcrSession); } protected void initScheduler() { this.resourceScheduler = HippoKonakartDaemonModule.getScheduler(); } protected void initializeKonakartModules(Session jcrSession) { HippoModuleConfig.load(jcrSession); } /** * Initialize each job. */ protected void initializeJobs(Session jcrSession) { Collection<KKStoreConfig> kkStoreConfigs = HippoModuleConfig.getConfig().getStoresConfig().values(); if (kkStoreConfigs.size() == 0) { log.error("No store config has been found. Please check the konakart:konakart configuration"); return; } // Get the first one. KKStoreConfig kkStoreConfig = kkStoreConfigs.iterator().next(); try { String triggerName = MASS_SYNC_JOB_TRIGGER; String jobName = MASS_SYNC_JOB_ONCE; JobDetail jobDetail = new JobDetail(jobName, MASS_SYNC_JOB_GROUP, Class.forName(kkStoreConfig.getJobClass())); JobDataMap dataMap = new JobDataMap(); jobDetail.setJobDataMap(dataMap); // Create a trigger that fires immediately, and run only once Trigger trigger = new SimpleTrigger(MASS_SYNC_JOB_TRIGGER_ONCE); trigger.setStartTime(new Date(System.currentTimeMillis() + 10000)); if (!triggerExists(trigger)) { resourceScheduler.scheduleJob(jobDetail, trigger); } jobName = MASS_SYNC_JOB; jobDetail = new JobDetail(jobName, MASS_SYNC_JOB_GROUP, Class.forName(kkStoreConfig.getJobClass())); // Create the cron task. The first launch is scheduled after 30 minutes if (StringUtils.isNotEmpty(kkStoreConfig.getCronExpression())) { trigger = new CronTrigger(triggerName, MASS_SYNC_JOB_TRIGGER_GROUP, jobName, MASS_SYNC_JOB_GROUP, kkStoreConfig.getCronExpression()); trigger.setStartTime(new Date(System.currentTimeMillis() + 1000)); if (triggerExists(trigger)) { if (triggerChanged(trigger)) { resourceScheduler.rescheduleJob(MASS_SYNC_JOB_TRIGGER, MASS_SYNC_JOB_TRIGGER_GROUP, trigger); } } else { resourceScheduler.scheduleJob(jobDetail, trigger); } } } catch (ClassNotFoundException e) { log.error("Failed to find the Job class named - " + kkStoreConfig.getJobClass(), e); } catch (ParseException e) { log.error("Failed to parse the cron expression - " + kkStoreConfig.getCronExpression(), e); } catch (SchedulerException e) { log.error("Failed to start the job", e); } } protected boolean triggerExists(Trigger checkTrigger) { try { Trigger trigger = resourceScheduler.getTrigger(checkTrigger.getName(), checkTrigger.getGroup()); return (trigger != null); } catch (SchedulerException e) { log.error("Failed to check if the trigger exists", e); } return false; } protected boolean triggerChanged(Trigger checkTrigger) { try { Trigger trigger = resourceScheduler.getTrigger(checkTrigger.getName(), checkTrigger.getGroup()); if (trigger != null && trigger instanceof CronTrigger) { return !((CronTrigger) trigger).getCronExpression().equals(((CronTrigger) checkTrigger).getCronExpression()); } } catch (SchedulerException e) { log.error("Failed to check if the trigger has changed", e); } return false; } }