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 2014/11/05 09:50:36 UTC
svn commit: r1636824 - in /sling/trunk/bundles/extensions/event/src:
main/java/org/apache/sling/event/impl/jobs/
main/java/org/apache/sling/event/impl/jobs/config/
main/java/org/apache/sling/event/impl/jobs/queues/
main/java/org/apache/sling/event/impl...
Author: cziegeler
Date: Wed Nov 5 08:50:36 2014
New Revision: 1636824
URL: http://svn.apache.org/r1636824
Log:
SLING-4133 : Allow job consumers to register for a topic and all subtopics
Added:
sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/JobConsumerManagerTest.java (with props)
Modified:
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobConsumerManager.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java
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/config/JobManagerConfiguration.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/queues/QueueJobCache.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/FindUnfinishedJobsTask.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.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/jobs/JobBuilder.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobConsumer.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobExecutionContext.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobExecutor.java
sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/package-info.java
sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/EventUtilTest.java
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobConsumerManager.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobConsumerManager.java?rev=1636824&r1=1636823&r2=1636824&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobConsumerManager.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobConsumerManager.java Wed Nov 5 08:50:36 2014
@@ -198,13 +198,23 @@ public class JobConsumerManager {
if ( consumers != null ) {
return consumers.get(0).getExecutor(this.bundleContext);
}
- final int pos = topic.lastIndexOf('/');
+ int pos = topic.lastIndexOf('/');
if ( pos > 0 ) {
final String category = topic.substring(0, pos + 1).concat("*");
final List<ConsumerInfo> categoryConsumers = this.topicToConsumerMap.get(category);
if ( categoryConsumers != null ) {
return categoryConsumers.get(0).getExecutor(this.bundleContext);
}
+
+ // search deep consumers (since 1.2 of the consumer package)
+ do {
+ final String subCategory = topic.substring(0, pos + 1).concat("**");
+ final List<ConsumerInfo> subCategoryConsumers = this.topicToConsumerMap.get(subCategory);
+ if ( subCategoryConsumers != null ) {
+ return subCategoryConsumers.get(0).getExecutor(this.bundleContext);
+ }
+ pos = topic.lastIndexOf('/', pos - 1);
+ } while ( pos > 0 );
}
}
return null;
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java?rev=1636824&r1=1636823&r2=1636824&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/JobHandler.java Wed Nov 5 08:50:36 2014
@@ -97,9 +97,10 @@ public class JobHandler {
}
/**
- * Finish a job
- * @param info The job handler
+ * Finish a job.
* @param state The state of the processing
+ * @param keepJobInHistory whether to keep the job in the job history.
+ * @param duration the duration of the processing.
*/
public void finished(final Job.JobState state,
final boolean keepJobInHistory,
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=1636824&r1=1636823&r2=1636824&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 Wed Nov 5 08:50:36 2014
@@ -367,7 +367,7 @@ public class JobImpl implements Job, Com
}
/**
- * @see org.apache.sling.event.jobs.Job#getCurrentProgressStep()
+ * @see org.apache.sling.event.jobs.Job#getFinishedProgressStep()
*/
@Override
public int getFinishedProgressStep() {
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=1636824&r1=1636823&r2=1636824&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 Nov 5 08:50:36 2014
@@ -501,7 +501,7 @@ public class JobManagerImpl
}
/**
- * @see org.apache.sling.event.jobs.JobManager#findJobs(org.apache.sling.event.jobs.JobManager.QueryType, java.lang.String, long, java.util.Map<java.lang.String,java.lang.Object>[])
+ * @see org.apache.sling.event.jobs.JobManager#findJobs(org.apache.sling.event.jobs.JobManager.QueryType, java.lang.String, long, java.util.Map[])
*/
@Override
public Collection<Job> findJobs(final QueryType type,
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=1636824&r1=1636823&r2=1636824&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 Nov 5 08:50:36 2014
@@ -165,7 +165,7 @@ public class JobSchedulerImpl
}
/**
- * @see org.apache.sling.event.impl.AbstractRepositoryEventHandler#runInBackground()
+ * This is the background thread processing new scheduled jobs.
*/
protected void runInBackground() {
Event event = null;
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java?rev=1636824&r1=1636823&r2=1636824&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/config/JobManagerConfiguration.java Wed Nov 5 08:50:36 2014
@@ -231,7 +231,7 @@ public class JobManagerConfiguration imp
* Create a new resource resolver for reading and writing the resource tree.
* The resolver needs to be closed by the client.
* @return A resource resolver
- * @throw RuntimeException if the resolver can't be created.
+ * @throws RuntimeException if the resolver can't be created.
*/
public ResourceResolver createResourceResolver() {
ResourceResolver resolver = null;
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=1636824&r1=1636823&r2=1636824&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 Nov 5 08:50:36 2014
@@ -380,8 +380,8 @@ public abstract class AbstractJobQueue
}
/**
- * Inform the queue about a job for the topic
- * @param topic A new topic.
+ * Inform the queue about new job for the given topics.
+ * @param topics the new topics
*/
public void wakeUpQueue(final Set<String> topics) {
this.cache.handleNewTopics(topics);
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueJobCache.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueJobCache.java?rev=1636824&r1=1636823&r2=1636824&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueJobCache.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueJobCache.java Wed Nov 5 08:50:36 2014
@@ -69,7 +69,7 @@ public class QueueJobCache {
/**
* Create a new queue job cache
* @param configuration Current job manager configuration
- * @param info The queue info
+ * @param queueType The queue type
* @param topics The topics handled by this queue.
*/
public QueueJobCache(final JobManagerConfiguration configuration,
@@ -109,7 +109,7 @@ public class QueueJobCache {
/**
* Get the next job.
* This method is not called concurrently, however
- * {@link #reschedule(JobImpl)} and {@link #handleNewTopics(String)}
+ * {@link #reschedule(JobHandler)} and {@link #handleNewTopics(Set)}
* can be called concurrently.
*/
public JobImpl getNextJob(final boolean doFull) {
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java?rev=1636824&r1=1636823&r2=1636824&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/queues/QueueManager.java Wed Nov 5 08:50:36 2014
@@ -337,7 +337,7 @@ public class QueueManager
/**
* This method is called whenever the topology or queue configurations change.
- * @param caps The new topology capabilities or {@code null} if currently unknown.
+ * @param active Whether the job handling is active atm.
*/
@Override
public void configurationChanged(final boolean active) {
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java?rev=1636824&r1=1636823&r2=1636824&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/CheckTopologyTask.java Wed Nov 5 08:50:36 2014
@@ -60,7 +60,7 @@ public class CheckTopologyTask {
/**
* Constructor
- * @param The configuration
+ * @param config The configuration
*/
public CheckTopologyTask(final JobManagerConfiguration config) {
this.configuration = config;
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/FindUnfinishedJobsTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/FindUnfinishedJobsTask.java?rev=1636824&r1=1636823&r2=1636824&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/FindUnfinishedJobsTask.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/FindUnfinishedJobsTask.java Wed Nov 5 08:50:36 2014
@@ -45,7 +45,7 @@ public class FindUnfinishedJobsTask {
/**
* Constructor
- * @param The configuration
+ * @param config the configuration
*/
public FindUnfinishedJobsTask(final JobManagerConfiguration config) {
this.configuration = config;
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.java?rev=1636824&r1=1636823&r2=1636824&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/jobs/tasks/UpgradeTask.java Wed Nov 5 08:50:36 2014
@@ -58,7 +58,7 @@ public class UpgradeTask {
/**
* Constructor
- * @param The configuration
+ * @param config the configuration
*/
public UpgradeTask(final JobManagerConfiguration config) {
this.configuration = config;
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=1636824&r1=1636823&r2=1636824&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 Nov 5 08:50:36 2014
@@ -182,7 +182,7 @@ public class TimedEventSender
}
/**
- * @see org.apache.sling.event.impl.AbstractRepositoryEventHandler#runInBackground()
+ * The background thread for the timed events.
*/
protected void runInBackground() {
Event event = null;
@@ -273,7 +273,7 @@ public class TimedEventSender
* Process the event.
* If a scheduler is available, a job is scheduled or stopped.
* @param event The incoming event.
- * @return
+ * @return {@code true} if the event could be processed.
*/
protected boolean processEvent(final Event event, final ScheduleInfo scheduleInfo) {
final Scheduler localScheduler = this.scheduler;
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=1636824&r1=1636823&r2=1636824&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 Nov 5 08:50:36 2014
@@ -131,7 +131,7 @@ public interface JobBuilder {
/**
* Schedule the job for according to the cron expression.
* If no expression is specified, the job can't be scheduled.
- * @param date The date
+ * @param expression The cron expression
*/
ScheduleBuilder cron(final String expression);
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobConsumer.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobConsumer.java?rev=1636824&r1=1636823&r2=1636824&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobConsumer.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobConsumer.java Wed Nov 5 08:50:36 2014
@@ -26,29 +26,43 @@ import aQute.bnd.annotation.ConsumerType
/**
* A job consumer consumes a job.
- *
+ * <p>
* If the job consumer needs more features like providing progress information or adding
* more information of the processing, {@link JobExecutor} should be implemented instead.
- *
+ * <p>
* A job consumer registers itself with the {@link #PROPERTY_TOPICS} service registration
* property. The value of this property defines which topics a consumer is able to process.
- * Each string value of this property is either a job topic or a topic category ending
- * with "/*" which means all topics in this category.
- * For example, the value "org/apache/sling/jobs/*" matches the topics
- * "org/apache/sling/jobs/a" and "org/apache/sling/jobs/b" but neither
- * "org/apache/sling/jobs" nor "org/apache/sling/jobs/subcategory/a"
- *
+ * Each string value of this property is either
+ * <ul>
+ * <li>a job topic, or
+ * <li>a topic category ending with "/*" which means all topics in this category, or
+ * <li>a topic category ending with "/**" which means all topics in this category and all
+ * sub categories. This matching is new since version 1.2.
+ * </ul>
+ * A consumer registering for just "*" or "**" is not considered.
+ * <p>
+ * For example, the value {@code org/apache/sling/jobs/*} matches the topics
+ * {@code org/apache/sling/jobs/a} and {@code org/apache/sling/jobs/b} but neither
+ * {@code org/apache/sling/jobs} nor {@code org/apache/sling/jobs/subcategory/a}. A value of
+ * {@code org/apache/sling/jobs/**} matches the same topics but also all sub topics
+ * like {@code org/apache/sling/jobs/subcategory/a} or {@code org/apache/sling/jobs/subcategory/a/c/d}.
+ * <p>
* If there is more than one job consumer or executor registered for a job topic, the selection is as
* follows:
- * - If there is a single consumer registering for the exact topic, this one is used
- * - If there is more than a single consumer registering for the exact topic, the one
- * with the highest service ranking is used. If the ranking is equal, the one with
- * the lowest service ID is used.
- * - If there is a single consumer registered for the category, it is used
- * - If there is more than a single consumer registered for the category, the service
- * with the highest service ranking is used. If the ranking is equal, the one with
- * the lowest service ID is used.
- *
+ * <ul>
+ * <li>If there is a single consumer registering for the exact topic, this one is used.
+ * <li>If there is more than a single consumer registering for the exact topic, the one
+ * with the highest service ranking is used. If the ranking is equal, the one with
+ * the lowest service ID is used.
+ * <li>If there is a single consumer registered for the category, it is used.
+ * <li>If there is more than a single consumer registered for the category, the service
+ * with the highest service ranking is used. If the ranking is equal, the one with
+ * the lowest service ID is used.
+ * <li>The search continues with consumer registered for deep categories. The nearest one
+ * is tried next. If there are several, the one with the highest service ranking is
+ * used. If the ranking is equal, the one with the lowest service ID is used.
+ * </ul>
+ * <p>
* If the consumer decides to process the job asynchronously, the processing must finish
* within the current lifetime of the job consumer. If the consumer (or the instance
* of the consumer) dies, the job processing will mark this processing as failed and
@@ -59,11 +73,18 @@ import aQute.bnd.annotation.ConsumerType
@ConsumerType
public interface JobConsumer {
+ /**
+ * The result of the job processing.
+ */
enum JobResult {
- OK, // processing finished
- FAILED, // processing failed, can be retried
- CANCEL, // processing failed permanently
- ASYNC // processing will be done async
+ /** Processing finished successfully. */
+ OK,
+ /** Processing failed but might be retried. */
+ FAILED,
+ /** Processing failed permanently and must not be retried. */
+ CANCEL,
+ /** Processing will be done asynchronously. */
+ ASYNC
}
/** Job property containing an asynchronous handler. */
@@ -92,18 +113,18 @@ public interface JobConsumer {
/**
* Execute the job.
- *
- * If the job has been processed successfully, {@link JobResult.OK} should be returned.
- * If the job has not been processed completely, but might be rescheduled {@link JobResult.FAILED}
+ * <p>
+ * If the job has been processed successfully, {@link JobResult#OK} should be returned.
+ * If the job has not been processed completely, but might be rescheduled {@link JobResult#FAILED}
* should be returned.
- * If the job processing failed and should not be rescheduled, {@link JobResult.CANCEL} should
+ * If the job processing failed and should not be rescheduled, {@link JobResult#CANCEL} should
* be returned.
- *
- * If the consumer decides to process the job asynchronously it should return {@link JobResult.ASYNC}
+ * <p>
+ * If the consumer decides to process the job asynchronously it should return {@link JobResult#ASYNC}
* and notify the job manager by using the {@link AsyncHandler} interface.
- *
+ * <p>
* If the processing fails with throwing an exception/throwable, the process will not be rescheduled
- * and treated like the method would have returned {@link JobResult.CANCEL}.
+ * and treated like the method would have returned {@link JobResult#CANCEL}.
*
* @param job The job
* @return The job result
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobExecutionContext.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobExecutionContext.java?rev=1636824&r1=1636823&r2=1636824&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobExecutionContext.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobExecutionContext.java Wed Nov 5 08:50:36 2014
@@ -71,7 +71,7 @@ public interface JobExecutionContext {
* job progress is assumed to be 100%.
* This method has only effect if {@link #initProgress(int, long)}
* has been called first with a positive number for steps
- * @param step The number of finished steps since the last call.
+ * @param steps The number of finished steps since the last call.
*/
void incrementProgressCount(final int steps);
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobExecutor.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobExecutor.java?rev=1636824&r1=1636823&r2=1636824&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobExecutor.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/JobExecutor.java Wed Nov 5 08:50:36 2014
@@ -24,26 +24,40 @@ import aQute.bnd.annotation.ConsumerType
/**
* A job executor consumes a job.
- *
+ * <p>
* A job executor registers itself with the {@link #PROPERTY_TOPICS} service registration
* property. The value of this property defines which topics an executor is able to process.
- * Each string value of this property is either a job topic or a topic category ending
- * with "/*" which means all topics in this category.
- * For example, the value "org/apache/sling/jobs/*" matches the topics
- * "org/apache/sling/jobs/a" and "org/apache/sling/jobs/b" but neither
- * "org/apache/sling/jobs" nor "org/apache/sling/jobs/subcategory/a"
- *
- * If there is more than one job executor or consumer registered for a job topic,
- * the selection is as follows:
- * - If there is a single consumer registering for the exact topic, this one is used
- * - If there is more than a single consumer registering for the exact topic, the one
- * with the highest service ranking is used. If the ranking is equal, the one with
- * the lowest service ID is used.
- * - If there is a single consumer registered for the category, it is used
- * - If there is more than a single consumer registered for the category, the service
- * with the highest service ranking is used. If the ranking is equal, the one with
- * the lowest service ID is used.
- *
+ * Each string value of this property is either
+ * <ul>
+ * <li>a job topic, or
+ * <li>a topic category ending with "/*" which means all topics in this category, or
+ * <li>a topic category ending with "/**" which means all topics in this category and all
+ * sub categories. This matching is new since version 1.2.
+ * </ul>
+ * A consumer registering for just "*" or "**" is not considered.
+ * <p>
+ * For example, the value {@code org/apache/sling/jobs/*} matches the topics
+ * {@code org/apache/sling/jobs/a} and {@code org/apache/sling/jobs/b} but neither
+ * {@code org/apache/sling/jobs} nor {@code org/apache/sling/jobs/subcategory/a}. A value of
+ * {@code org/apache/sling/jobs/**} matches the same topics but also all sub topics
+ * like {@code org/apache/sling/jobs/subcategory/a} or {@code org/apache/sling/jobs/subcategory/a/c/d}.
+ * <p>
+ * If there is more than one job consumer or executor registered for a job topic, the selection is as
+ * follows:
+ * <ul>
+ * <li>If there is a single consumer registering for the exact topic, this one is used.
+ * <li>If there is more than a single consumer registering for the exact topic, the one
+ * with the highest service ranking is used. If the ranking is equal, the one with
+ * the lowest service ID is used.
+ * <li>If there is a single consumer registered for the category, it is used.
+ * <li>If there is more than a single consumer registered for the category, the service
+ * with the highest service ranking is used. If the ranking is equal, the one with
+ * the lowest service ID is used.
+ * <li>The search continues with consumer registered for deep categories. The nearest one
+ * is tried next. If there are several, the one with the highest service ranking is
+ * used. If the ranking is equal, the one with the lowest service ID is used.
+ * </ul>
+ * <p>
* If the executor decides to process the job asynchronously, the processing must finish
* within the current lifetime of the job executor. If the executor (or the instance
* of the executor) dies, the job processing will mark this processing as failed and
@@ -64,7 +78,7 @@ public interface JobExecutor {
* Execute the job.
*
* If the job has been processed successfully, a job result of "succeeded" should be returned. This result can
- * be generated by calling <code>JobExecutionContext.result().succeeded()</code>.
+ * be generated by calling <code>JobExecutionContext.result().succeeded()</code>
*
* If the job has not been processed completely, but might be rescheduled "failed" should be returned.
* This result can be generated by calling <code>JobExecutionContext.result().failed()</code>.
Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/package-info.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/package-info.java?rev=1636824&r1=1636823&r2=1636824&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/package-info.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/jobs/consumer/package-info.java Wed Nov 5 08:50:36 2014
@@ -17,7 +17,7 @@
* under the License.
*/
-@Version("1.1.0")
+@Version("1.2.0")
package org.apache.sling.event.jobs.consumer;
import aQute.bnd.annotation.Version;
Modified: sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/EventUtilTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/EventUtilTest.java?rev=1636824&r1=1636823&r2=1636824&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/EventUtilTest.java (original)
+++ sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/EventUtilTest.java Wed Nov 5 08:50:36 2014
@@ -25,25 +25,14 @@ import static org.junit.Assert.assertTru
import java.util.Dictionary;
import java.util.Hashtable;
-import org.jmock.Mockery;
-import org.jmock.integration.junit4.JMock;
-import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.Test;
-import org.junit.runner.RunWith;
import org.osgi.service.event.Event;
/**
* Tests for the EventUtil utility methods.
*/
-@RunWith(JMock.class)
public class EventUtilTest {
- protected Mockery context;
-
- public EventUtilTest() {
- this.context = new JUnit4Mockery();
- }
-
@Test public void testDistributeFlag() {
final Event distributableEvent = EventUtil.createDistributableEvent("some/topic", null);
assertTrue(EventUtil.shouldDistribute(distributableEvent));
Added: sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/JobConsumerManagerTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/JobConsumerManagerTest.java?rev=1636824&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/JobConsumerManagerTest.java (added)
+++ sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/JobConsumerManagerTest.java Wed Nov 5 08:50:36 2014
@@ -0,0 +1,198 @@
+/*
+ * 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.impl.jobs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.Collections;
+
+import org.apache.sling.event.jobs.consumer.JobConsumer;
+import org.apache.sling.event.jobs.consumer.JobExecutor;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+public class JobConsumerManagerTest {
+
+ @Test public void testSimpleMappingConsumer() {
+ final BundleContext bc = Mockito.mock(BundleContext.class);
+ final JobConsumerManager jcs = new JobConsumerManager();
+ jcs.activate(bc, Collections.EMPTY_MAP);
+
+ final JobConsumer jc1 = Mockito.mock(JobConsumer.class);
+ final ServiceReference ref1 = Mockito.mock(ServiceReference.class);
+ Mockito.when(ref1.getProperty(JobConsumer.PROPERTY_TOPICS)).thenReturn("a/b");
+ Mockito.when(ref1.getProperty(Constants.SERVICE_RANKING)).thenReturn(1);
+ Mockito.when(ref1.getProperty(Constants.SERVICE_ID)).thenReturn(1L);
+ Mockito.when(bc.getService(ref1)).thenReturn(jc1);
+ jcs.bindJobConsumer(ref1);
+
+ assertNotNull(jcs.getExecutor("a/b"));
+ assertNull(jcs.getExecutor("a"));
+ assertNull(jcs.getExecutor("a/c"));
+ assertNull(jcs.getExecutor("a/b/a"));
+ }
+
+ @Test public void testCategoryMappingConsumer() {
+ final BundleContext bc = Mockito.mock(BundleContext.class);
+ final JobConsumerManager jcs = new JobConsumerManager();
+ jcs.activate(bc, Collections.EMPTY_MAP);
+
+ final JobConsumer jc1 = Mockito.mock(JobConsumer.class);
+ final ServiceReference ref1 = Mockito.mock(ServiceReference.class);
+ Mockito.when(ref1.getProperty(JobConsumer.PROPERTY_TOPICS)).thenReturn("a/*");
+ Mockito.when(ref1.getProperty(Constants.SERVICE_RANKING)).thenReturn(1);
+ Mockito.when(ref1.getProperty(Constants.SERVICE_ID)).thenReturn(1L);
+ Mockito.when(bc.getService(ref1)).thenReturn(jc1);
+ jcs.bindJobConsumer(ref1);
+
+ assertNotNull(jcs.getExecutor("a/b"));
+ assertNull(jcs.getExecutor("a"));
+ assertNotNull(jcs.getExecutor("a/c"));
+ assertNull(jcs.getExecutor("a/b/a"));
+ }
+
+ @Test public void testSubCategoryMappingConsumer() {
+ final BundleContext bc = Mockito.mock(BundleContext.class);
+ final JobConsumerManager jcs = new JobConsumerManager();
+ jcs.activate(bc, Collections.EMPTY_MAP);
+
+ final JobConsumer jc1 = Mockito.mock(JobConsumer.class);
+ final ServiceReference ref1 = Mockito.mock(ServiceReference.class);
+ Mockito.when(ref1.getProperty(JobConsumer.PROPERTY_TOPICS)).thenReturn("a/**");
+ Mockito.when(ref1.getProperty(Constants.SERVICE_RANKING)).thenReturn(1);
+ Mockito.when(ref1.getProperty(Constants.SERVICE_ID)).thenReturn(1L);
+ Mockito.when(bc.getService(ref1)).thenReturn(jc1);
+ jcs.bindJobConsumer(ref1);
+
+ assertNotNull(jcs.getExecutor("a/b"));
+ assertNull(jcs.getExecutor("a"));
+ assertNotNull(jcs.getExecutor("a/c"));
+ assertNotNull(jcs.getExecutor("a/b/a"));
+ }
+
+ @Test public void testSimpleMappingExecutor() {
+ final BundleContext bc = Mockito.mock(BundleContext.class);
+ final JobConsumerManager jcs = new JobConsumerManager();
+ jcs.activate(bc, Collections.EMPTY_MAP);
+
+ final JobExecutor jc1 = Mockito.mock(JobExecutor.class);
+ final ServiceReference ref1 = Mockito.mock(ServiceReference.class);
+ Mockito.when(ref1.getProperty(JobConsumer.PROPERTY_TOPICS)).thenReturn("a/b");
+ Mockito.when(ref1.getProperty(Constants.SERVICE_RANKING)).thenReturn(1);
+ Mockito.when(ref1.getProperty(Constants.SERVICE_ID)).thenReturn(1L);
+ Mockito.when(bc.getService(ref1)).thenReturn(jc1);
+ jcs.bindJobExecutor(ref1);
+
+ assertNotNull(jcs.getExecutor("a/b"));
+ assertNull(jcs.getExecutor("a"));
+ assertNull(jcs.getExecutor("a/c"));
+ assertNull(jcs.getExecutor("a/b/a"));
+ }
+
+ @Test public void testCategoryMappingExecutor() {
+ final BundleContext bc = Mockito.mock(BundleContext.class);
+ final JobConsumerManager jcs = new JobConsumerManager();
+ jcs.activate(bc, Collections.EMPTY_MAP);
+
+ final JobExecutor jc1 = Mockito.mock(JobExecutor.class);
+ final ServiceReference ref1 = Mockito.mock(ServiceReference.class);
+ Mockito.when(ref1.getProperty(JobExecutor.PROPERTY_TOPICS)).thenReturn("a/*");
+ Mockito.when(ref1.getProperty(Constants.SERVICE_RANKING)).thenReturn(1);
+ Mockito.when(ref1.getProperty(Constants.SERVICE_ID)).thenReturn(1L);
+ Mockito.when(bc.getService(ref1)).thenReturn(jc1);
+ jcs.bindJobExecutor(ref1);
+
+ assertNotNull(jcs.getExecutor("a/b"));
+ assertNull(jcs.getExecutor("a"));
+ assertNotNull(jcs.getExecutor("a/c"));
+ assertNull(jcs.getExecutor("a/b/a"));
+ }
+
+ @Test public void testSubCategoryMappingExecutor() {
+ final BundleContext bc = Mockito.mock(BundleContext.class);
+ final JobConsumerManager jcs = new JobConsumerManager();
+ jcs.activate(bc, Collections.EMPTY_MAP);
+
+ final JobExecutor jc1 = Mockito.mock(JobExecutor.class);
+ final ServiceReference ref1 = Mockito.mock(ServiceReference.class);
+ Mockito.when(ref1.getProperty(JobExecutor.PROPERTY_TOPICS)).thenReturn("a/**");
+ Mockito.when(ref1.getProperty(Constants.SERVICE_RANKING)).thenReturn(1);
+ Mockito.when(ref1.getProperty(Constants.SERVICE_ID)).thenReturn(1L);
+ Mockito.when(bc.getService(ref1)).thenReturn(jc1);
+ jcs.bindJobExecutor(ref1);
+
+ assertNotNull(jcs.getExecutor("a/b"));
+ assertNull(jcs.getExecutor("a"));
+ assertNotNull(jcs.getExecutor("a/c"));
+ assertNotNull(jcs.getExecutor("a/b/a"));
+ }
+
+ @Test public void testRanking() {
+ final BundleContext bc = Mockito.mock(BundleContext.class);
+ final JobConsumerManager jcs = new JobConsumerManager();
+ jcs.activate(bc, Collections.EMPTY_MAP);
+
+ final JobExecutor jc1 = Mockito.mock(JobExecutor.class);
+ final JobExecutor jc2 = Mockito.mock(JobExecutor.class);
+ final JobExecutor jc3 = Mockito.mock(JobExecutor.class);
+ final JobExecutor jc4 = Mockito.mock(JobExecutor.class);
+ final ServiceReference ref1 = Mockito.mock(ServiceReference.class);
+ Mockito.when(ref1.getProperty(JobExecutor.PROPERTY_TOPICS)).thenReturn("a/b");
+ Mockito.when(ref1.getProperty(Constants.SERVICE_RANKING)).thenReturn(1);
+ Mockito.when(ref1.getProperty(Constants.SERVICE_ID)).thenReturn(1L);
+ Mockito.when(bc.getService(ref1)).thenReturn(jc1);
+ jcs.bindJobExecutor(ref1);
+ assertEquals(jc1, jcs.getExecutor("a/b"));
+
+ final ServiceReference ref2 = Mockito.mock(ServiceReference.class);
+ Mockito.when(ref2.getProperty(JobExecutor.PROPERTY_TOPICS)).thenReturn("a/b");
+ Mockito.when(ref2.getProperty(Constants.SERVICE_RANKING)).thenReturn(10);
+ Mockito.when(ref2.getProperty(Constants.SERVICE_ID)).thenReturn(2L);
+ Mockito.when(bc.getService(ref2)).thenReturn(jc2);
+ jcs.bindJobExecutor(ref2);
+ assertEquals(jc2, jcs.getExecutor("a/b"));
+
+ final ServiceReference ref3 = Mockito.mock(ServiceReference.class);
+ Mockito.when(ref3.getProperty(JobExecutor.PROPERTY_TOPICS)).thenReturn("a/b");
+ Mockito.when(ref3.getProperty(Constants.SERVICE_RANKING)).thenReturn(5);
+ Mockito.when(ref3.getProperty(Constants.SERVICE_ID)).thenReturn(3L);
+ Mockito.when(bc.getService(ref3)).thenReturn(jc3);
+ jcs.bindJobExecutor(ref3);
+ assertEquals(jc2, jcs.getExecutor("a/b"));
+
+ final ServiceReference ref4 = Mockito.mock(ServiceReference.class);
+ Mockito.when(ref4.getProperty(JobExecutor.PROPERTY_TOPICS)).thenReturn("a/b");
+ Mockito.when(ref4.getProperty(Constants.SERVICE_RANKING)).thenReturn(5);
+ Mockito.when(ref4.getProperty(Constants.SERVICE_ID)).thenReturn(4L);
+ Mockito.when(bc.getService(ref4)).thenReturn(jc4);
+ jcs.bindJobExecutor(ref4);
+ assertEquals(jc2, jcs.getExecutor("a/b"));
+
+ jcs.unbindJobExecutor(ref2);
+ assertEquals(jc3, jcs.getExecutor("a/b"));
+
+ jcs.unbindJobExecutor(ref3);
+ assertEquals(jc4, jcs.getExecutor("a/b"));
+ }
+}
Propchange: sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/JobConsumerManagerTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/JobConsumerManagerTest.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/trunk/bundles/extensions/event/src/test/java/org/apache/sling/event/impl/jobs/JobConsumerManagerTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain