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/07 15:14:36 UTC
svn commit: r1529835 - in /sling/trunk/bundles/extensions/event/src:
main/java/org/apache/sling/event/impl/jobs/
main/java/org/apache/sling/event/impl/support/
main/java/org/apache/sling/event/jobs/
test/java/org/apache/sling/event/impl/jobs/
Author: cziegeler
Date: Mon Oct 7 13:14:35 2013
New Revision: 1529835
URL: http://svn.apache.org/r1529835
Log:
SLING-3139 : Provide a way to schedule jobs
SLING-3138 : Add fluent api to create new jobs
Modified:
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobImpl.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/ScheduledJobInfoImpl.java
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/Job.java
sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/InstanceDescriptionComparatorTest.java
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobImpl.java?rev=1529835&r1=1529834&r2=1529835&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobImpl.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobImpl.java Mon Oct 7 13:14:35 2013
@@ -272,7 +272,7 @@ public class JobImpl implements Job {
return new String[] {Job.PROPERTY_JOB_PROGRESS_ETA, PROPERTY_JOB_PROGRESS_STEPS};
}
- public String setProgress(final int step) {
+ public String[] setProgress(final int step) {
final int steps = this.getProperty(Job.PROPERTY_JOB_PROGRESS_STEPS, -1);
if ( steps > 0 && step > 0 ) {
int current = this.getProperty(Job.PROPERTY_JOB_PROGRESS_STEP, 0);
@@ -282,8 +282,13 @@ public class JobImpl implements Job {
}
this.setProperty(Job.PROPERTY_JOB_PROGRESS_STEP, current);
- // TODO - recalculate ETA
- return Job.PROPERTY_JOB_PROGRESS_STEP;
+ final Calendar now = Calendar.getInstance();
+ final long elapsed = now.getTimeInMillis() - this.getProcessingStarted().getTimeInMillis();
+
+ final long eta = elapsed * steps / step;
+ now.setTimeInMillis(eta);
+ this.setProperty(Job.PROPERTY_JOB_PROGRESS_ETA, now);
+ return new String[] {Job.PROPERTY_JOB_PROGRESS_STEP, Job.PROPERTY_JOB_PROGRESS_ETA};
}
return null;
}
@@ -318,7 +323,9 @@ public class JobImpl implements Job {
public JobType getJobType() {
final String enumValue = this.getProperty(JobImpl.PROPERTY_FINISHED_STATE, String.class);
if ( enumValue == null ) {
- // TODO - find out active
+ if ( this.getProcessingStarted() != null ) {
+ return JobType.ACTIVE;
+ }
return JobType.QUEUED;
}
return JobType.valueOf(enumValue);
@@ -360,7 +367,7 @@ public class JobImpl implements Job {
* @see org.apache.sling.event.jobs.Job#getCurrentProgressStep()
*/
@Override
- public int getCurrentProgressStep() {
+ public int getFinishedProgressStep() {
return this.getProperty(Job.PROPERTY_JOB_PROGRESS_STEP, 0);
}
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=1529835&r1=1529834&r2=1529835&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 Mon Oct 7 13:14:35 2013
@@ -1441,16 +1441,20 @@ public class JobManagerImpl
return new JobBuilderImpl(this, this.logger, topic);
}
+ /**
+ * @see org.apache.sling.event.jobs.JobManager#getScheduledJobs()
+ */
@Override
public Collection<ScheduledJobInfo> getScheduledJobs() {
- // TODO Auto-generated method stub
- return null;
+ return this.jobScheduler.getScheduledJobs();
}
+ /**
+ * @see org.apache.sling.event.jobs.JobManager#getScheduledJob(java.lang.String)
+ */
@Override
- public ScheduledJobInfo getScheduledJob(String name) {
- // TODO Auto-generated method stub
- return null;
+ public ScheduledJobInfo getScheduledJob(final String name) {
+ return this.jobScheduler.getScheduledJob(name);
}
public boolean addScheduledJob(final String topic,
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=1529835&r1=1529834&r2=1529835&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 Mon Oct 7 13:14:35 2013
@@ -21,6 +21,7 @@ package org.apache.sling.event.impl.jobs
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
@@ -65,14 +66,10 @@ import org.slf4j.LoggerFactory;
/**
* A scheduler for scheduling jobs
*
- * TODO check handling of running and active flag
*/
public class JobSchedulerImpl
implements EventHandler, TopologyEventListener, org.apache.sling.commons.scheduler.Job {
- /** We use the same resource type as for timed events. */
- private static final String SCHEDULED_JOB_RESOURCE_TYPE = "slingevent:TimedEvent";
-
private static final String TOPIC_READ_JOB = "org/apache/sling/event/impl/jobs/READSCHEDULEDJOB";
private static final String PROPERTY_READ_JOB = "properties";
@@ -111,6 +108,21 @@ public class JobSchedulerImpl
this.scheduler = scheduler;
this.running = true;
this.jobManager = jobManager;
+
+ final long now = System.currentTimeMillis();
+ final Thread backgroundThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ loadScheduledJobs(now);
+ try {
+ runInBackground();
+ } catch (final Throwable t) { //NOSONAR
+ logger.error("Background thread stopped with exception: " + t.getMessage(), t);
+ running = false;
+ }
+ }
+ });
+ backgroundThread.start();
}
/**
@@ -119,25 +131,6 @@ public class JobSchedulerImpl
public void deactivate() {
this.running = false;
this.stopScheduling();
- }
-
- private void stopScheduling() {
- if ( this.active ) {
- final List<ScheduledJobInfoImpl> jobs = new ArrayList<ScheduledJobInfoImpl>();
- synchronized ( this.scheduledJobs ) {
- for(final ScheduledJobInfoImpl job : this.scheduledJobs.values() ) {
- jobs.add(job);
- }
- }
- for(final ScheduledJobInfoImpl info : jobs) {
- try {
- logger.debug("Stopping scheduled job : {}", info.getName());
- this.scheduler.removeJob(info.getSchedulerJobId());
- } catch ( final NoSuchElementException nsee ) {
- this.ignoreException(nsee);
- }
- }
- }
synchronized ( this.scheduledJobs ) {
this.scheduledJobs.clear();
}
@@ -151,21 +144,27 @@ public class JobSchedulerImpl
}
}
- private void startScheduling() {
- final long now = System.currentTimeMillis();
- final Thread backgroundThread = new Thread(new Runnable() {
- @Override
- public void run() {
- loadScheduledJobs(now);
+ private void stopScheduling() {
+ if ( this.active ) {
+ final Collection<ScheduledJobInfo> jobs = this.getScheduledJobs();
+ for(final ScheduledJobInfo info : jobs) {
try {
- runInBackground();
- } catch (final Throwable t) { //NOSONAR
- logger.error("Background thread stopped with exception: " + t.getMessage(), t);
- running = false;
+ logger.debug("Stopping scheduled job : {}", info.getName());
+ this.scheduler.removeJob(((ScheduledJobInfoImpl)info).getSchedulerJobId());
+ } catch ( final NoSuchElementException nsee ) {
+ this.ignoreException(nsee);
}
}
- });
- backgroundThread.start();
+ }
+ }
+
+ private void startScheduling() {
+ if ( this.active ) {
+ final Collection<ScheduledJobInfo> jobs = this.getScheduledJobs();
+ for(final ScheduledJobInfo info : jobs) {
+ this.startScheduledJob(((ScheduledJobInfoImpl)info));
+ }
+ }
}
/**
@@ -199,7 +198,7 @@ public class JobSchedulerImpl
final String schedulerName = (String) properties.remove(ResourceHelper.PROPERTY_SCHEDULER_NAME);
final ScheduleInfo scheduleInfo = (ScheduleInfo) properties.remove(ResourceHelper.PROPERTY_SCHEDULER_INFO);
- // and now schedule (TODO)
+ // and now schedule
final ScheduledJobInfoImpl info = new ScheduledJobInfoImpl(this, jobTopic, jobName, properties, schedulerName, scheduleInfo);
synchronized ( this.scheduledJobs ) {
this.scheduledJobs.put(ResourceHelper.filterName(schedulerName), info);
@@ -266,7 +265,8 @@ public class JobSchedulerImpl
try {
switch ( info.getScheduleType() ) {
case DAILY:
- // TODO
+ case WEEKLY:
+ this.scheduler.addJob(info.getSchedulerJobId(), this, config, info.getCronExpression(), false);
break;
case DATE:
this.scheduler.fireJobAt(info.getSchedulerJobId(), this, config, info.getNextScheduledExecution());
@@ -274,9 +274,6 @@ public class JobSchedulerImpl
case PERIODICALLY:
this.scheduler.addPeriodicJob(info.getSchedulerJobId(), this, config, info.getPeriod() * 1000, false);
break;
- case WEEKLY:
- // TODO
- break;
}
} catch (final Exception e) {
// we ignore it if scheduled fails...
@@ -414,7 +411,7 @@ public class JobSchedulerImpl
final StringBuilder buf = new StringBuilder(64);
buf.append("//element(*,");
- buf.append(SCHEDULED_JOB_RESOURCE_TYPE);
+ buf.append(ResourceHelper.RESOURCE_TYPE_SCHEDULED_JOB);
buf.append(")[@");
buf.append(ISO9075.encode(org.apache.sling.event.jobs.Job.PROPERTY_JOB_CREATED));
buf.append(" < xs:dateTime('");
@@ -595,4 +592,20 @@ public class JobSchedulerImpl
final JobBuilder builder = this.jobManager.createJob(info.getJobTopic()).name(info.getJobTopic()).properties(info.getJobProperties());
return builder.schedule(info.getName());
}
+
+ public Collection<ScheduledJobInfo> getScheduledJobs() {
+ final List<ScheduledJobInfo> jobs = new ArrayList<ScheduledJobInfo>();
+ synchronized ( this.scheduledJobs ) {
+ for(final ScheduledJobInfoImpl job : this.scheduledJobs.values() ) {
+ jobs.add(job);
+ }
+ }
+ return jobs;
+ }
+
+ 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/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=1529835&r1=1529834&r2=1529835&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 Mon Oct 7 13:14:35 2013
@@ -126,4 +126,27 @@ 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();
+ }
+ return null;
+ }
}
Modified: 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/ScheduleInfo.java?rev=1529835&r1=1529834&r2=1529835&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/ScheduleInfo.java Mon Oct 7 13:14:35 2013
@@ -18,16 +18,19 @@
*/
package org.apache.sling.event.impl.support;
+import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
import org.apache.sling.event.jobs.ScheduledJobInfo.ScheduleType;
-// TODO - implement serializing
public class ScheduleInfo implements Serializable {
private static final long serialVersionUID = 1L;
+ /** Serialization version. */
+ private static final int VERSION = 1;
+
public static ScheduleInfo PERIODIC(final int minutes) {
return new ScheduleInfo(ScheduleType.PERIODICALLY, minutes, -1, -1, -1, null);
}
@@ -44,17 +47,17 @@ public class ScheduleInfo implements Ser
return new ScheduleInfo(ScheduleType.DAILY, -1, -1, hour, minute, null);
}
- private final ScheduleType scheduleType;
+ private ScheduleType scheduleType;
- private final int period;
+ private int period;
- private final int dayOfWeek;
+ private int dayOfWeek;
- private final int hourOfDay;
+ private int hourOfDay;
- private final int minuteOfHour;
+ private int minuteOfHour;
- private final Date at;
+ private Date at;
private ScheduleInfo(final ScheduleType scheduleType,
final int period,
@@ -70,6 +73,43 @@ public class ScheduleInfo implements Ser
this.at = at;
}
+ /**
+ * Serialize the object
+ * - write version id
+ * - serialize each entry
+ * @param out Object output stream
+ * @throws IOException
+ */
+ private void writeObject(final java.io.ObjectOutputStream out)
+ throws IOException {
+ out.writeInt(VERSION);
+ out.writeObject(this.scheduleType.name());
+ out.writeInt(this.period);
+ out.writeInt(this.dayOfWeek);
+ out.writeInt(this.hourOfDay);
+ out.writeInt(this.minuteOfHour);
+ out.writeObject(this.at);
+ }
+
+ /**
+ * Deserialize the object
+ * - read version id
+ * - deserialize each entry
+ */
+ private void readObject(final java.io.ObjectInputStream in)
+ throws IOException, ClassNotFoundException {
+ final int version = in.readInt();
+ if ( version < 1 || version > VERSION ) {
+ throw new ClassNotFoundException(this.getClass().getName());
+ }
+ this.scheduleType = ScheduleType.valueOf((String)in.readObject());
+ this.period = in.readInt();
+ this.dayOfWeek = in.readInt();
+ this.hourOfDay = in.readInt();
+ this.minuteOfHour = in.readInt();
+ this.at = (Date) in.readObject();
+ }
+
public Date getAt() {
return this.at;
}
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/Job.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/Job.java?rev=1529835&r1=1529834&r2=1529835&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/Job.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/Job.java Mon Oct 7 13:14:35 2013
@@ -311,26 +311,38 @@ public interface Job {
String getResultMessage();
/**
- * TODO
+ * This method returns the optional progress log from the last job
+ * processing. The log is optional and can be set by a job consumer.
+ * @return The log or <code>null</code>
* @since 1.3
*/
String[] getProgressLog();
/**
- * TODO
+ * If the job is in processing, return the optional progress step
+ * count if available. The progress information is optional and
+ * can be set by a job consumer.
+ * @return The progress step count or <code>-1</code>.
* @since 1.3
*/
int getProgressStepCount();
/**
- * TODO
+ * If the job is in processing, return the optional information
+ * about the finished steps. This progress information is optional
+ * and can be set by a job consumer.
+ * In combination with {@link #getProgressStepCount()} this can
+ * be used to calculate a progress bar.
+ * @return The number of the finished progress step or <code>0</code>
* @since 1.3
*/
- int getCurrentProgressStep();
+ int getFinishedProgressStep();
/**
- * TODO
+ * If the job is in processing, return the optional ETA for this job.
+ * The progress information is optional and can be set by a job consumer.
* @since 1.3
+ * @return The estimated ETA or <code>null</code>
*/
Calendar getProgressETA();
}
Modified: sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/InstanceDescriptionComparatorTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/InstanceDescriptionComparatorTest.java?rev=1529835&r1=1529834&r2=1529835&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/InstanceDescriptionComparatorTest.java (original)
+++ sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/InstanceDescriptionComparatorTest.java Mon Oct 7 13:14:35 2013
@@ -155,13 +155,11 @@ public class InstanceDescriptionComparat
@Override
public InstanceDescription getLeader() {
- // TODO Auto-generated method stub
return null;
}
@Override
public List<InstanceDescription> getInstances() {
- // TODO Auto-generated method stub
return null;
}
@@ -189,13 +187,11 @@ public class InstanceDescriptionComparat
@Override
public String getProperty(String name) {
- // TODO Auto-generated method stub
return null;
}
@Override
public Map<String, String> getProperties() {
- // TODO Auto-generated method stub
return null;
}
}