mirror of
https://github.com/Telecominfraproject/wlan-cloud-rrm.git
synced 2025-10-29 17:52:24 +00:00
[WIFI-10819] parse cron into valid quartz cron (#89)
Signed-off-by: Jun Woo Shin <jwoos@fb.com>
This commit is contained in:
@@ -478,8 +478,10 @@ components:
|
||||
RRMSchedule:
|
||||
type: object
|
||||
properties:
|
||||
cron:
|
||||
type: string
|
||||
crons:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
algorithms:
|
||||
type: array
|
||||
items:
|
||||
|
||||
@@ -19,9 +19,9 @@ public class RRMSchedule {
|
||||
*
|
||||
* This field expects a cron-like format as defined by the Quartz Job
|
||||
* Scheduler (CronTrigger):
|
||||
* https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html
|
||||
* https://www.quartz-scheduler.org/documentation/quartz-2.4.0/tutorials/crontrigger.html
|
||||
*/
|
||||
public String cron;
|
||||
public List<String> crons;
|
||||
|
||||
/**
|
||||
* The list of RRM algorithms to run.
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
package com.facebook.openwifirrm.modules;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -159,12 +160,21 @@ public class ProvMonitor implements Runnable {
|
||||
return null;
|
||||
}
|
||||
|
||||
RRMSchedule schedule = new RRMSchedule();
|
||||
schedule.cron = RRMScheduler
|
||||
String[] crons = RRMScheduler
|
||||
.parseIntoQuartzCron(details.rrm.schedule);
|
||||
if (schedule.cron == null || schedule.cron.isEmpty()) {
|
||||
if (crons == null || crons.length == 0) {
|
||||
return null;
|
||||
}
|
||||
// if ANY crons are invalid throw it out since it doesn't make sense to
|
||||
// schedule partial jobs
|
||||
for (String cron : crons) {
|
||||
if (cron == null || cron.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
RRMSchedule schedule = new RRMSchedule();
|
||||
schedule.crons = Arrays.asList(crons);
|
||||
|
||||
if (details.rrm.algorithms != null) {
|
||||
schedule.algorithms =
|
||||
@@ -175,6 +185,7 @@ public class ProvMonitor implements Runnable {
|
||||
)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return schedule;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.slf4j.LoggerFactory;
|
||||
import com.facebook.openwifirrm.DeviceConfig;
|
||||
import com.facebook.openwifirrm.DeviceDataManager;
|
||||
import com.facebook.openwifirrm.RRMAlgorithm;
|
||||
import com.facebook.openwifirrm.RRMSchedule;
|
||||
import com.facebook.openwifirrm.RRMConfig.ModuleConfig.RRMSchedulerParams;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
@@ -74,15 +75,21 @@ public class RRMScheduler {
|
||||
/** The scheduler instance. */
|
||||
private Scheduler scheduler;
|
||||
|
||||
/** The zones with active triggers scheduled. */
|
||||
private Set<String> scheduledZones;
|
||||
/**
|
||||
* The job keys with active triggers scheduled. Job keys take the format of
|
||||
* {@code <zone>:<index>}
|
||||
*
|
||||
* @see #parseIntoQuartzCron(String)
|
||||
* */
|
||||
private Set<String> scheduledJobKeys;
|
||||
|
||||
/** RRM job. */
|
||||
public static class RRMJob implements Job {
|
||||
@Override
|
||||
public void execute(JobExecutionContext context)
|
||||
throws JobExecutionException {
|
||||
String zone = context.getTrigger().getKey().getName();
|
||||
String jobKey = context.getTrigger().getKey().getName();
|
||||
String zone = jobKey.split(":")[0];
|
||||
logger.debug("Executing job for zone: {}", zone);
|
||||
try {
|
||||
SchedulerContext schedulerContext =
|
||||
@@ -107,13 +114,14 @@ public class RRMScheduler {
|
||||
* @param linuxCron Linux cron with seconds
|
||||
* (seconds minutes hours day_of_month month day_of_week [year])
|
||||
*
|
||||
* @throws IllegalArgumentException when a linux cron cannot be parsed
|
||||
* into a valid Quartz spec
|
||||
* @return String a Quartz supported cron
|
||||
* @throws IllegalArgumentException when a linux cron cannot be parsed into a
|
||||
* valid Quartz spec
|
||||
* @return String[] an array of length 1 or 2 of Quartz supported cron that's
|
||||
* equivalent to the original linux cron
|
||||
*/
|
||||
public static String parseIntoQuartzCron(String linuxCron) {
|
||||
public static String[] parseIntoQuartzCron(String linuxCron) {
|
||||
if (CronExpression.isValidExpression(linuxCron)) {
|
||||
return linuxCron;
|
||||
return new String[] { linuxCron };
|
||||
}
|
||||
|
||||
String[] split = linuxCron.split(" ");
|
||||
@@ -144,15 +152,36 @@ public class RRMScheduler {
|
||||
// if first case failed and only day of week is *, set to ?
|
||||
split[DAY_OF_WEEK_INDEX] = "?";
|
||||
} else {
|
||||
// Quartz does not support both values being set, so return null
|
||||
return null;
|
||||
// Quartz does not support both values being set but the standard says that
|
||||
// if both are specified then it becomes OR of the two fields. Which means
|
||||
// that we can split it into two separate crons and have it work the same way
|
||||
split[DAY_OF_MONTH_INDEX] = "?";
|
||||
String dayOfWeekCron = String.join(" ", split);
|
||||
|
||||
split[DAY_OF_MONTH_INDEX] = dayOfMonth;
|
||||
split[DAY_OF_WEEK_INDEX] = "?";
|
||||
String dayOfMonthCron = String.join(" ", split);
|
||||
|
||||
if (
|
||||
!CronExpression.isValidExpression(dayOfWeekCron) ||
|
||||
!CronExpression.isValidExpression(dayOfMonthCron)
|
||||
) {
|
||||
logger.error(
|
||||
"Unable to parse cron {} into valid crons",
|
||||
linuxCron
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new String[] { dayOfWeekCron, dayOfMonthCron };
|
||||
}
|
||||
|
||||
String quartzCron = String.join(" ", split);
|
||||
if (!CronExpression.isValidExpression(quartzCron)) {
|
||||
return null;
|
||||
}
|
||||
return quartzCron;
|
||||
|
||||
return new String[] { quartzCron };
|
||||
}
|
||||
|
||||
/** Constructor. */
|
||||
@@ -194,7 +223,7 @@ public class RRMScheduler {
|
||||
// Schedule job and triggers
|
||||
scheduler.addJob(job, false);
|
||||
syncTriggers();
|
||||
logger.info("Scheduled {} RRM trigger(s)", scheduledZones.size());
|
||||
logger.info("Scheduled {} RRM trigger(s)", scheduledJobKeys.size());
|
||||
|
||||
// Start scheduler
|
||||
scheduler.start();
|
||||
@@ -218,85 +247,98 @@ public class RRMScheduler {
|
||||
|
||||
/**
|
||||
* Synchronize triggers to the current topology, adding/updating/deleting
|
||||
* them as necessary. This updates {@link #scheduledZones}.
|
||||
* them as necessary. This updates {@link #scheduledJobKeys}.
|
||||
*/
|
||||
public void syncTriggers() {
|
||||
Set<String> scheduled = ConcurrentHashMap.newKeySet();
|
||||
Set<String> prevScheduled = new HashSet<>();
|
||||
if (scheduledZones != null) {
|
||||
prevScheduled.addAll(scheduledZones);
|
||||
if (scheduledJobKeys != null) {
|
||||
prevScheduled.addAll(scheduledJobKeys);
|
||||
}
|
||||
|
||||
// Add new triggers
|
||||
for (String zone : deviceDataManager.getZones()) {
|
||||
DeviceConfig config = deviceDataManager.getZoneConfig(zone);
|
||||
RRMSchedule schedule = config.schedule;
|
||||
if (
|
||||
config.schedule == null ||
|
||||
config.schedule.cron == null ||
|
||||
config.schedule.cron.isEmpty()
|
||||
schedule == null || schedule.crons == null ||
|
||||
schedule.crons.isEmpty()
|
||||
) {
|
||||
continue; // RRM not scheduled
|
||||
}
|
||||
|
||||
try {
|
||||
CronExpression.validateExpression(config.schedule.cron);
|
||||
} catch (ParseException e) {
|
||||
logger.error(
|
||||
String.format(
|
||||
"Invalid cron expression (%s) for zone %s",
|
||||
config.schedule.cron,
|
||||
zone
|
||||
),
|
||||
e
|
||||
for (int i = 0; i < schedule.crons.size(); i++) {
|
||||
String cron = schedule.crons.get(i);
|
||||
// if even one schedule has invalid cron, the whole thing is probably wrong
|
||||
if (cron == null || cron.isEmpty()) {
|
||||
logger.error("There was an invalid cron in the schedule");
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
CronExpression.validateExpression(cron);
|
||||
} catch (ParseException e) {
|
||||
logger.error(
|
||||
String.format(
|
||||
"Invalid cron expression (%s) for zone %s",
|
||||
cron,
|
||||
zone
|
||||
),
|
||||
e
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create trigger
|
||||
String jobKey = String.format("%s:%d", zone, i);
|
||||
Trigger trigger = TriggerBuilder.newTrigger()
|
||||
.withIdentity(jobKey)
|
||||
.forJob(job)
|
||||
.withSchedule(
|
||||
CronScheduleBuilder.cronSchedule(cron)
|
||||
)
|
||||
.build();
|
||||
|
||||
try {
|
||||
if (!prevScheduled.contains(jobKey)) {
|
||||
scheduler.scheduleJob(trigger);
|
||||
} else {
|
||||
scheduler.rescheduleJob(trigger.getKey(), trigger);
|
||||
}
|
||||
} catch (SchedulerException e) {
|
||||
logger.error(
|
||||
"Failed to schedule RRM trigger for job key: " + jobKey,
|
||||
e
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
scheduled.add(jobKey);
|
||||
logger.debug(
|
||||
"Scheduled/updated RRM for job key '{}' at: < {} >",
|
||||
jobKey,
|
||||
cron
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create trigger
|
||||
Trigger trigger = TriggerBuilder.newTrigger()
|
||||
.withIdentity(zone)
|
||||
.forJob(job)
|
||||
.withSchedule(
|
||||
CronScheduleBuilder.cronSchedule(config.schedule.cron)
|
||||
)
|
||||
.build();
|
||||
try {
|
||||
if (!prevScheduled.contains(zone)) {
|
||||
scheduler.scheduleJob(trigger);
|
||||
} else {
|
||||
scheduler.rescheduleJob(trigger.getKey(), trigger);
|
||||
}
|
||||
} catch (SchedulerException e) {
|
||||
logger.error(
|
||||
"Failed to schedule RRM trigger for zone: " + zone,
|
||||
e
|
||||
);
|
||||
continue;
|
||||
}
|
||||
scheduled.add(zone);
|
||||
logger.debug(
|
||||
"Scheduled/updated RRM for zone '{}' at: < {} >",
|
||||
zone,
|
||||
config.schedule.cron
|
||||
);
|
||||
}
|
||||
|
||||
// Remove old triggers
|
||||
prevScheduled.removeAll(scheduled);
|
||||
for (String zone : prevScheduled) {
|
||||
for (String jobKey : prevScheduled) {
|
||||
try {
|
||||
scheduler.unscheduleJob(TriggerKey.triggerKey(zone));
|
||||
scheduler.unscheduleJob(TriggerKey.triggerKey(jobKey));
|
||||
} catch (SchedulerException e) {
|
||||
logger.error(
|
||||
"Failed to remove RRM trigger for zone: " + zone,
|
||||
"Failed to remove RRM trigger for jobKey: " + jobKey,
|
||||
e
|
||||
);
|
||||
continue;
|
||||
}
|
||||
logger.debug("Removed RRM trigger for zone '{}'", zone);
|
||||
logger.debug("Removed RRM trigger for jobKey '{}'", jobKey);
|
||||
}
|
||||
|
||||
this.scheduledZones = scheduled;
|
||||
this.scheduledJobKeys = scheduled;
|
||||
}
|
||||
|
||||
/** Run RRM algorithms for the given zone. */
|
||||
@@ -305,16 +347,19 @@ public class RRMScheduler {
|
||||
|
||||
// Get algorithms from zone config
|
||||
DeviceConfig config = deviceDataManager.getZoneConfig(zone);
|
||||
if (config.schedule == null) {
|
||||
RRMSchedule schedule = config.schedule;
|
||||
if (schedule == null) {
|
||||
logger.error("RRM schedule missing for zone '{}', aborting!", zone);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
config.schedule.algorithms == null ||
|
||||
config.schedule.algorithms.isEmpty()
|
||||
schedule.algorithms == null ||
|
||||
schedule.algorithms.isEmpty()
|
||||
) {
|
||||
logger.debug("Using default RRM algorithms for zone '{}'", zone);
|
||||
config.schedule.algorithms = Arrays.asList(
|
||||
logger
|
||||
.debug("Using default RRM algorithms for zone '{}'", zone);
|
||||
schedule.algorithms = Arrays.asList(
|
||||
new RRMAlgorithm(
|
||||
RRMAlgorithm.AlgorithmType.OptimizeChannel.name()
|
||||
),
|
||||
@@ -325,7 +370,7 @@ public class RRMScheduler {
|
||||
}
|
||||
|
||||
// Execute algorithms
|
||||
for (RRMAlgorithm algo : config.schedule.algorithms) {
|
||||
for (RRMAlgorithm algo : schedule.algorithms) {
|
||||
RRMAlgorithm.AlgorithmResult result = algo.run(
|
||||
deviceDataManager,
|
||||
configManager,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
package com.facebook.openwifirrm.modules;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -23,48 +23,48 @@ public class RRMSchedulerTest {
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * * * * * *"));
|
||||
|
||||
// correct (6 fields)
|
||||
assertEquals(
|
||||
"* * * ? * *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * *")
|
||||
);
|
||||
|
||||
// correct (7 fields)
|
||||
assertEquals(
|
||||
"* * * ? * * *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * * *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * * *")
|
||||
);
|
||||
|
||||
// correct value other than * for day of month
|
||||
assertEquals(
|
||||
"* * * 1 * ?",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * 1 * ?" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1 * *")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * 1 * ? *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * 1 * ? *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1 * * *")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * 1/2 * ?",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * 1/2 * ?" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1/2 * *")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * 1/2 * ? *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * 1/2 * ? *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1/2 * * *")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * 1-2 * ?",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * 1-2 * ?" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1-2 * *")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * 1-2 * ? *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * 1-2 * ? *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1-2 * * *")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * 1,2 * ?",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * 1,2 * ?" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1,2 * *")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * 1,2 * ? *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * 1,2 * ? *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1,2 * * *")
|
||||
);
|
||||
|
||||
@@ -79,70 +79,70 @@ public class RRMSchedulerTest {
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0,1 * * *"));
|
||||
|
||||
// correct value other than * for day of month
|
||||
assertEquals(
|
||||
"* * * ? * 1",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 1 *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1 *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1 *")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 1/3",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1/3" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1/3")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 1/3 *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1/3 *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1/3 *")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 1-3",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1-3" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1-3")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 1-3 *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1-3 *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1-3 *")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 1,3",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1,3" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1,3")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 1,3 *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1,3 *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1,3 *")
|
||||
);
|
||||
|
||||
// correct value other than * for day of month, make sure 0 turns into 7
|
||||
assertEquals(
|
||||
"* * * ? * 7",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 7" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 0")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 7 *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 7 *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 0 *")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 1/7",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1/7" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1/0")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 1/7 *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1/7 *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1/0 *")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 1-7",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1-7" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1-0")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 1-7 *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1-7 *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1-0 *")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 1,7",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1,7" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1,0")
|
||||
);
|
||||
assertEquals(
|
||||
"* * * ? * 1,7 *",
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1,7 *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * * * 1,0 *")
|
||||
);
|
||||
|
||||
@@ -155,5 +155,119 @@ public class RRMSchedulerTest {
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * * * 7-8 *"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * * * 7,8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * * * 7,8 *"));
|
||||
|
||||
// correct value for both day of week and day of month
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 7", "* * * 1 * ?" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1 * 0")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 7 *", "* * * 1 * ? *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1 * 0 *")
|
||||
);
|
||||
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1/7", "* * * 1 * ?" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1 * 1/0")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1", "* * * 1/2 * ?" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1/2 * 1")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1/7", "* * * 1/2 * ?" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1/2 * 1/0")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1/7 *", "* * * 1 * ? *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1 * 1/0 *")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1 *", "* * * 1/2 * ? *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1/2 * 1 *")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1/7 *", "* * * 1/2 * ? *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1/2 * 1/0 *")
|
||||
);
|
||||
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1-7", "* * * 1 * ?" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1 * 1-0")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1", "* * * 1-3 * ?" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1-3 * 1")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1-7", "* * * 1-3 * ?" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1-3 * 1-0")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1-7 *", "* * * 1 * ? *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1 * 1-0 *")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1 *", "* * * 1-3 * ? *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1-3 * 1 *")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1-7 *", "* * * 1-3 * ? *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1-3 * 1-0 *")
|
||||
);
|
||||
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1-7", "* * * 1/3 * ?" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1/3 * 1-0")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1/7", "* * * 1-3 * ?" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1-3 * 1/0")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1-7 *", "* * * 1/3 * ? *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1/3 * 1-0 *")
|
||||
);
|
||||
assertArrayEquals(
|
||||
new String[] { "* * * ? * 1/7 *", "* * * 1-3 * ? *" },
|
||||
RRMScheduler.parseIntoQuartzCron("* * * 1-3 * 1/0 *")
|
||||
);
|
||||
|
||||
// wrong value for either day of week or day of month
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0 * 8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0 * 8 *"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0 * 7/8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0 * 7/8 *"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0 * 7-8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0 * 7-8 *"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0 * 7,8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0 * 7,8 *"));
|
||||
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0/1 * 8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0/1 * 8 *"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0/1 * 7/8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0/1 * 7/8 *"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0/1 * 7-8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0/1 * 7-8 *"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0/1 * 7,8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0/1 * 7,8 *"));
|
||||
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0-1 * 8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0-1 * 8 *"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0-1 * 7/8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0-1 * 7/8 *"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0-1 * 7-8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0-1 * 7-8 *"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0-1 * 7,8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0-1 * 7,8 *"));
|
||||
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0,1 * 8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0,1 * 8 *"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0,1 * 7/8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0,1 * 7/8 *"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0,1 * 7-8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0,1 * 7-8 *"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0,1 * 7,8"));
|
||||
assertNull(RRMScheduler.parseIntoQuartzCron("* * * 0,1 * 7,8 *"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user