You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2013/10/09 19:28:26 UTC
svn commit: r1530723 [1/2] - in /sling/trunk/bundles/extensions/event: ./
src/main/java/org/apache/sling/event/impl/dea/
src/main/java/org/apache/sling/event/impl/jobs/
src/main/java/org/apache/sling/event/impl/jobs/console/
src/main/java/org/apache/sl...
Author: cziegeler
Date: Wed Oct 9 17:28:25 2013
New Revision: 1530723
URL: http://svn.apache.org/r1530723
Log:
SLING-3139 : Provide a way to schedule jobs
Added:
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ScheduleInfoImpl.java
- copied, changed from r1530653, sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ScheduleInfo.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/ScheduleInfo.java (with props)
Removed:
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ScheduleInfo.java
Modified:
sling/trunk/bundles/extensions/event/pom.xml
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/dea/DistributedEventReceiver.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobBuilderImpl.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobSchedulerImpl.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/MaintenanceTask.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/ScheduledJobInfoImpl.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/Utility.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/console/WebConsolePlugin.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/deprecated/EventAdminBridge.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/deprecated/JobStatusProviderImpl.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/AbstractJobQueue.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/timed/ScheduleInfo.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/timed/TimedEventSender.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/JobBuilder.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/JobManager.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/ScheduledJobInfo.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobConsumer.java
sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/it/AbstractJobHandlingTest.java
sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/it/JobHandlingTest.java
sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/it/TimedJobsTest.java
Modified: sling/trunk/bundles/extensions/event/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/pom.xml?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/pom.xml (original)
+++ sling/trunk/bundles/extensions/event/pom.xml Wed Oct 9 17:28:25 2013
@@ -220,7 +220,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.commons.scheduler</artifactId>
- <version>2.1.0</version>
+ <version>2.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/dea/DistributedEventReceiver.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/dea/DistributedEventReceiver.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/dea/DistributedEventReceiver.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/dea/DistributedEventReceiver.java Wed Oct 9 17:28:25 2013
@@ -197,7 +197,7 @@ public class DistributedEventReceiver
final String[] propNames = event.getPropertyNames();
if ( propNames != null && propNames.length > 0 ) {
for(final String propName : propNames) {
- if ( !ResourceHelper.ignoreProperty(propName) || JobUtil.JOB_ID.equals(propName) ) { // special handling for job id
+ if ( !ResourceHelper.ignoreProperty(propName) || ResourceHelper.PROPERTY_JOB_ID.equals(propName) ) { // special handling for job id
properties.put(propName, event.getProperty(propName));
}
}
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobBuilderImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobBuilderImpl.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobBuilderImpl.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobBuilderImpl.java Wed Oct 9 17:28:25 2013
@@ -18,14 +18,15 @@
*/
package org.apache.sling.event.impl.jobs;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import java.util.Map;
-import org.apache.sling.event.impl.support.ScheduleInfo;
+import org.apache.sling.event.impl.support.ScheduleInfoImpl;
import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.JobBuilder;
import org.apache.sling.event.jobs.ScheduledJobInfo;
-import org.slf4j.Logger;
/**
* Fluent builder API
@@ -36,18 +37,16 @@ public class JobBuilderImpl implements J
private final JobManagerImpl jobManager;
- private final Logger logger;
-
private String name;
private Map<String, Object> properties;
- public JobBuilderImpl(final JobManagerImpl manager, final Logger logger, final String topic) {
+ public JobBuilderImpl(final JobManagerImpl manager, final String topic) {
this.jobManager = manager;
this.topic = topic;
- this.logger = logger;
}
+
@Override
public JobBuilder name(final String name) {
this.name = name;
@@ -62,7 +61,12 @@ public class JobBuilderImpl implements J
@Override
public Job add() {
- return this.jobManager.addJob(this.topic, this.name, this.properties);
+ return this.add(null);
+ }
+
+ @Override
+ public Job add(final List<String> errors) {
+ return this.jobManager.addJob(this.topic, this.name, this.properties, errors);
}
@Override
@@ -70,105 +74,75 @@ public class JobBuilderImpl implements J
return new ScheduleBuilderImpl(name);
}
- public final class ScheduleBuilderImpl implements ScheduleBuilder {
+ public final class ScheduleBuilderImpl implements ScheduleBuilder,
+ WeekBuilder, DayBuilder, MinuteBuilder, DateBuilder, ScheduleBuilderAdder {
private final String scheduleName;
private boolean suspend = false;
+ private final List<ScheduleInfoImpl> schedules = new ArrayList<ScheduleInfoImpl>();
+
public ScheduleBuilderImpl(final String name) {
this.scheduleName = name;
}
- private boolean check() {
- if ( this.scheduleName == null || this.scheduleName.length() == 0 ) {
- logger.warn("Discarding scheduled job - schedule name not specified");
- return false;
- }
- final String errorMessage = Utility.checkJob(topic, properties);
- if ( errorMessage != null ) {
- logger.warn("{}", errorMessage);
- return false;
- }
- return true;
- }
-
- @Override
- public boolean hourly(final int minutes) {
- if ( check() ) {
- if ( minutes > 0 ) {
- final ScheduleInfo info = ScheduleInfo.HOURLY(minutes);
- return jobManager.addScheduledJob(topic, name, properties, scheduleName, suspend, info);
- }
- logger.warn("Discarding scheduled job - minutes must be between 0 and 59 : {}", minutes);
- }
- return false;
- }
-
- @Override
- public TimeBuilder daily() {
- return new TimeBuilderImpl(ScheduledJobInfo.ScheduleType.DAILY, -1);
- }
-
- @Override
- public TimeBuilder weekly(final int day) {
- return new TimeBuilderImpl(ScheduledJobInfo.ScheduleType.WEEKLY, day);
- }
-
- @Override
- public boolean at(final Date date) {
- if ( check() ) {
- if ( date != null && date.getTime() > System.currentTimeMillis() ) {
- final ScheduleInfo info = ScheduleInfo.AT(date);
- return jobManager.addScheduledJob(topic, name, properties, scheduleName, suspend, info);
- }
- logger.warn("Discarding scheduled job - date must be in the future : {}", date);
- }
- return false;
- }
-
- @Override
- public ScheduleBuilder suspend(final boolean flag) {
- this.suspend = flag;
- return this;
- }
-
- public final class TimeBuilderImpl implements TimeBuilder {
-
- private final ScheduledJobInfo.ScheduleType scheduleType;
-
- private final int day;
-
- public TimeBuilderImpl(ScheduledJobInfo.ScheduleType scheduleType, final int day) {
- this.scheduleType = scheduleType;
- this.day = day;
- }
-
- @Override
- public boolean at(final int hour, final int minute) {
- if ( check() ) {
- boolean valid = true;
- if ( scheduleType == ScheduledJobInfo.ScheduleType.WEEKLY ) {
- if ( day < 1 || day > 7 ) {
- valid = false;
- logger.warn("Discarding scheduled job - day must be between 1 and 7 : {}", day);
- }
- }
- if ( valid ) {
- if ( hour >= 0 && hour < 24 && minute >= 0 && minute < 60 ) {
- final ScheduleInfo info;
- if ( scheduleType == ScheduledJobInfo.ScheduleType.WEEKLY ) {
- info = ScheduleInfo.WEEKLY(this.day, hour, minute);
- } else {
- info = ScheduleInfo.DAYLY(hour, minute);
- }
- return jobManager.addScheduledJob(topic, name, properties, scheduleName, suspend, info);
- }
- logger.warn("Discarding scheduled job - wrong time information : {}â¦{}", hour, minute);
- }
- }
- return false;
- }
+ @Override
+ public WeekBuilder weekly(final int day, final int hour, final int minute) {
+ schedules.add(ScheduleInfoImpl.WEEKLY(day, hour, minute));
+ return this;
+ }
+
+ @Override
+ public DayBuilder dayly(final int hour, final int minute) {
+ schedules.add(ScheduleInfoImpl.DAYLY(hour, minute));
+ return this;
+ }
+
+ @Override
+ public MinuteBuilder hourly(final int minute) {
+ schedules.add(ScheduleInfoImpl.HOURLY(minute));
+ return this;
+ }
+
+ @Override
+ public DateBuilder at(final Date date) {
+ schedules.add(ScheduleInfoImpl.AT(date));
+ return this;
+ }
+
+ @Override
+ public MinuteBuilder at(int minute) {
+ schedules.add(ScheduleInfoImpl.HOURLY(minute));
+ return this;
+ }
+
+ @Override
+ public DayBuilder at(int hour, int minute) {
+ schedules.add(ScheduleInfoImpl.DAYLY(hour, minute));
+ return this;
+ }
+
+ @Override
+ public WeekBuilder at(int day, int hour, int minute) {
+ schedules.add(ScheduleInfoImpl.WEEKLY(day, hour, minute));
+ return this;
+ }
+
+ @Override
+ public ScheduledJobInfo add() {
+ return this.add(null);
+ }
+
+ @Override
+ public ScheduledJobInfo add(final List<String> errors) {
+ return jobManager.addScheduledJob(topic, name, properties, scheduleName, suspend, schedules, errors);
+ }
+
+ @Override
+ public ScheduleBuilder suspend() {
+ this.suspend = true;
+ return this;
}
}
}
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobManagerImpl.java Wed Oct 9 17:28:25 2013
@@ -69,7 +69,7 @@ import org.apache.sling.event.impl.jobs.
import org.apache.sling.event.impl.jobs.stats.TopicStatisticsImpl;
import org.apache.sling.event.impl.support.Environment;
import org.apache.sling.event.impl.support.ResourceHelper;
-import org.apache.sling.event.impl.support.ScheduleInfo;
+import org.apache.sling.event.impl.support.ScheduleInfoImpl;
import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.JobBuilder;
import org.apache.sling.event.jobs.JobManager;
@@ -517,10 +517,10 @@ public class JobManagerImpl
final ValueMap vm = ResourceHelper.getValueMap(resource);
// check job topic and job id
- final String errorMessage = Utility.checkJobTopic(vm.get(JobUtil.PROPERTY_JOB_TOPIC));
- final String jobId = vm.get(JobUtil.JOB_ID, String.class);
+ final String errorMessage = Utility.checkJobTopic(vm.get(ResourceHelper.PROPERTY_JOB_TOPIC));
+ final String jobId = vm.get(ResourceHelper.PROPERTY_JOB_ID, String.class);
if ( errorMessage == null && jobId != null ) {
- final String topic = vm.get(JobUtil.PROPERTY_JOB_TOPIC, String.class);
+ final String topic = vm.get(ResourceHelper.PROPERTY_JOB_TOPIC, String.class);
final Map<String, Object> jobProperties = ResourceHelper.cloneValueMap(vm);
jobProperties.put(JobImpl.PROPERTY_RESOURCE_PATH, resource.getPath());
@@ -542,7 +542,7 @@ public class JobManagerImpl
}
}
job = new JobImpl(topic,
- (String)jobProperties.get(JobUtil.PROPERTY_JOB_NAME),
+ (String)jobProperties.get(ResourceHelper.PROPERTY_JOB_NAME),
jobId,
jobProperties);
} else {
@@ -833,16 +833,7 @@ public class JobManagerImpl
*/
@Override
public Job addJob(final String topic, final String name, final Map<String, Object> properties) {
- final String errorMessage = Utility.checkJob(topic, properties);
- if ( errorMessage != null ) {
- logger.warn("{}", errorMessage);
- return null;
- }
- Job result = this.addJobInteral(topic, name, properties);
- if ( result == null && name != null ) {
- result = this.getJobByName(name);
- }
- return result;
+ return this.addJob(topic, name, properties, null);
}
/**
@@ -859,7 +850,7 @@ public class JobManagerImpl
buf.append("//element(*,");
buf.append(ResourceHelper.RESOURCE_TYPE_JOB);
buf.append(")[@");
- buf.append(ISO9075.encode(JobUtil.PROPERTY_JOB_NAME));
+ buf.append(ISO9075.encode(ResourceHelper.PROPERTY_JOB_NAME));
buf.append(" = '");
buf.append(name);
buf.append("']");
@@ -902,7 +893,7 @@ public class JobManagerImpl
buf.append("//element(*,");
buf.append(ResourceHelper.RESOURCE_TYPE_JOB);
buf.append(")[@");
- buf.append(JobUtil.JOB_ID);
+ buf.append(ResourceHelper.PROPERTY_JOB_ID);
buf.append(" = '");
buf.append(id);
buf.append("']");
@@ -977,7 +968,7 @@ public class JobManagerImpl
buf.append("//element(*,");
buf.append(ResourceHelper.RESOURCE_TYPE_JOB);
buf.append(")[@");
- buf.append(ISO9075.encode(JobUtil.PROPERTY_JOB_TOPIC));
+ buf.append(ISO9075.encode(ResourceHelper.PROPERTY_JOB_TOPIC));
buf.append(" = '");
buf.append(topic);
buf.append("'");
@@ -1244,7 +1235,10 @@ public class JobManagerImpl
* @param jobProperties The optional job properties
* @return The persisted job or <code>null</code>.
*/
- private Job addJobInteral(final String jobTopic, final String jobName, final Map<String, Object> jobProperties) {
+ private Job addJobInteral(final String jobTopic,
+ final String jobName,
+ final Map<String, Object> jobProperties,
+ final List<String> errors) {
final QueueInfo info = this.queueConfigManager.getQueueInfo(jobTopic);
if ( info.queueConfiguration.getType() == QueueConfiguration.Type.DROP ) {
if ( logger.isDebugEnabled() ) {
@@ -1281,8 +1275,8 @@ public class JobManagerImpl
if ( configuration.isLocalJob(job.getResourcePath()) ) {
this.backgroundLoader.addJob(job);
}
+ return job;
}
- return job;
} catch (final PersistenceException re ) {
// something went wrong, so let's log it
this.logger.error("Exception during persisting new job '" + Utility.toString(jobTopic, jobName, jobProperties) + "'", re);
@@ -1294,6 +1288,9 @@ public class JobManagerImpl
resolver.close();
}
}
+ if ( errors != null ) {
+ errors.add("Unable to persist new job.");
+ }
}
}
return null;
@@ -1327,10 +1324,10 @@ public class JobManagerImpl
}
}
- properties.put(JobUtil.JOB_ID, jobId);
- properties.put(JobUtil.PROPERTY_JOB_TOPIC, jobTopic);
+ properties.put(ResourceHelper.PROPERTY_JOB_ID, jobId);
+ properties.put(ResourceHelper.PROPERTY_JOB_TOPIC, jobTopic);
if ( jobName != null ) {
- properties.put(JobUtil.PROPERTY_JOB_NAME, jobName);
+ properties.put(ResourceHelper.PROPERTY_JOB_NAME, jobName);
}
properties.put(Job.PROPERTY_JOB_QUEUE_NAME, info.queueConfiguration.getName());
properties.put(Job.PROPERTY_JOB_RETRY_COUNT, 0);
@@ -1464,7 +1461,7 @@ public class JobManagerImpl
*/
@Override
public JobBuilder createJob(final String topic) {
- return new JobBuilderImpl(this, this.logger, topic);
+ return new JobBuilderImpl(this, topic);
}
/**
@@ -1483,18 +1480,64 @@ public class JobManagerImpl
return this.jobScheduler.getScheduledJob(name);
}
- public boolean addScheduledJob(final String topic,
+ public ScheduledJobInfo addScheduledJob(final String topic,
final String jobName,
final Map<String, Object> properties,
final String scheduleName,
final boolean isSuspended,
- final ScheduleInfo scheduleInfo) {
- try {
- return this.jobScheduler.writeJob(topic, jobName, properties, scheduleName, isSuspended, scheduleInfo);
- } catch ( final PersistenceException pe) {
- logger.warn("Unable to persist scheduled job", pe);
+ final List<ScheduleInfoImpl> scheduleInfos,
+ final List<String> errors) {
+ final List<String> msgs = new ArrayList<String>();
+ if ( scheduleName == null || scheduleName.length() == 0 ) {
+ msgs.add("Schedule name not specified");
}
- return false;
+ final String errorMessage = Utility.checkJob(topic, properties);
+ if ( errorMessage != null ) {
+ msgs.add(errorMessage);
+ }
+ if ( scheduleInfos.size() == 0 ) {
+ msgs.add("No schedule defined for " + scheduleName);
+ }
+ for(final ScheduleInfoImpl info : scheduleInfos) {
+ info.check(msgs);
+ }
+ if ( msgs.size() == 0 ) {
+ try {
+ final ScheduledJobInfo info = this.jobScheduler.writeJob(topic, jobName, properties, scheduleName, isSuspended, scheduleInfos);
+ if ( info != null ) {
+ return info;
+ }
+ msgs.add("Unable to persist scheduled job.");
+ } catch ( final PersistenceException pe) {
+ msgs.add("Unable to persist scheduled job: " + scheduleName);
+ logger.warn("Unable to persist scheduled job", pe);
+ }
+ } else {
+ for(final String msg : msgs) {
+ logger.warn(msg);
+ }
+ }
+ if ( errors != null ) {
+ errors.addAll(msgs);
+ }
+ return null;
}
+ public Job addJob(final String topic, final String name,
+ final Map<String, Object> properties,
+ final List<String> errors) {
+ final String errorMessage = Utility.checkJob(topic, properties);
+ if ( errorMessage != null ) {
+ logger.warn("{}", errorMessage);
+ if ( errors != null ) {
+ errors.add(errorMessage);
+ }
+ return null;
+ }
+ Job result = this.addJobInteral(topic, name, properties, errors);
+ if ( result == null && name != null ) {
+ result = this.getJobByName(name);
+ }
+ return result;
+ }
}
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobSchedulerImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobSchedulerImpl.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobSchedulerImpl.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobSchedulerImpl.java Wed Oct 9 17:28:25 2013
@@ -29,7 +29,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -47,16 +46,18 @@ import org.apache.sling.api.resource.Res
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.commons.scheduler.JobContext;
+import org.apache.sling.commons.scheduler.ScheduleOptions;
import org.apache.sling.commons.scheduler.Scheduler;
import org.apache.sling.discovery.TopologyEvent;
import org.apache.sling.discovery.TopologyEvent.Type;
import org.apache.sling.discovery.TopologyEventListener;
import org.apache.sling.event.impl.support.Environment;
import org.apache.sling.event.impl.support.ResourceHelper;
-import org.apache.sling.event.impl.support.ScheduleInfo;
+import org.apache.sling.event.impl.support.ScheduleInfoImpl;
import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.JobBuilder;
import org.apache.sling.event.jobs.JobUtil;
+import org.apache.sling.event.jobs.ScheduleInfo;
import org.apache.sling.event.jobs.ScheduledJobInfo;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
@@ -149,12 +150,7 @@ public class JobSchedulerImpl
if ( this.active ) {
final Collection<ScheduledJobInfo> jobs = this.getScheduledJobs();
for(final ScheduledJobInfo info : jobs) {
- try {
- logger.debug("Stopping scheduled job : {}", info.getName());
- this.scheduler.removeJob(((ScheduledJobInfoImpl)info).getSchedulerJobId());
- } catch ( final NoSuchElementException nsee ) {
- this.ignoreException(nsee);
- }
+ this.stopScheduledJob((ScheduledJobInfoImpl)info);
}
}
}
@@ -190,27 +186,8 @@ public class JobSchedulerImpl
if ( event.getTopic().equals(TOPIC_READ_JOB) ) {
@SuppressWarnings("unchecked")
final Map<String, Object> properties = (Map<String, Object>) event.getProperty(PROPERTY_READ_JOB);
- properties.remove(ResourceResolver.PROPERTY_RESOURCE_TYPE);
- properties.remove(Job.PROPERTY_JOB_CREATED);
- properties.remove(Job.PROPERTY_JOB_CREATED_INSTANCE);
-
- final String jobTopic = (String) properties.remove(JobUtil.PROPERTY_JOB_TOPIC);
- final String jobName = (String) properties.remove(JobUtil.PROPERTY_JOB_NAME);
- final String schedulerName = (String) properties.remove(ResourceHelper.PROPERTY_SCHEDULE_NAME);
- final ScheduleInfo scheduleInfo = (ScheduleInfo) properties.remove(ResourceHelper.PROPERTY_SCHEDULE_INFO);
- final boolean isSuspended = properties.remove(ResourceHelper.PROPERTY_SCHEDULE_SUSPENDED) != null;
- // and now schedule
- final String key = ResourceHelper.filterName(schedulerName);
- ScheduledJobInfoImpl info;
- synchronized ( this.scheduledJobs ) {
- info = this.scheduledJobs.get(key);
- if ( info == null ) {
- info = new ScheduledJobInfoImpl(this, jobTopic, jobName,
- properties, schedulerName);
- this.scheduledJobs.put(key, info);
- }
- info.update(isSuspended, scheduleInfo);
- }
+ final ScheduledJobInfoImpl info = this.addOrUpdateScheduledJob(properties);
+
if ( this.active ) {
this.startScheduledJob(info);
}
@@ -249,14 +226,7 @@ public class JobSchedulerImpl
info = this.scheduledJobs.remove(scheduleName);
}
if ( info != null && this.active ) {
- logger.debug("Stopping scheduled job : {}", info.getName());
- try {
- this.scheduler.removeJob(info.getSchedulerJobId());
- } catch (final NoSuchElementException nsee) {
- // this can happen if the job is scheduled on another node
- // so we can just ignore this
- }
-
+ this.stopScheduledJob(info);
}
}
event = nextEvent;
@@ -264,6 +234,32 @@ public class JobSchedulerImpl
}
}
+ private ScheduledJobInfoImpl addOrUpdateScheduledJob(final Map<String, Object> properties) {
+ properties.remove(ResourceResolver.PROPERTY_RESOURCE_TYPE);
+ properties.remove(Job.PROPERTY_JOB_CREATED);
+ properties.remove(Job.PROPERTY_JOB_CREATED_INSTANCE);
+
+ final String jobTopic = (String) properties.remove(ResourceHelper.PROPERTY_JOB_TOPIC);
+ final String jobName = (String) properties.remove(ResourceHelper.PROPERTY_JOB_NAME);
+ final String schedulerName = (String) properties.remove(ResourceHelper.PROPERTY_SCHEDULE_NAME);
+ @SuppressWarnings("unchecked")
+ final List<ScheduleInfo> scheduleInfos = (List<ScheduleInfo>) properties.remove(ResourceHelper.PROPERTY_SCHEDULE_INFO);
+ final boolean isSuspended = properties.remove(ResourceHelper.PROPERTY_SCHEDULE_SUSPENDED) != null;
+ // and now schedule
+ final String key = ResourceHelper.filterName(schedulerName);
+ ScheduledJobInfoImpl info;
+ synchronized ( this.scheduledJobs ) {
+ info = this.scheduledJobs.get(key);
+ if ( info == null ) {
+ info = new ScheduledJobInfoImpl(this, jobTopic, jobName,
+ properties, schedulerName);
+ this.scheduledJobs.put(key, info);
+ }
+ info.update(isSuspended, scheduleInfos);
+ }
+ return info;
+ }
+
private void startScheduledJob(final ScheduledJobInfoImpl info) {
if ( !info.isSuspended() ) {
// Create configuration for scheduled job
@@ -271,24 +267,35 @@ public class JobSchedulerImpl
config.put(PROPERTY_READ_JOB, info);
logger.debug("Adding scheduled job: {}", info.getName());
- try {
- switch ( info.getScheduleType() ) {
- case DAILY:
+ int index = 0;
+ for(final ScheduleInfo si : info.getSchedules()) {
+ final String name = info.getSchedulerJobId() + "-" + String.valueOf(index);
+ ScheduleOptions options = null;
+ switch ( si.getType() ) {
+ case DAYLY:
case WEEKLY:
case HOURLY:
- this.scheduler.addJob(info.getSchedulerJobId(), this, config, info.getCronExpression(), false);
+ options = this.scheduler.EXPR(((ScheduleInfoImpl)si).getCronExpression());
+
break;
case DATE:
- this.scheduler.fireJobAt(info.getSchedulerJobId(), this, config, info.getNextScheduledExecution());
+ options = this.scheduler.AT(((ScheduleInfoImpl)si).getNextScheduledExecution());
break;
}
- } catch (final Exception e) {
- // we ignore it if scheduled fails...
- this.ignoreException(e);
+ this.scheduler.schedule(this, options.name(name).config(config).canRunConcurrently(false));
+ index++;
}
}
}
+ private void stopScheduledJob(final ScheduledJobInfoImpl info) {
+ logger.debug("Stopping scheduled job : {}", info.getName());
+ for(int index = 0; index<info.getSchedules().size(); index++) {
+ final String name = info.getSchedulerJobId() + "-" + String.valueOf(index);
+ this.scheduler.unschedule(name);
+ }
+ }
+
/**
* @see org.apache.sling.commons.scheduler.Job#execute(org.apache.sling.commons.scheduler.JobContext)
*/
@@ -297,12 +304,6 @@ public class JobSchedulerImpl
final ScheduledJobInfoImpl info = (ScheduledJobInfoImpl) context.getConfiguration().get(PROPERTY_READ_JOB);
this.jobManager.addJob(info.getJobTopic(), info.getJobName(), info.getJobProperties());
-
- // is this job scheduled for a specific date?
- if ( info.getScheduleType() == ScheduledJobInfo.ScheduleType.DATE ) {
- // we can remove it from the resource tree
- this.unschedule(info);
- }
}
public void unschedule(final ScheduledJobInfoImpl info) {
@@ -500,13 +501,13 @@ public class JobSchedulerImpl
* Write a schedule job to the resource tree.
* @throws PersistenceException
*/
- public boolean writeJob(
+ public ScheduledJobInfoImpl writeJob(
final String jobTopic,
final String jobName,
final Map<String, Object> jobProperties,
final String scheduleName,
final boolean suspend,
- final ScheduleInfo scheduleInfo)
+ final List<ScheduleInfoImpl> scheduleInfos)
throws PersistenceException {
ResourceResolver resolver = null;
try {
@@ -524,16 +525,22 @@ public class JobSchedulerImpl
}
}
- properties.put(JobUtil.PROPERTY_JOB_TOPIC, jobTopic);
+ properties.put(ResourceHelper.PROPERTY_JOB_TOPIC, jobTopic);
if ( jobName != null ) {
- properties.put(JobUtil.PROPERTY_JOB_NAME, jobName);
+ properties.put(ResourceHelper.PROPERTY_JOB_NAME, jobName);
}
properties.put(Job.PROPERTY_JOB_CREATED, Calendar.getInstance());
properties.put(Job.PROPERTY_JOB_CREATED_INSTANCE, Environment.APPLICATION_ID);
// put scheduler name and scheduler info
properties.put(ResourceHelper.PROPERTY_SCHEDULE_NAME, scheduleName);
- properties.put(ResourceHelper.PROPERTY_SCHEDULE_INFO, scheduleInfo.getSerializedString());
+ final String[] infoArray = new String[scheduleInfos.size()];
+ int index = 0;
+ for(final ScheduleInfoImpl info : scheduleInfos) {
+ infoArray[index] = info.getSerializedString();
+ index++;
+ }
+ properties.put(ResourceHelper.PROPERTY_SCHEDULE_INFO, infoArray);
if ( suspend ) {
properties.put(ResourceHelper.PROPERTY_SCHEDULE_SUSPENDED, Boolean.TRUE);
}
@@ -558,7 +565,10 @@ public class JobSchedulerImpl
ResourceHelper.getOrCreateResource(resolver,
path,
properties);
- return true;
+ // put back real schedule infos
+ properties.put(ResourceHelper.PROPERTY_SCHEDULE_INFO, scheduleInfos);
+
+ return this.addOrUpdateScheduledJob(properties);
} catch ( final LoginException le ) {
// we ignore this
this.ignoreException(le);
@@ -567,7 +577,7 @@ public class JobSchedulerImpl
resolver.close();
}
}
- return false;
+ return null;
}
/**
@@ -600,12 +610,18 @@ public class JobSchedulerImpl
}
}
+ /**
+ * Create a schedule builder for a currently scheduled job
+ */
public JobBuilder.ScheduleBuilder createJobBuilder(final ScheduledJobInfoImpl info) {
final JobBuilder builder = this.jobManager.createJob(info.getJobTopic()).name(info.getJobTopic()).properties(info.getJobProperties());
final JobBuilder.ScheduleBuilder sb = builder.schedule(info.getName());
- return sb.suspend(info.isSuspended());
+ return (info.isSuspended() ? sb.suspend() : sb);
}
+ /**
+ * Get all scheduled jobs
+ */
public Collection<ScheduledJobInfo> getScheduledJobs() {
final List<ScheduledJobInfo> jobs = new ArrayList<ScheduledJobInfo>();
synchronized ( this.scheduledJobs ) {
@@ -616,6 +632,9 @@ public class JobSchedulerImpl
return jobs;
}
+ /**
+ * Get a scheduled job with the given name
+ */
public ScheduledJobInfo getScheduledJob(final String name) {
synchronized ( this.scheduledJobs ) {
return this.scheduledJobs.get(ResourceHelper.filterName(name));
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/MaintenanceTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/MaintenanceTask.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/MaintenanceTask.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/MaintenanceTask.java Wed Oct 9 17:28:25 2013
@@ -710,7 +710,7 @@ public class MaintenanceTask {
properties.put(JobImpl.PROPERTY_BRIDGED_EVENT, true);
final String topic = (String)properties.remove("slingevent:topic");
- properties.put(JobUtil.PROPERTY_JOB_TOPIC, topic);
+ properties.put(ResourceHelper.PROPERTY_JOB_TOPIC, topic);
properties.remove(Job.PROPERTY_JOB_QUEUE_NAME);
properties.remove(Job.PROPERTY_JOB_TARGET_INSTANCE);
@@ -752,7 +752,7 @@ public class MaintenanceTask {
properties.put(ResourceResolver.PROPERTY_RESOURCE_TYPE, ResourceHelper.RESOURCE_TYPE_JOB);
final String jobId = this.configuration.getUniqueId(topic);
- properties.put(JobUtil.JOB_ID, jobId);
+ properties.put(ResourceHelper.PROPERTY_JOB_ID, jobId);
properties.remove(Job.PROPERTY_JOB_STARTED_TIME);
final String newPath = this.configuration.getUniquePath(targetId, topic, jobId, vm);
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/ScheduledJobInfoImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/ScheduledJobInfoImpl.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/ScheduledJobInfoImpl.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/ScheduledJobInfoImpl.java Wed Oct 9 17:28:25 2013
@@ -19,14 +19,17 @@
package org.apache.sling.event.impl.jobs;
import java.io.Serializable;
-import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
-import org.apache.sling.event.impl.support.ScheduleInfo;
+import org.apache.sling.event.impl.support.ScheduleInfoImpl;
import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.JobBuilder.ScheduleBuilder;
+import org.apache.sling.event.jobs.ScheduleInfo;
import org.apache.sling.event.jobs.ScheduledJobInfo;
public class ScheduledJobInfoImpl implements ScheduledJobInfo, Serializable {
@@ -43,7 +46,7 @@ public class ScheduledJobInfoImpl implem
private final JobSchedulerImpl jobScheduler;
- private ScheduleInfo scheduleInfo;
+ private List<ScheduleInfo> scheduleInfos;
private AtomicBoolean isSuspended;
@@ -60,8 +63,8 @@ public class ScheduledJobInfoImpl implem
}
public void update(final boolean isSuspended,
- final ScheduleInfo scheduleInfo) {
- this.scheduleInfo = scheduleInfo;
+ final List<ScheduleInfo> scheduleInfos) {
+ this.scheduleInfos = Collections.unmodifiableList(scheduleInfos);
this.isSuspended = new AtomicBoolean(isSuspended);
}
@@ -74,11 +77,11 @@ public class ScheduledJobInfoImpl implem
}
/**
- * @see org.apache.sling.event.jobs.ScheduledJobInfo#getScheduleType()
+ * @see org.apache.sling.event.jobs.ScheduledJobInfo#getSchedules()
*/
@Override
- public ScheduleType getScheduleType() {
- return this.scheduleInfo.getScheduleType();
+ public Collection<ScheduleInfo> getSchedules() {
+ return this.scheduleInfos;
}
/**
@@ -86,56 +89,14 @@ public class ScheduledJobInfoImpl implem
*/
@Override
public Date getNextScheduledExecution() {
- final Calendar now = Calendar.getInstance();
- switch ( this.scheduleInfo.getScheduleType() ) {
- case DATE : return this.scheduleInfo.getAt();
- case DAILY : final Calendar next = Calendar.getInstance();
- next.set(Calendar.HOUR_OF_DAY, this.getHourOfDay());
- next.set(Calendar.MINUTE, this.getMinuteOfHour());
- if ( next.before(now) ) {
- next.add(Calendar.DAY_OF_WEEK, 1);
- }
- return next.getTime();
- case WEEKLY : final Calendar nextW = Calendar.getInstance();
- nextW.set(Calendar.HOUR_OF_DAY, this.getHourOfDay());
- nextW.set(Calendar.MINUTE, this.getMinuteOfHour());
- nextW.set(Calendar.DAY_OF_WEEK, this.getDayOfWeek());
- if ( nextW.before(now) ) {
- nextW.add(Calendar.WEEK_OF_YEAR, 1);
- }
- return nextW.getTime();
- case HOURLY : final Calendar nextH = Calendar.getInstance();
- nextH.set(Calendar.MINUTE, this.getMinuteOfHour());
- if ( nextH.before(now) ) {
- nextH.add(Calendar.HOUR_OF_DAY, 1);
- }
- return nextH.getTime();
+ Date result = null;
+ for(final ScheduleInfo info : this.scheduleInfos) {
+ final Date newResult = ((ScheduleInfoImpl)info).getNextScheduledExecution();
+ if ( result == null || result.getTime() > newResult.getTime() ) {
+ result = newResult;
+ }
}
- return null;
- }
-
- /**
- * @see org.apache.sling.event.jobs.ScheduledJobInfo#getDayOfWeek()
- */
- @Override
- public int getDayOfWeek() {
- return this.scheduleInfo.getDayOfWeek();
- }
-
- /**
- * @see org.apache.sling.event.jobs.ScheduledJobInfo#getHourOfDay()
- */
- @Override
- public int getHourOfDay() {
- return this.scheduleInfo.getHourOfDay();
- }
-
- /**
- * @see org.apache.sling.event.jobs.ScheduledJobInfo#getMinuteOfHour()
- */
- @Override
- public int getMinuteOfHour() {
- return this.scheduleInfo.getMinuteOfHour();
+ return result;
}
/**
@@ -212,32 +173,4 @@ public class ScheduledJobInfoImpl implem
public String getSchedulerJobId() {
return Job.class.getName() + ":" + this.scheduleName;
}
-
- /**
- * If the job is scheduled daily or weekly, return the cron expression
- */
- public String getCronExpression() {
- if ( this.scheduleInfo.getScheduleType() == ScheduleType.DAILY ) {
- final StringBuilder sb = new StringBuilder("0 ");
- sb.append(this.scheduleInfo.getMinuteOfHour());
- sb.append(' ');
- sb.append(this.scheduleInfo.getHourOfDay());
- sb.append(" * * *");
- return sb.toString();
- } else if ( this.scheduleInfo.getScheduleType() == ScheduleType.WEEKLY ) {
- final StringBuilder sb = new StringBuilder("0 ");
- sb.append(this.scheduleInfo.getMinuteOfHour());
- sb.append(' ');
- sb.append(this.scheduleInfo.getHourOfDay());
- sb.append(" * * ");
- sb.append(this.scheduleInfo.getDayOfWeek());
- return sb.toString();
- } else if ( this.scheduleInfo.getScheduleType() == ScheduleType.HOURLY ) {
- final StringBuilder sb = new StringBuilder("0 ");
- sb.append(this.scheduleInfo.getMinuteOfHour());
- sb.append(" * * * *");
- return sb.toString();
- }
- return null;
- }
}
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/Utility.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/Utility.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/Utility.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/Utility.java Wed Oct 9 17:28:25 2013
@@ -25,6 +25,7 @@ import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
+import org.apache.sling.event.impl.support.ResourceHelper;
import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.JobUtil;
import org.apache.sling.event.jobs.consumer.JobConsumer;
@@ -169,9 +170,9 @@ public abstract class Utility {
final Map<String, Object> eventProps = new HashMap<String, Object>();
eventProps.putAll(((JobImpl)job).getProperties());
if ( job.getName() != null ) {
- eventProps.put(JobUtil.PROPERTY_JOB_NAME, job.getName());
+ eventProps.put(ResourceHelper.PROPERTY_JOB_NAME, job.getName());
}
- eventProps.put(JobUtil.JOB_ID, job.getId());
+ eventProps.put(ResourceHelper.PROPERTY_JOB_ID, job.getId());
eventProps.remove(JobConsumer.PROPERTY_JOB_ASYNC_HANDLER);
return new Event(job.getTopic(), eventProps);
}
@@ -185,9 +186,9 @@ public abstract class Utility {
sb.append(", properties=");
boolean first = true;
for(final String propName : properties.keySet()) {
- if ( propName.equals(JobUtil.JOB_ID)
- || propName.equals(JobUtil.PROPERTY_JOB_NAME)
- || propName.equals(JobUtil.PROPERTY_JOB_TOPIC) ) {
+ if ( propName.equals(ResourceHelper.PROPERTY_JOB_ID)
+ || propName.equals(ResourceHelper.PROPERTY_JOB_NAME)
+ || propName.equals(ResourceHelper.PROPERTY_JOB_TOPIC) ) {
continue;
}
if ( first ) {
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/console/WebConsolePlugin.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/console/WebConsolePlugin.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/console/WebConsolePlugin.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/console/WebConsolePlugin.java Wed Oct 9 17:28:25 2013
@@ -44,6 +44,7 @@ import org.apache.sling.event.impl.jobs.
import org.apache.sling.event.impl.jobs.TopologyCapabilities;
import org.apache.sling.event.impl.jobs.config.InternalQueueConfiguration;
import org.apache.sling.event.impl.jobs.config.QueueConfigurationManager;
+import org.apache.sling.event.impl.support.ResourceHelper;
import org.apache.sling.event.jobs.JobManager;
import org.apache.sling.event.jobs.JobUtil;
import org.apache.sling.event.jobs.Queue;
@@ -183,9 +184,9 @@ public class WebConsolePlugin extends Ht
private Event getTestEvent(final String id) {
final Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put(JobUtil.PROPERTY_JOB_TOPIC, SLING_WEBCONSOLE_TEST_JOB_TOPIC);
+ props.put(ResourceHelper.PROPERTY_JOB_TOPIC, SLING_WEBCONSOLE_TEST_JOB_TOPIC);
if ( id != null ) {
- props.put(JobUtil.PROPERTY_JOB_NAME, id);
+ props.put(ResourceHelper.PROPERTY_JOB_NAME, id);
}
return new Event(JobUtil.TOPIC_JOB, props);
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/deprecated/EventAdminBridge.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/deprecated/EventAdminBridge.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/deprecated/EventAdminBridge.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/deprecated/EventAdminBridge.java Wed Oct 9 17:28:25 2013
@@ -35,6 +35,7 @@ import org.apache.sling.event.EventUtil;
import org.apache.sling.event.impl.jobs.JobImpl;
import org.apache.sling.event.impl.jobs.Utility;
import org.apache.sling.event.impl.support.Environment;
+import org.apache.sling.event.impl.support.ResourceHelper;
import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.JobManager;
import org.apache.sling.event.jobs.JobUtil;
@@ -154,8 +155,8 @@ public class EventAdminBridge
this.ignoreException(ie);
}
} else {
- final String jobTopic = (String)event.getProperty(JobUtil.PROPERTY_JOB_TOPIC);
- final String jobName = (String)event.getProperty(JobUtil.PROPERTY_JOB_NAME);
+ final String jobTopic = (String)event.getProperty(ResourceHelper.PROPERTY_JOB_TOPIC);
+ final String jobName = (String)event.getProperty(ResourceHelper.PROPERTY_JOB_NAME);
final Map<String, Object> props = new EventPropertiesMap(event);
props.put(JobImpl.PROPERTY_BRIDGED_EVENT, Boolean.TRUE);
@@ -187,7 +188,7 @@ public class EventAdminBridge
logger.debug("Handling local job {}", EventUtil.toString(event));
}
// check job topic
- final String errorMessage = Utility.checkJobTopic(event.getProperty(JobUtil.PROPERTY_JOB_TOPIC));
+ final String errorMessage = Utility.checkJobTopic(event.getProperty(ResourceHelper.PROPERTY_JOB_TOPIC));
if ( errorMessage == null ) {
try {
this.writeQueue.put(event);
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/deprecated/JobStatusProviderImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/deprecated/JobStatusProviderImpl.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/deprecated/JobStatusProviderImpl.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/deprecated/JobStatusProviderImpl.java Wed Oct 9 17:28:25 2013
@@ -29,9 +29,9 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.event.JobStatusProvider;
import org.apache.sling.event.JobsIterator;
+import org.apache.sling.event.impl.support.ResourceHelper;
import org.apache.sling.event.jobs.JobManager;
import org.apache.sling.event.jobs.JobManager.QueryType;
-import org.apache.sling.event.jobs.JobUtil;
import org.apache.sling.event.jobs.Queue;
import org.osgi.service.event.Event;
@@ -57,9 +57,9 @@ public class JobStatusProviderImpl
public boolean removeJob(final String topic, final String jobId) {
if ( jobId != null && topic != null ) {
final Event job = this.jobManager.findJob(topic,
- Collections.singletonMap(JobUtil.PROPERTY_JOB_NAME, (Object)jobId));
+ Collections.singletonMap(ResourceHelper.PROPERTY_JOB_NAME, (Object)jobId));
if ( job != null ) {
- return this.removeJob((String)job.getProperty(JobUtil.JOB_ID));
+ return this.removeJob((String)job.getProperty(ResourceHelper.PROPERTY_JOB_ID));
}
}
return true;
@@ -81,9 +81,9 @@ public class JobStatusProviderImpl
public void forceRemoveJob(final String topic, final String jobId) {
if ( jobId != null && topic != null ) {
final Event job = this.jobManager.findJob(topic,
- Collections.singletonMap(JobUtil.PROPERTY_JOB_NAME, (Object)jobId));
+ Collections.singletonMap(ResourceHelper.PROPERTY_JOB_NAME, (Object)jobId));
if ( job != null ) {
- this.forceRemoveJob((String)job.getProperty(JobUtil.JOB_ID));
+ this.forceRemoveJob((String)job.getProperty(ResourceHelper.PROPERTY_JOB_ID));
}
}
}
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/AbstractJobQueue.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/AbstractJobQueue.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/AbstractJobQueue.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/AbstractJobQueue.java Wed Oct 9 17:28:25 2013
@@ -39,6 +39,7 @@ import org.apache.sling.event.impl.jobs.
import org.apache.sling.event.impl.jobs.deprecated.JobStatusNotifier;
import org.apache.sling.event.impl.jobs.stats.StatisticsImpl;
import org.apache.sling.event.impl.support.Environment;
+import org.apache.sling.event.impl.support.ResourceHelper;
import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.JobUtil;
import org.apache.sling.event.jobs.Queue;
@@ -276,7 +277,7 @@ public abstract class AbstractJobQueue
*/
@Override
public boolean sendAcknowledge(final Event job) {
- final String jobId = (String)job.getProperty(JobUtil.JOB_ID);
+ final String jobId = (String)job.getProperty(ResourceHelper.PROPERTY_JOB_ID);
final JobHandler ack;
synchronized ( this.startedJobsLists ) {
ack = this.startedJobsLists.remove(jobId);
@@ -350,7 +351,7 @@ public abstract class AbstractJobQueue
*/
@Override
public boolean finishedJob(final Event job, final boolean shouldReschedule) {
- final String location = (String)job.getProperty(JobUtil.JOB_ID);
+ final String location = (String)job.getProperty(ResourceHelper.PROPERTY_JOB_ID);
return this.finishedJob(location, shouldReschedule ? JobStatus.FAILED : JobStatus.SUCCEEDED, false);
}
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/timed/ScheduleInfo.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/timed/ScheduleInfo.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/timed/ScheduleInfo.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/timed/ScheduleInfo.java Wed Oct 9 17:28:25 2013
@@ -67,7 +67,7 @@ final class ScheduleInfo implements Seri
}
final String id = (String)event.getProperty(EventUtil.PROPERTY_TIMED_EVENT_ID);
- final String jId = (String)event.getProperty(JobUtil.PROPERTY_JOB_NAME);
+ final String jId = (String)event.getProperty(ResourceHelper.PROPERTY_JOB_NAME);
this.jobId = getJobId(topic, id, jId);
}
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/timed/TimedEventSender.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/timed/TimedEventSender.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/timed/TimedEventSender.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/timed/TimedEventSender.java Wed Oct 9 17:28:25 2013
@@ -22,6 +22,7 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
+import java.util.Date;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
@@ -29,7 +30,6 @@ import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -53,6 +53,7 @@ import org.apache.sling.api.resource.Res
import org.apache.sling.api.resource.ValueMap;
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.apache.sling.discovery.TopologyEvent;
import org.apache.sling.discovery.TopologyEvent.Type;
@@ -143,11 +144,7 @@ public class TimedEventSender
final Scheduler localScheduler = this.scheduler;
if ( localScheduler != null ) {
for(final String id : this.startedSchedulerJobs ) {
- try {
- localScheduler.removeJob(id);
- } catch ( final NoSuchElementException nsee ) {
- this.ignoreException(nsee);
- }
+ localScheduler.unschedule(id);
}
}
this.startedSchedulerJobs.clear();
@@ -227,12 +224,7 @@ public class TimedEventSender
final String jobId = ResourceUtil.getName(path);
this.startedSchedulerJobs.remove(jobId);
logger.debug("Stopping job with id : {}", jobId);
- try {
- this.scheduler.removeJob(jobId);
- } catch (final NoSuchElementException nsee) {
- // this can happen if the job is scheduled on another node
- // so we can just ignore this
- }
+ this.scheduler.unschedule(jobId);
event = null;
} else if ( !Utility.TOPIC_STOPPED.equals(event.getTopic()) ) {
@@ -275,12 +267,7 @@ public class TimedEventSender
this.logger.debug("Stopping timed event " + event.getProperty(EventUtil.PROPERTY_TIMED_EVENT_TOPIC) + "(" + scheduleInfo.jobId + ")");
}
this.startedSchedulerJobs.remove(scheduleInfo.jobId);
- try {
- localScheduler.removeJob(scheduleInfo.jobId);
- } catch (final NoSuchElementException nsee) {
- // this can happen if the job is scheduled on another node
- // so we can just ignore this
- }
+ localScheduler.unschedule(scheduleInfo.jobId);
return true;
}
@@ -298,29 +285,28 @@ public class TimedEventSender
config.put(JOB_CONFIG, properties);
config.put(JOB_SCHEDULE_INFO, scheduleInfo);
- try {
- if ( scheduleInfo.expression != null ) {
- if ( this.logger.isDebugEnabled() ) {
- this.logger.debug("Adding timed event " + config.get(JOB_TOPIC) + "(" + scheduleInfo.jobId + ")" + " with cron expression " + scheduleInfo.expression);
- }
- localScheduler.addJob(scheduleInfo.jobId, this, config, scheduleInfo.expression, false);
- } else if ( scheduleInfo.period != null ) {
- if ( this.logger.isDebugEnabled() ) {
- this.logger.debug("Adding timed event " + config.get(JOB_TOPIC) + "(" + scheduleInfo.jobId + ")" + " with period " + scheduleInfo.period);
- }
- localScheduler.addPeriodicJob(scheduleInfo.jobId, this, config, scheduleInfo.period, false);
- } else {
- // then it must be date
- if ( this.logger.isDebugEnabled() ) {
- this.logger.debug("Adding timed event " + config.get(JOB_TOPIC) + "(" + scheduleInfo.jobId + ")" + " with date " + scheduleInfo.date);
- }
- localScheduler.fireJobAt(scheduleInfo.jobId, this, config, scheduleInfo.date);
+ final ScheduleOptions options;
+ if ( scheduleInfo.expression != null ) {
+ if ( this.logger.isDebugEnabled() ) {
+ this.logger.debug("Adding timed event " + config.get(JOB_TOPIC) + "(" + scheduleInfo.jobId + ")" + " with cron expression " + scheduleInfo.expression);
}
- this.startedSchedulerJobs.add(scheduleInfo.jobId);
- return true;
- } catch (final Exception e) {
- this.ignoreException(e);
+ options = localScheduler.EXPR(scheduleInfo.expression);
+ } else if ( scheduleInfo.period != null ) {
+ if ( this.logger.isDebugEnabled() ) {
+ this.logger.debug("Adding timed event " + config.get(JOB_TOPIC) + "(" + scheduleInfo.jobId + ")" + " with period " + scheduleInfo.period);
+ }
+ final Date startDate = new Date(System.currentTimeMillis() + scheduleInfo.period * 1000);
+ options = localScheduler.AT(startDate, -1, scheduleInfo.period);
+ } else {
+ // then it must be date
+ if ( this.logger.isDebugEnabled() ) {
+ this.logger.debug("Adding timed event " + config.get(JOB_TOPIC) + "(" + scheduleInfo.jobId + ")" + " with date " + scheduleInfo.date);
+ }
+ options = localScheduler.AT(scheduleInfo.date);
}
+ localScheduler.schedule(this, options.canRunConcurrently(false).name(scheduleInfo.jobId).config(config));
+ this.startedSchedulerJobs.add(scheduleInfo.jobId);
+ return true;
} else {
this.logger.error("No scheduler available to start timed event " + event);
}
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ResourceHelper.java Wed Oct 9 17:28:25 2013
@@ -38,6 +38,7 @@ import org.apache.sling.event.impl.jobs.
import org.apache.sling.event.impl.jobs.deprecated.JobStatusNotifier;
import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.JobUtil;
+import org.apache.sling.event.jobs.ScheduleInfo;
import org.apache.sling.event.jobs.consumer.JobConsumer;
import org.osgi.service.event.EventConstants;
@@ -60,13 +61,17 @@ public abstract class ResourceHelper {
public static final String PROPERTY_SCHEDULE_INFO = "slingevent:scheduleInfo";
public static final String PROPERTY_SCHEDULE_SUSPENDED = "slingevent:scheduleSuspended";
+ public static final String PROPERTY_JOB_ID = "slingevent:eventId";
+ public static final String PROPERTY_JOB_NAME = "event.job.id";
+ public static final String PROPERTY_JOB_TOPIC = "event.job.topic";
+
/** List of ignored properties to write to the repository. */
@SuppressWarnings("deprecation")
private static final String[] IGNORE_PROPERTIES = new String[] {
EventUtil.PROPERTY_DISTRIBUTE,
EventUtil.PROPERTY_APPLICATION,
EventConstants.EVENT_TOPIC,
- JobUtil.JOB_ID,
+ ResourceHelper.PROPERTY_JOB_ID,
JobUtil.PROPERTY_JOB_PARALLEL,
JobUtil.PROPERTY_JOB_RUN_LOCAL,
JobUtil.PROPERTY_JOB_QUEUE_ORDERED,
@@ -159,11 +164,22 @@ public abstract class ResourceHelper {
final Map<String, Object> result = new HashMap<String, Object>(vm);
for(final Map.Entry<String, Object> entry : result.entrySet()) {
if ( entry.getKey().equals(PROPERTY_SCHEDULE_INFO) ) {
- final ScheduleInfo info = ScheduleInfo.deserialize(entry.getValue().toString());
- if ( info == null ) {
+ final String[] infoArray = vm.get(entry.getKey(), String[].class);
+ if ( infoArray == null || infoArray.length == 0 ) {
hasReadError.add(new Exception("Unable to deserialize property '" + entry.getKey() + "'"));
} else {
- entry.setValue(info);
+ final List<ScheduleInfo> infos = new ArrayList<ScheduleInfo>();
+ for(final String i : infoArray) {
+ final ScheduleInfoImpl info = ScheduleInfoImpl.deserialize(i);
+ if ( info != null ) {
+ infos.add(info);
+ }
+ }
+ if ( infos.size() < infoArray.length ) {
+ hasReadError.add(new Exception("Unable to deserialize property '" + entry.getKey() + "'"));
+ } else {
+ entry.setValue(infos);
+ }
}
}
if ( entry.getValue() instanceof InputStream ) {
Copied: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ScheduleInfoImpl.java (from r1530653, sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ScheduleInfo.java)
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ScheduleInfoImpl.java?p2=sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ScheduleInfoImpl.java&p1=sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ScheduleInfo.java&r1=1530653&r2=1530723&rev=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ScheduleInfo.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/support/ScheduleInfoImpl.java Wed Oct 9 17:28:25 2013
@@ -19,31 +19,33 @@
package org.apache.sling.event.impl.support;
import java.io.Serializable;
+import java.util.Calendar;
import java.util.Date;
+import java.util.List;
-import org.apache.sling.event.jobs.ScheduledJobInfo.ScheduleType;
+import org.apache.sling.event.jobs.ScheduleInfo;
-public class ScheduleInfo implements Serializable {
+public class ScheduleInfoImpl implements ScheduleInfo, Serializable {
private static final long serialVersionUID = 1L;
/** Serialization version. */
private static final String VERSION = "1";
- public static ScheduleInfo HOURLY(final int minutes) {
- return new ScheduleInfo(ScheduleType.HOURLY, -1, -1, minutes, null);
+ public static ScheduleInfoImpl HOURLY(final int minutes) {
+ return new ScheduleInfoImpl(ScheduleType.HOURLY, -1, -1, minutes, null);
}
- public static ScheduleInfo AT(final Date at) {
- return new ScheduleInfo(ScheduleType.DATE, -1, -1, -1, at);
+ public static ScheduleInfoImpl AT(final Date at) {
+ return new ScheduleInfoImpl(ScheduleType.DATE, -1, -1, -1, at);
}
- public static ScheduleInfo WEEKLY(final int day, final int hour, final int minute) {
- return new ScheduleInfo(ScheduleType.WEEKLY, day, hour, minute, null);
+ public static ScheduleInfoImpl WEEKLY(final int day, final int hour, final int minute) {
+ return new ScheduleInfoImpl(ScheduleType.WEEKLY, day, hour, minute, null);
}
- public static ScheduleInfo DAYLY(final int hour, final int minute) {
- return new ScheduleInfo(ScheduleType.DAILY, -1, hour, minute, null);
+ public static ScheduleInfoImpl DAYLY(final int hour, final int minute) {
+ return new ScheduleInfoImpl(ScheduleType.DAYLY, -1, hour, minute, null);
}
private final ScheduleType scheduleType;
@@ -56,7 +58,7 @@ public class ScheduleInfo implements Ser
private final Date at;
- private ScheduleInfo(final ScheduleType scheduleType,
+ private ScheduleInfoImpl(final ScheduleType scheduleType,
final int dayOfWeek,
final int hourOfDay,
final int minuteOfHour,
@@ -68,11 +70,11 @@ public class ScheduleInfo implements Ser
this.at = at;
}
- public static ScheduleInfo deserialize(final String s) {
+ public static ScheduleInfoImpl deserialize(final String s) {
final String[] parts = s.split(":");
if ( parts.length == 6 && parts[0].equals(VERSION) ) {
try {
- return new ScheduleInfo(ScheduleType.valueOf(parts[1]),
+ return new ScheduleInfoImpl(ScheduleType.valueOf(parts[1]),
Integer.parseInt(parts[2]),
Integer.parseInt(parts[3]),
Integer.parseInt(parts[4]),
@@ -103,23 +105,109 @@ public class ScheduleInfo implements Ser
return sb.toString();
}
- public Date getAt() {
- return this.at;
+ @Override
+ public ScheduleType getType() {
+ return this.scheduleType;
}
- public ScheduleType getScheduleType() {
- return this.scheduleType;
+ @Override
+ public Date getAt() {
+ return this.at;
}
+ @Override
public int getDayOfWeek() {
return this.dayOfWeek;
}
+ @Override
public int getHourOfDay() {
return this.hourOfDay;
}
+ @Override
public int getMinuteOfHour() {
return this.minuteOfHour;
}
+
+ public void check(final List<String> errors) {
+ switch ( this.scheduleType ) {
+ case DAYLY : if ( hourOfDay < 0 || hourOfDay > 23 || minuteOfHour < 0 || minuteOfHour > 59 ) {
+ errors.add("Wrong time information : " + minuteOfHour + ":" + minuteOfHour);
+ }
+ break;
+ case DATE : if ( at == null || at.getTime() <= System.currentTimeMillis() + 2000 ) {
+ errors.add("Date must be in the future : " + at);
+ }
+ break;
+ case HOURLY : if ( minuteOfHour < 0 || minuteOfHour > 59 ) {
+ errors.add("Minute must be between 0 and 59 : " + minuteOfHour);
+ }
+ break;
+ case WEEKLY : if ( hourOfDay < 0 || hourOfDay > 23 || minuteOfHour < 0 || minuteOfHour > 59 ) {
+ errors.add("Wrong time information : " + minuteOfHour + ":" + minuteOfHour);
+ }
+ if ( dayOfWeek < 1 || dayOfWeek > 7 ) {
+ errors.add("Day must be between 1 and 7 : " + dayOfWeek);
+ }
+ break;
+ }
+ }
+
+ public Date getNextScheduledExecution() {
+ final Calendar now = Calendar.getInstance();
+ switch ( this.scheduleType ) {
+ case DATE : return this.at;
+ case DAYLY : final Calendar next = Calendar.getInstance();
+ next.set(Calendar.HOUR_OF_DAY, this.hourOfDay);
+ next.set(Calendar.MINUTE, this.minuteOfHour);
+ if ( next.before(now) ) {
+ next.add(Calendar.DAY_OF_WEEK, 1);
+ }
+ return next.getTime();
+ case WEEKLY : final Calendar nextW = Calendar.getInstance();
+ nextW.set(Calendar.HOUR_OF_DAY, this.hourOfDay);
+ nextW.set(Calendar.MINUTE, this.minuteOfHour);
+ nextW.set(Calendar.DAY_OF_WEEK, this.dayOfWeek);
+ if ( nextW.before(now) ) {
+ nextW.add(Calendar.WEEK_OF_YEAR, 1);
+ }
+ return nextW.getTime();
+ case HOURLY : final Calendar nextH = Calendar.getInstance();
+ nextH.set(Calendar.MINUTE, this.minuteOfHour);
+ if ( nextH.before(now) ) {
+ nextH.add(Calendar.HOUR_OF_DAY, 1);
+ }
+ return nextH.getTime();
+ }
+ return null;
+ }
+
+ /**
+ * If the job is scheduled daily or weekly, return the cron expression
+ */
+ public String getCronExpression() {
+ if ( this.scheduleType == ScheduleType.DAYLY ) {
+ final StringBuilder sb = new StringBuilder("0 ");
+ sb.append(String.valueOf(this.minuteOfHour));
+ sb.append(' ');
+ sb.append(String.valueOf(this.hourOfDay));
+ sb.append(" * * *");
+ return sb.toString();
+ } else if ( this.scheduleType == ScheduleType.WEEKLY ) {
+ final StringBuilder sb = new StringBuilder("0 ");
+ sb.append(String.valueOf(this.minuteOfHour));
+ sb.append(' ');
+ sb.append(String.valueOf(this.hourOfDay));
+ sb.append(" * * ");
+ sb.append(String.valueOf(this.dayOfWeek));
+ return sb.toString();
+ } else if ( this.scheduleType == ScheduleType.HOURLY ) {
+ final StringBuilder sb = new StringBuilder("0 ");
+ sb.append(String.valueOf(this.minuteOfHour));
+ sb.append(" * * * *");
+ return sb.toString();
+ }
+ return null;
+ }
}
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/JobBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/JobBuilder.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/JobBuilder.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/JobBuilder.java Wed Oct 9 17:28:25 2013
@@ -19,6 +19,7 @@
package org.apache.sling.event.jobs;
import java.util.Date;
+import java.util.List;
import java.util.Map;
import aQute.bnd.annotation.ProviderType;
@@ -44,12 +45,20 @@ public interface JobBuilder {
/**
* Add the job.
- * @see JobManager#addJob(String, Map)
* @return The job or <code>null</code>
+ * @see JobManager#addJob(String, Map)
*/
Job add();
/**
+ * Add the job.
+ * @param errors Optional list which will be filled with error messages.
+ * @return The job or <code>null</code>
+ * @see JobManager#addJob(String, Map)
+ */
+ Job add(final List<String> errors);
+
+ /**
* Schedule the job
* If a job scheduler with the same name already exists, it is updated
* with the new information.
@@ -59,46 +68,83 @@ public interface JobBuilder {
*/
ScheduleBuilder schedule(final String name);
+ public interface ScheduleBuilderAdder {
+
+ /**
+ * Finally add the job to the schedule
+ * @return Returns the info object if the job could be scheduled, <code>null</code>otherwise.
+ */
+ ScheduledJobInfo add();
+
+ /**
+ * Finally add the job to the schedule
+ * @param errors Optional list which will be filled with error messages.
+ * @return Returns the info object if the job could be scheduled, <code>null</code>otherwise.
+ */
+ ScheduledJobInfo add(final List<String> errors);
+ }
+
/**
* This is a builder interface for creating schedule information
*/
public interface ScheduleBuilder {
/**
- * Suspend this scheduling by default
+ * Suspend this scheduling by default.
+ * Invoking this method several times has the same effect as calling it just once.
*/
- ScheduleBuilder suspend(final boolean flag);
+ ScheduleBuilder suspend();
/**
* Schedule the job hourly at the given minute.
* If the minutes argument is less than 0 or higher than 59, the job can't be scheduled.
- * @param minutes Between 0 and 59.
- * @return <code>true</code> if the job could be scheduled, <code>false</code>otherwise.
+ * @param minute Between 0 and 59.
*/
- boolean hourly(final int minutes);
+ MinuteBuilder hourly(final int minute);
/**
- * Schedule the job daily, the time needs to be specified in addition.
+ * Schedule the job daily at the given time.
+ * If a value less than zero for hour or minute is specified or a value higher than 23 for hour or
+ * a value higher than 59 for minute than the job can't be scheduled.
+ * @param hour Hour of the day ranging from 0 to 23.
+ * @param minute Minute of the hour ranging from 0 to 59.
*/
- TimeBuilder daily();
+ DayBuilder dayly(final int hour, final int minute);
/**
* Schedule the job weekly, the time needs to be specified in addition.
- * If a value lower than 1 or higher than 7 is used, the job can't be scheduled.
+ * If a value lower than 1 or higher than 7 is used for the day, the job can't be scheduled.
+ * If a value less than zero for hour or minute is specified or a value higher than 23 for hour or
+ * a value higher than 59 for minute than the job can't be scheduled.
* @param day Day of the week, 1:Sunday, 2:Monday, ... 7:Saturday.
+ * @param hour Hour of the day ranging from 0 to 23.
+ * @param minute Minute of the hour ranging from 0 to 59.
*/
- TimeBuilder weekly(final int day);
+ WeekBuilder weekly(final int day, final int hour, final int minute);
/**
* Schedule the job for a specific date.
* If no date or a a date in the past is provided, the job can't be scheduled.
* @param date The date
- * @return <code>true</code> if the job could be scheduled, <code>false</code>otherwise.
*/
- boolean at(final Date date);
+ DateBuilder at(final Date date);
}
- public interface TimeBuilder {
+ public interface WeekBuilder extends ScheduleBuilderAdder {
+
+ /**
+ * Schedule the job for the given day, hour and minute.
+ * If a value lower than 1 or higher than 7 is used for the day, the job can't be scheduled.
+ * If a value less than zero for hour or minute is specified or a value higher than 23 for hour or
+ * a value higher than 59 for minute than the job can't be scheduled.
+ * @param day Day of the week, 1:Sunday, 2:Monday, ... 7:Saturday.
+ * @param hour Hour of the day ranging from 0 to 23.
+ * @param minute Minute of the hour ranging from 0 to 59.
+ */
+ WeekBuilder at(final int day, final int hour, final int minute);
+ }
+
+ public interface DayBuilder extends ScheduleBuilderAdder {
/**
* Schedule the job for the given hour and minute.
@@ -106,8 +152,27 @@ public interface JobBuilder {
* a value higher than 59 for minute than the job can't be scheduled.
* @param hour Hour of the day ranging from 0 to 23.
* @param minute Minute of the hour ranging from 0 to 59.
- * @return <code>true</code> if the job could be scheduled, <code>false</code>otherwise.
*/
- boolean at(final int hour, final int minute);
+ DayBuilder at(final int hour, final int minute);
+ }
+
+ public interface DateBuilder extends ScheduleBuilderAdder {
+
+ /**
+ * Schedule the job for a specific date.
+ * If no date or a a date in the past is provided, the job can't be scheduled.
+ * @param date The date
+ */
+ DateBuilder at(final Date date);
+ }
+
+ public interface MinuteBuilder extends ScheduleBuilderAdder {
+
+ /**
+ * Schedule the job hourly at the given minute.
+ * If the minutes argument is less than 0 or higher than 59, the job can't be scheduled.
+ * @param minute Between 0 and 59.
+ */
+ MinuteBuilder at(final int minute);
}
}
\ No newline at end of file
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/JobManager.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/JobManager.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/JobManager.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/JobManager.java Wed Oct 9 17:28:25 2013
@@ -88,6 +88,9 @@ public interface JobManager {
* The returned job object is a snapshot of the job state taken at the time of creation. Updates
* to the job state are not reflected and the client needs to get a new job object using the job id.
*
+ * If the queue for processing this job is configured to drop the job, <code>null</code> is returned
+ * as well.
+ *
* @param topic The required job topic.
* @param properties Optional job properties. The properties must be serializable.
* @return The new job - or <code>null</code> if the job could not be created.
@@ -113,6 +116,9 @@ public interface JobManager {
* The returned job object is a snapshot of the job state taken at the time of creation. Updates
* to the job state are not reflected and the client needs to get a new job object using the job id.
*
+ * If the queue for processing this job is configured to drop the job, <code>null</code> is returned
+ * as well.
+ *
* @param topic The required job topic.
* @param name Optional unique job name
* @param properties Optional job properties. The properties must be serializable.
Added: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/ScheduleInfo.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/ScheduleInfo.java?rev=1530723&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/ScheduleInfo.java (added)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/ScheduleInfo.java Wed Oct 9 17:28:25 2013
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache 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://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.sling.event.jobs;
+
+import java.util.Date;
+
+import aQute.bnd.annotation.ProviderType;
+
+/**
+ * Scheduling information.
+ * @since 1.3
+ */
+@ProviderType
+public interface ScheduleInfo {
+
+ enum ScheduleType {
+ DATE, // scheduled for a date
+ HOURLY, // scheduled hourly
+ DAYLY, // scheduled once a day
+ WEEKLY // scheduled once a week
+ }
+
+ /**
+ * Return the scheduling type
+ * @return The scheduling type
+ */
+ ScheduleType getType();
+
+ /**
+ * Return the scheduled execution date for a schedule of type date.
+ */
+ Date getAt();
+
+ /**
+ * If the job is scheduled weekly, returns the day of the week
+ * @return The day of the week (from 1 to 7) or -1
+ */
+ int getDayOfWeek();
+
+ /**
+ * Return the hour of the day for daily and weekly scheduled jobs
+ * @return The hour of the day (from 0 to 23) or -1
+ */
+ int getHourOfDay();
+
+ /**
+ * Return the minute of the hour for daily, weekly and hourly scheduled jobs.
+ * @return The minute of the hour (from 0 to 59) or -1
+ */
+ int getMinuteOfHour();
+}
Propchange: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/ScheduleInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/ScheduleInfo.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/ScheduleInfo.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/ScheduledJobInfo.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/ScheduledJobInfo.java?rev=1530723&r1=1530722&r2=1530723&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/ScheduledJobInfo.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/ScheduledJobInfo.java Wed Oct 9 17:28:25 2013
@@ -18,6 +18,7 @@
*/
package org.apache.sling.event.jobs;
+import java.util.Collection;
import java.util.Date;
import java.util.Map;
@@ -30,13 +31,6 @@ import aQute.bnd.annotation.ProviderType
@ProviderType
public interface ScheduledJobInfo {
- enum ScheduleType {
- DATE, // scheduled for a date
- HOURLY, // scheduled hourly
- DAILY, // scheduled once a day
- WEEKLY // scheduled once a week
- }
-
/**
* Return the unique scheduling name.
* @return The unique name
@@ -44,10 +38,10 @@ public interface ScheduledJobInfo {
String getName();
/**
- * Return the scheduling type
- * @return The scheduling type
+ * Get all schedules for this job
+ * @return A non null and non empty list of schedules.
*/
- ScheduleType getScheduleType();
+ Collection<ScheduleInfo> getSchedules();
/**
* Return the next scheduled execution date.
@@ -55,24 +49,6 @@ public interface ScheduledJobInfo {
Date getNextScheduledExecution();
/**
- * If the job is scheduled weekly, returns the day of the week
- * @return The day of the week (from 1 to 7) or -1
- */
- int getDayOfWeek();
-
- /**
- * Return the hour of the day for daily and weekly scheduled jobs
- * @return The hour of the day (from 0 to 23) or -1
- */
- int getHourOfDay();
-
- /**
- * Return the minute of the hour for daily, weekly and hourly scheduled jobs.
- * @return The minute of the hour (from 0 to 59) or -1
- */
- int getMinuteOfHour();
-
- /**
* Return the job topic.
* @return The job topic
*/