diff --git a/docs/src/main/asciidoc/scheduler-reference.adoc b/docs/src/main/asciidoc/scheduler-reference.adoc index 134e3bef9407a..b2374725ae3a1 100644 --- a/docs/src/main/asciidoc/scheduler-reference.adoc +++ b/docs/src/main/asciidoc/scheduler-reference.adoc @@ -164,7 +164,7 @@ void myMethod() { } An interval trigger defines a period between invocations. The period expression is based on the ISO-8601 duration format `PnDTnHnMn.nS` and the value of `@Scheduled#every()` is parsed with `java.time.Duration#parse(CharSequence)`. -However, if an expression starts with a digit then the `PT` prefix is added automatically. +However, if an expression starts with a digit and ends with `d`, `P` prefix will be added automatically. If the expression only starts with a digit, `PT` prefix is added automatically. So for example, `15m` can be used instead of `PT15M` and is parsed as "15 minutes". .Interval Trigger Example @@ -237,7 +237,7 @@ NOTE: The final value is always rounded to full second. `@Scheduled#delayed()` is a text alternative to the properties above. The period expression is based on the ISO-8601 duration format `PnDTnHnMn.nS` and the value is parsed with `java.time.Duration#parse(CharSequence)`. -However, if an expression starts with a digit, the `PT` prefix is added automatically. +However, if an expression starts with a digit and ends with `d`, `P` prefix will be added automatically. If the expression only starts with a digit, `PT` prefix is added automatically. So for example, `15s` can be used instead of `PT15S` and is parsed as "15 seconds". [source,java] diff --git a/extensions/scheduler/api/src/main/java/io/quarkus/scheduler/Scheduled.java b/extensions/scheduler/api/src/main/java/io/quarkus/scheduler/Scheduled.java index 0353c8c401bbe..e13e64c127ae2 100644 --- a/extensions/scheduler/api/src/main/java/io/quarkus/scheduler/Scheduled.java +++ b/extensions/scheduler/api/src/main/java/io/quarkus/scheduler/Scheduled.java @@ -95,7 +95,8 @@ /** * Defines the period between invocations. *
- * The value is parsed with {@link Duration#parse(CharSequence)}. However, if an expression starts with a digit, "PT" prefix + * The value is parsed with {@link Duration#parse(CharSequence)}. However, if an expression starts with a digit and ends + * with 'd', "P" prefix will be added automatically. If the expression only starts with a digit, "PT" prefix * is added automatically, so for example, {@code 15m} can be used instead of {@code PT15M} and is parsed as "15 minutes". * Note that the absolute value of the value is always used. *
@@ -135,7 +136,8 @@ * Defines a period after which the trigger should start. It's an alternative to {@link #delay()}. If {@link #delay()} is * set to a value greater than zero the value of {@link #delayed()} is ignored. *
- * The value is parsed with {@link Duration#parse(CharSequence)}. However, if an expression starts with a digit, "PT" prefix + * The value is parsed with {@link Duration#parse(CharSequence)}. However, if an expression starts with a digit and ends + * with 'd', "P" prefix will be added automatically. If the expression only starts with a digit, "PT" prefix * is added automatically, so for example, {@code 15s} can be used instead of {@code PT15S} and is parsed as "15 seconds". * Note that the absolute value of the value is always used. *
@@ -171,7 +173,8 @@ /** * Defines a period after which the job is considered overdue. *
- * The value is parsed with {@link Duration#parse(CharSequence)}. However, if an expression starts with a digit, "PT" prefix + * The value is parsed with {@link Duration#parse(CharSequence)}. HHowever, if an expression starts with a digit and ends + * with 'd', "P" prefix will be added automatically. If the expression only starts with a digit, "PT" prefix * is added automatically, so for example, {@code 15m} can be used instead of {@code PT15M} and is parsed as "15 minutes". * Note that the absolute value of the value is always used. *
diff --git a/extensions/scheduler/common/src/main/java/io/quarkus/scheduler/common/runtime/util/SchedulerUtils.java b/extensions/scheduler/common/src/main/java/io/quarkus/scheduler/common/runtime/util/SchedulerUtils.java index 9b6181c1c4970..39de16105895c 100644 --- a/extensions/scheduler/common/src/main/java/io/quarkus/scheduler/common/runtime/util/SchedulerUtils.java +++ b/extensions/scheduler/common/src/main/java/io/quarkus/scheduler/common/runtime/util/SchedulerUtils.java @@ -175,7 +175,11 @@ private static long parseDurationAsMillis(Scheduled scheduled, String value, Str private static Duration parseDuration(Scheduled scheduled, String value, String memberName) { if (Character.isDigit(value.charAt(0))) { - value = "PT" + value; + if (Character.toLowerCase(value.charAt(value.length() - 1)) == 'd') { + value = "P" + value; + } else { + value = "PT" + value; + } } try { diff --git a/extensions/scheduler/common/src/test/java/io/quarkus/scheduler/common/runtime/util/SchedulerUtilsTest.java b/extensions/scheduler/common/src/test/java/io/quarkus/scheduler/common/runtime/util/SchedulerUtilsTest.java index a88b726cc3f58..09083fce197d2 100644 --- a/extensions/scheduler/common/src/test/java/io/quarkus/scheduler/common/runtime/util/SchedulerUtilsTest.java +++ b/extensions/scheduler/common/src/test/java/io/quarkus/scheduler/common/runtime/util/SchedulerUtilsTest.java @@ -1,8 +1,13 @@ package io.quarkus.scheduler.common.runtime.util; +import java.lang.annotation.Annotation; +import java.util.concurrent.TimeUnit; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import io.quarkus.scheduler.Scheduled; + public class SchedulerUtilsTest { @Test @@ -62,4 +67,73 @@ void testDefaultValueNestedJBossStyle() { Assertions.assertEquals("MY_DEFAULT_VALUE", SchedulerUtils.lookUpPropertyValue("${non.existing.property1:${non.existing.property2:MY_DEFAULT_VALUE}}")); } + + @Test + void testParseDurationPeriodString() { + Assertions.assertEquals(24 * 60 * 60 * 1000, SchedulerUtils.parseDelayedAsMillis(createScheduledDelayed("P1D"))); + } + + @Test + void testParseDurationPeriod() { + Assertions.assertEquals(24 * 60 * 60 * 1000, SchedulerUtils.parseDelayedAsMillis(createScheduledDelayed("1d"))); + } + + @Test + void testParseDurationPeriodOfTimeString() { + Assertions.assertEquals(2 * 60 * 60 * 1000, SchedulerUtils.parseDelayedAsMillis(createScheduledDelayed("PT2H"))); + } + + @Test + void testParseDurationPeriodOfTime() { + Assertions.assertEquals(2 * 60 * 60 * 1000, SchedulerUtils.parseDelayedAsMillis(createScheduledDelayed("2h"))); + } + + private Scheduled createScheduledDelayed(String delayed) { + return new Scheduled() { + + public Class extends Annotation> annotationType() { + return null; + } + + public long delay() { + return 0; + } + + public TimeUnit delayUnit() { + return TimeUnit.MINUTES; + } + + public ConcurrentExecution concurrentExecution() { + return ConcurrentExecution.PROCEED; + } + + public String timeZone() { + return Scheduled.DEFAULT_TIMEZONE; + } + + public String identity() { + return ""; + } + + public String every() { + return ""; + } + + public String cron() { + return ""; + } + + public String overdueGracePeriod() { + return ""; + } + + public Class extends SkipPredicate> skipExecutionIf() { + return Never.class; + } + + public String delayed() { + return delayed; + } + }; + } }