Skip to content

Commit

Permalink
JBPM-5886: Add support for ISO_8601 repeating intervals (#819)
Browse files Browse the repository at this point in the history
  • Loading branch information
sutaakar authored and mswiderski committed Apr 18, 2017
1 parent 5c99a8d commit d98a34d
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 14 deletions.
Expand Up @@ -57,8 +57,6 @@ public static long parseDateTime(String dateTimeStr) {
public static long parseDuration(String durationStr) {
if (isPeriod(durationStr)) {
return Duration.parse(durationStr).toMillis();
} else if (DateTimeUtils.isNumeric(durationStr)) {
return Long.valueOf(durationStr);
} else {
return TimeUtils.parseTimeString(durationStr);
}
Expand Down Expand Up @@ -101,25 +99,33 @@ public static long[] parseRepeatableDateTime(String dateTimeStr) {
String periodIn = parsed[2];

Duration startAtDelayDur = null;
if (DateTimeUtils.isNumeric(delayIn)) {
startAtDelayDur = Duration.of(Long.valueOf(delayIn), ChronoUnit.MILLIS);
Duration period = null;

if (DateTimeUtils.isPeriod(delayIn)) {
// If delay is specified as duration then period variable carry end time information
OffsetDateTime endTime = OffsetDateTime.parse(periodIn, DateTimeFormatter.ISO_DATE_TIME);
period = Duration.parse(delayIn);
startAtDelayDur = Duration.between(OffsetDateTime.now(), endTime.minus(period));

} else if (DateTimeUtils.isPeriod(periodIn)) {
// If period is specified as duration then delay variable carry start time information
OffsetDateTime startTime = OffsetDateTime.parse(delayIn, DateTimeFormatter.ISO_DATE_TIME);
period = Duration.parse(periodIn);
startAtDelayDur = Duration.between(OffsetDateTime.now(), startTime);

} else {
OffsetDateTime startAtDelay = OffsetDateTime.parse(delayIn, DateTimeFormatter.ISO_DATE_TIME);
startAtDelayDur = Duration.between(OffsetDateTime.now(), startAtDelay);
// Both delay and period are specified as start and end times
OffsetDateTime startTime = OffsetDateTime.parse(delayIn, DateTimeFormatter.ISO_DATE_TIME);
OffsetDateTime endTime = OffsetDateTime.parse(periodIn, DateTimeFormatter.ISO_DATE_TIME);
startAtDelayDur = Duration.between(OffsetDateTime.now(), startTime);
period = Duration.between(startTime, endTime);
}

if (startAtDelayDur.isNegative() || startAtDelayDur.isZero()) {
// need to introduce delay to allow all initialization
startAtDelayDur = Duration.of(1, ChronoUnit.SECONDS);
}

Duration period = null;
if (DateTimeUtils.isNumeric(periodIn)) {
period = Duration.of(Long.valueOf(periodIn), ChronoUnit.MILLIS);
} else {
period = Duration.parse(periodIn);
}

result[0] = Long.parseLong(repeats.length()==0?"-1":repeats);
result[1] = startAtDelayDur.toMillis();
result[2] = period.toMillis();
Expand Down
@@ -0,0 +1,134 @@
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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.jbpm.process.core.timer;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

import org.jbpm.test.util.AbstractBaseTest;
import org.junit.Test;
import org.slf4j.LoggerFactory;

public class DateTimeUtilsTest extends AbstractBaseTest {

private static final long MINUTE_IN_MILLISECONDS = 60 * 1000L;
private static final long FIFTY_NINE_SECONDS_IN_MILLISECONDS = 59 * 1000L;
private static final long HOUR_IN_MILLISECONDS = 60 * 60 * 1000L;

public void addLogger() {
logger = LoggerFactory.getLogger(this.getClass());
}

@Test
public void testParseDateTime() {
OffsetDateTime hourAfterEpoch = OffsetDateTime.of(1970, 1, 1, 1, 0, 0, 0, ZoneOffset.UTC);

long parsedMilliseconds = DateTimeUtils.parseDateTime(hourAfterEpoch.format(DateTimeFormatter.ISO_DATE_TIME));

assertEquals(HOUR_IN_MILLISECONDS, parsedMilliseconds);
}

@Test
public void testParseDuration() {
long parsedMilliseconds = DateTimeUtils.parseDuration("1h");

assertEquals(HOUR_IN_MILLISECONDS, parsedMilliseconds);
}

@Test
public void testParseDurationPeriodFormat() {
long parsedMilliseconds = DateTimeUtils.parseDuration("PT1H");

assertEquals(HOUR_IN_MILLISECONDS, parsedMilliseconds);
}

@Test
public void testParseDurationDefaultMilliseconds() {
long parsedMilliseconds = DateTimeUtils.parseDuration(Long.toString(HOUR_IN_MILLISECONDS));

assertEquals(HOUR_IN_MILLISECONDS, parsedMilliseconds);
}

@Test
public void testParseDateAsDuration() {
OffsetDateTime oneMinuteFromNow = OffsetDateTime.now().plusMinutes(1);

long parsedMilliseconds = DateTimeUtils.parseDateAsDuration(oneMinuteFromNow.format(DateTimeFormatter.ISO_DATE_TIME));

assertTrue("Parsed date as duration is bigger than " + MINUTE_IN_MILLISECONDS, parsedMilliseconds <= MINUTE_IN_MILLISECONDS);
assertTrue("Parsed date as duration is too low! Expected value is between " + MINUTE_IN_MILLISECONDS + " and " + FIFTY_NINE_SECONDS_IN_MILLISECONDS + " but is " + parsedMilliseconds, parsedMilliseconds > FIFTY_NINE_SECONDS_IN_MILLISECONDS);
}

@Test
public void testParseRepeatableStartEndDateTime() {
OffsetDateTime oneMinuteFromNow = OffsetDateTime.now().plusMinutes(1);
OffsetDateTime twoMinutesFromNow = oneMinuteFromNow.plusMinutes(1);
String oneMinuteFromNowFormatted = oneMinuteFromNow.format(DateTimeFormatter.ISO_DATE_TIME);
String twoMinutesFromNowFormatted = twoMinutesFromNow.format(DateTimeFormatter.ISO_DATE_TIME);
String isoString = "R5/" + oneMinuteFromNowFormatted + "/" + twoMinutesFromNowFormatted;

long[] parsedRepeatable = DateTimeUtils.parseRepeatableDateTime(isoString);

assertEquals(5L, parsedRepeatable[0]);
assertTrue("Parsed delay is bigger than " + MINUTE_IN_MILLISECONDS, parsedRepeatable[1] <= MINUTE_IN_MILLISECONDS);
assertTrue("Parsed delay is too low! Expected value is between " + MINUTE_IN_MILLISECONDS + " and " + FIFTY_NINE_SECONDS_IN_MILLISECONDS + " but is " + parsedRepeatable[1], parsedRepeatable[1] > FIFTY_NINE_SECONDS_IN_MILLISECONDS);
assertEquals("Parsed period should be one minute in milliseconds but is " + parsedRepeatable[2], MINUTE_IN_MILLISECONDS, parsedRepeatable[2]);
}

@Test
public void testParseRepeatableStartDateTimeAndPeriod() {
OffsetDateTime oneMinuteFromNow = OffsetDateTime.now().plusMinutes(1);
String oneMinuteFromNowFormatted = oneMinuteFromNow.format(DateTimeFormatter.ISO_DATE_TIME);
String isoString = "R5/" + oneMinuteFromNowFormatted + "/PT1M";

long[] parsedRepeatable = DateTimeUtils.parseRepeatableDateTime(isoString);

assertEquals(5L, parsedRepeatable[0]);
assertTrue("Parsed delay is bigger than " + MINUTE_IN_MILLISECONDS, parsedRepeatable[1] <= MINUTE_IN_MILLISECONDS);
assertTrue("Parsed delay is too low! Expected value is between " + MINUTE_IN_MILLISECONDS + " and " + FIFTY_NINE_SECONDS_IN_MILLISECONDS + " but is " + parsedRepeatable[1], parsedRepeatable[1] > FIFTY_NINE_SECONDS_IN_MILLISECONDS);
assertEquals("Parsed period should be one minute in milliseconds but is " + parsedRepeatable[2], MINUTE_IN_MILLISECONDS, parsedRepeatable[2]);
}

@Test
public void testParseRepeatablePeriodAndEndDateTime() {
OffsetDateTime twoMinutesFromNow = OffsetDateTime.now().plusMinutes(2);
String twoMinutesFromNowFormatted = twoMinutesFromNow.format(DateTimeFormatter.ISO_DATE_TIME);
String isoString = "R5/PT1M/" + twoMinutesFromNowFormatted;

long[] parsedRepeatable = DateTimeUtils.parseRepeatableDateTime(isoString);

assertEquals(5L, parsedRepeatable[0]);
assertTrue("Parsed delay is bigger than " + MINUTE_IN_MILLISECONDS, parsedRepeatable[1] <= MINUTE_IN_MILLISECONDS);
assertTrue("Parsed delay is too low! Expected value is between " + MINUTE_IN_MILLISECONDS + " and " + FIFTY_NINE_SECONDS_IN_MILLISECONDS + " but is " + parsedRepeatable[1], parsedRepeatable[1] > FIFTY_NINE_SECONDS_IN_MILLISECONDS);
assertEquals("Parsed period should be one minute in milliseconds but is " + parsedRepeatable[2], MINUTE_IN_MILLISECONDS, parsedRepeatable[2]);
}

@Test
public void testParseRepeatablePeriodOnly() {
String isoString = "R/PT1M";

long[] parsedRepeatable = DateTimeUtils.parseRepeatableDateTime(isoString);

assertEquals(-1L, parsedRepeatable[0]);
// Default delay time is 1000ms
assertEquals(1000L, parsedRepeatable[1]);
assertEquals("Parsed period should be one minute in milliseconds but is " + parsedRepeatable[2], MINUTE_IN_MILLISECONDS, parsedRepeatable[2]);
}
}
Expand Up @@ -179,7 +179,7 @@ private void testStartProcess(RuntimeEngine runtime) throws Exception {
logger.debug("Starting process on ksession {}", runtime.getKieSession().getIdentifier());
Map<String, Object> params = new HashMap<String, Object>();

params.put("x", "R2/" + wait + "/PT1S");
params.put("x", "R2/PT1S");
ProcessInstance processInstance = runtime.getKieSession().startProcess("IntermediateCatchEvent", params);
logger.debug("Started process instance {} on ksession {}", processInstance.getId(), runtime.getKieSession().getIdentifier());
ut.commit();
Expand Down

0 comments on commit d98a34d

Please sign in to comment.