Author: cziegeler Date: Tue Aug 8 15:33:16 2017 New Revision: 1804434 URL: http://svn.apache.org/viewvc?rev=1804434&view=rev Log: SLING-7037 : Scheduler does not retain provided name. Fix handling of name and provided name, add tests including new test case from Marcel Reutegger
Modified: sling/trunk/bundles/commons/scheduler/pom.xml sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/InternalScheduleOptions.java sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandler.java sling/trunk/bundles/commons/scheduler/src/test/java/org/apache/sling/commons/scheduler/impl/QuartzSchedulerTest.java sling/trunk/bundles/commons/scheduler/src/test/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandlerTest.java Modified: sling/trunk/bundles/commons/scheduler/pom.xml URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/scheduler/pom.xml?rev=1804434&r1=1804433&r2=1804434&view=diff ============================================================================== --- sling/trunk/bundles/commons/scheduler/pom.xml (original) +++ sling/trunk/bundles/commons/scheduler/pom.xml Tue Aug 8 15:33:16 2017 @@ -23,7 +23,7 @@ <parent> <groupId>org.apache.sling</groupId> <artifactId>sling</artifactId> - <version>30</version> + <version>31</version> <relativePath /> </parent> @@ -50,9 +50,6 @@ <extensions>true</extensions> <configuration> <instructions> - <Private-Package> - org.apache.sling.commons.scheduler.impl - </Private-Package> <Import-Package> !commonj.work, !com.mchange.v2.c3p0, Modified: sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/InternalScheduleOptions.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/InternalScheduleOptions.java?rev=1804434&r1=1804433&r2=1804434&view=diff ============================================================================== --- sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/InternalScheduleOptions.java (original) +++ sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/InternalScheduleOptions.java Tue Aug 8 15:33:16 2017 @@ -30,6 +30,10 @@ import org.quartz.TriggerBuilder; */ public class InternalScheduleOptions implements ScheduleOptions { + public final TriggerBuilder<? extends Trigger> trigger; + + public final IllegalArgumentException argumentException; + public String providedName; public String name; @@ -40,10 +44,6 @@ public class InternalScheduleOptions imp public Map<String, Serializable> configuration; - public final TriggerBuilder<? extends Trigger> trigger; - - public final IllegalArgumentException argumentException; - public String[] runOn; public InternalScheduleOptions(final TriggerBuilder<? extends Trigger> trigger) { @@ -71,6 +71,7 @@ public class InternalScheduleOptions imp @Override public ScheduleOptions name(final String name) { this.name = name; + this.providedName = name; return this; } Modified: sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java?rev=1804434&r1=1804433&r2=1804434&view=diff ============================================================================== --- sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java (original) +++ sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java Tue Aug 8 15:33:16 2017 @@ -75,7 +75,7 @@ public class QuartzScheduler implements static final String DATA_MAP_OBJECT = "QuartzJobScheduler.Object"; /** Map key for the provided job name */ - static final String DATA_MAP_PROVIDED_NAME = "QuartzJobScheduler.JobName"; + static final String DATA_MAP_PROVIDED_NAME = "QuartzJobScheduler.ProvidedJobName"; /** Map key for the job name */ static final String DATA_MAP_NAME = "QuartzJobScheduler.JobName"; @@ -97,7 +97,7 @@ public class QuartzScheduler implements /** Map key for the quartz scheduler */ static final String DATA_MAP_QUARTZ_SCHEDULER = "QuartzJobScheduler.QuartzScheduler"; - + static final String DATA_MAP_THREAD_POOL_NAME = "QuartzJobScheduler.threadPoolName"; static final String METRICS_NAME_RUNNING_JOBS = "commons.scheduler.running.jobs"; @@ -112,11 +112,11 @@ public class QuartzScheduler implements @Reference private ThreadPoolManager threadPoolManager; - @Reference + @Reference MetricsService metricsService; - + ConfigHolder configHolder; - + /** The quartz schedulers. */ private final Map<String, SchedulerProxy> schedulers = new HashMap<>(); @@ -146,7 +146,7 @@ public class QuartzScheduler implements ctx.addBundleListener(this); this.configHolder = new ConfigHolder(configuration); - + this.active = true; } @@ -615,7 +615,6 @@ public class QuartzScheduler implements } synchronized ( proxy ) { - opts.providedName = opts.name; final String name; if ( opts.name != null ) { // if there is already a job with the name, remove it first Modified: sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandler.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandler.java?rev=1804434&r1=1804433&r2=1804434&view=diff ============================================================================== --- sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandler.java (original) +++ sling/trunk/bundles/commons/scheduler/src/main/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandler.java Tue Aug 8 15:33:16 2017 @@ -247,7 +247,6 @@ public class WhiteboardHandler { } private void scheduleJob(final ServiceReference<?> ref, final Object job, final ScheduleOptions scheduleOptions) { - ((InternalScheduleOptions)scheduleOptions).providedName = getStringProperty(ref, Scheduler.PROPERTY_SCHEDULER_NAME); final String name = getServiceIdentifier(ref); final Boolean concurrent = getBooleanProperty(ref, Scheduler.PROPERTY_SCHEDULER_CONCURRENT); final String[] runOnOpts = getRunOpts(ref); @@ -265,6 +264,7 @@ public class WhiteboardHandler { .canRunConcurrently((concurrent != null ? concurrent : true)) .threadPoolName(poolName) .onInstancesOnly(runOnOpts); + ((InternalScheduleOptions)scheduleOptions).providedName = getStringProperty(ref, Scheduler.PROPERTY_SCHEDULER_NAME); final long bundleId = ref.getBundle().getBundleId(); final Long serviceId = getLongProperty(ref, Constants.SERVICE_ID); Modified: sling/trunk/bundles/commons/scheduler/src/test/java/org/apache/sling/commons/scheduler/impl/QuartzSchedulerTest.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/scheduler/src/test/java/org/apache/sling/commons/scheduler/impl/QuartzSchedulerTest.java?rev=1804434&r1=1804433&r2=1804434&view=diff ============================================================================== --- sling/trunk/bundles/commons/scheduler/src/test/java/org/apache/sling/commons/scheduler/impl/QuartzSchedulerTest.java (original) +++ sling/trunk/bundles/commons/scheduler/src/test/java/org/apache/sling/commons/scheduler/impl/QuartzSchedulerTest.java Tue Aug 8 15:33:16 2017 @@ -25,9 +25,12 @@ import static org.mockito.Mockito.when; import java.io.Serializable; import java.lang.reflect.Field; +import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.sling.commons.scheduler.Job; import org.apache.sling.testing.mock.osgi.MockOsgi; @@ -42,9 +45,11 @@ import org.mockito.runners.MockitoJUnitR import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; +import org.quartz.JobDetail; import org.quartz.JobKey; import org.quartz.SchedulerException; import org.quartz.TriggerBuilder; +import org.quartz.impl.matchers.GroupMatcher; @RunWith(MockitoJUnitRunner.class) public class QuartzSchedulerTest { @@ -327,4 +332,39 @@ public class QuartzSchedulerTest { sField.set(quartzScheduler, this.proxies); } } + + @SuppressWarnings("rawtypes") + @Test + public void testNameAndProvidedName() throws SchedulerException { + final Date future = new Date(System.currentTimeMillis() + 1000 * 60 * 60); + quartzScheduler.schedule(1L, 1L, new Thread(), quartzScheduler.AT(future).name("j1").threadPoolName("tp1")); + quartzScheduler.schedule(1L, 1L, new Thread(), quartzScheduler.AT(future) + .config(Collections.singletonMap("key", (Serializable)"value")).threadPoolName("tp1")); + assertNull(proxies.get("tp1")); + // j1 is scheduled named, so both name and provided name should be set to j1 + JobDetail jobDetail = proxies.get("testName").getScheduler().getJobDetail(JobKey.jobKey("j1")); + assertEquals("j1", jobDetail.getJobDataMap().get(QuartzScheduler.DATA_MAP_NAME)); + assertEquals("j1", jobDetail.getJobDataMap().get(QuartzScheduler.DATA_MAP_PROVIDED_NAME)); + + // search job detail for job without name + jobDetail = null; + org.quartz.Scheduler scheduler = quartzScheduler.getSchedulers().get("testName").getScheduler(); + final List<String> groups = scheduler.getJobGroupNames(); + for(final String group : groups) { + final Set<JobKey> keys = scheduler.getJobKeys(GroupMatcher.jobGroupEquals(group)); + for(final JobKey key : keys) { + final JobDetail detail = scheduler.getJobDetail(key); + if ( detail != null + && detail.getJobDataMap().get(QuartzScheduler.DATA_MAP_CONFIGURATION) != null + && ((Map)detail.getJobDataMap().get(QuartzScheduler.DATA_MAP_CONFIGURATION)).get("key").equals("value")) { + jobDetail = detail; + break; + } + } + } + // provided name should be null, name is generated + assertNotNull(jobDetail); + assertNull(jobDetail.getJobDataMap().get(QuartzScheduler.DATA_MAP_PROVIDED_NAME)); + assertNotNull(jobDetail.getJobDataMap().get(QuartzScheduler.DATA_MAP_NAME)); + } } Modified: sling/trunk/bundles/commons/scheduler/src/test/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandlerTest.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/scheduler/src/test/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandlerTest.java?rev=1804434&r1=1804433&r2=1804434&view=diff ============================================================================== --- sling/trunk/bundles/commons/scheduler/src/test/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandlerTest.java (original) +++ sling/trunk/bundles/commons/scheduler/src/test/java/org/apache/sling/commons/scheduler/impl/WhiteboardHandlerTest.java Tue Aug 8 15:33:16 2017 @@ -16,12 +16,15 @@ */ package org.apache.sling.commons.scheduler.impl; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import java.lang.reflect.Field; import java.util.Dictionary; import java.util.Hashtable; +import java.util.List; +import java.util.Set; import org.apache.sling.commons.scheduler.Scheduler; import org.apache.sling.testing.mock.osgi.MockOsgi; @@ -32,8 +35,10 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; +import org.quartz.JobDetail; import org.quartz.JobKey; import org.quartz.SchedulerException; +import org.quartz.impl.matchers.GroupMatcher; public class WhiteboardHandlerTest { private WhiteboardHandler handler; @@ -113,6 +118,71 @@ public class WhiteboardHandlerTest { assertNull(quartzScheduler.getSchedulers().get("testName").getScheduler().getJobDetail(jobKey)); } + // SLING-7037 + @Test + public void testAddingServiceWithProvidedName() throws SchedulerException { + Thread service = new Thread(); + String schedulerName = "testScheduler"; + Long period = 1L; + Integer times = 2; + + Dictionary<String, Object> serviceProps = new Hashtable<>(); + serviceProps.put(Scheduler.PROPERTY_SCHEDULER_RUN_ON, Scheduler.VALUE_RUN_ON_LEADER); + serviceProps.put(Scheduler.PROPERTY_SCHEDULER_CONCURRENT, Boolean.FALSE); + serviceProps.put(Scheduler.PROPERTY_SCHEDULER_IMMEDIATE, Boolean.FALSE); + serviceProps.put(Scheduler.PROPERTY_SCHEDULER_NAME, schedulerName); + serviceProps.put(Scheduler.PROPERTY_SCHEDULER_PERIOD, period); + serviceProps.put(Scheduler.PROPERTY_SCHEDULER_TIMES, times); + serviceProps.put(Constants.SERVICE_PID, "1"); + + final ServiceRegistration<?> reg = context.registerService(Runnable.class.getName(), service, serviceProps); + final ServiceReference<?> reference = reg.getReference(); + handler.register(reference, service); + JobKey jobKey = JobKey.jobKey(schedulerName + "." + reference.getProperty(Constants.SERVICE_ID)); + + JobDetail jobDetail = quartzScheduler.getSchedulers().get("testName").getScheduler().getJobDetail(jobKey); + assertNotNull(jobDetail); + assertEquals(schedulerName, jobDetail.getJobDataMap().getString(QuartzScheduler.DATA_MAP_PROVIDED_NAME)); + assertEquals(schedulerName + "." + reference.getProperty(Constants.SERVICE_ID), + jobDetail.getJobDataMap().getString(QuartzScheduler.DATA_MAP_NAME)); + } + + @Test + public void testAddingServiceWithoutProvidedName() throws SchedulerException { + Thread service = new Thread(); + Long period = 1L; + Integer times = 2; + + Dictionary<String, Object> serviceProps = new Hashtable<>(); + serviceProps.put(Scheduler.PROPERTY_SCHEDULER_RUN_ON, Scheduler.VALUE_RUN_ON_LEADER); + serviceProps.put(Scheduler.PROPERTY_SCHEDULER_CONCURRENT, Boolean.FALSE); + serviceProps.put(Scheduler.PROPERTY_SCHEDULER_IMMEDIATE, Boolean.FALSE); + serviceProps.put(Scheduler.PROPERTY_SCHEDULER_PERIOD, period); + serviceProps.put(Scheduler.PROPERTY_SCHEDULER_TIMES, times); + serviceProps.put(Constants.SERVICE_PID, "1"); + + final ServiceRegistration<?> reg = context.registerService(Runnable.class.getName(), service, serviceProps); + final ServiceReference<?> reference = reg.getReference(); + handler.register(reference, service); + + JobDetail jobDetail = null; + org.quartz.Scheduler scheduler = quartzScheduler.getSchedulers().get("testName").getScheduler(); + final List<String> groups = scheduler.getJobGroupNames(); + for(final String group : groups) { + final Set<JobKey> keys = scheduler.getJobKeys(GroupMatcher.jobGroupEquals(group)); + for(final JobKey key : keys) { + final JobDetail detail = scheduler.getJobDetail(key); + if ( detail != null && detail.getJobDataMap().get(QuartzScheduler.DATA_MAP_SERVICE_ID).equals(reg.getReference().getProperty(Constants.SERVICE_ID))) { + jobDetail = detail; + break; + } + } + } + assertNotNull(jobDetail); + assertNull(jobDetail.getJobDataMap().getString(QuartzScheduler.DATA_MAP_PROVIDED_NAME)); + assertNotNull(jobDetail.getJobDataMap().getString(QuartzScheduler.DATA_MAP_NAME)); + } + @After public void deactivateScheduler() { quartzScheduler.deactivate(context);