Browse Source

[Bug] [Cron] Parse corn expression error (#13841)

* fix-cron

* update catch exception
3.2.0-release
旺阳 2 years ago committed by GitHub
parent
commit
61637cc0a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessDefinitionServiceImpl.java
  2. 7
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java
  3. 8
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/SchedulerServiceTest.java
  4. 20
      dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/cron/CronUtils.java
  5. 6
      dolphinscheduler-service/src/test/java/org/apache/dolphinscheduler/service/cron/CronUtilsTest.java

3
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessDefinitionServiceImpl.java

@ -122,6 +122,7 @@ import org.apache.dolphinscheduler.plugin.task.api.enums.TaskTimeoutStrategy;
import org.apache.dolphinscheduler.plugin.task.api.model.Property; import org.apache.dolphinscheduler.plugin.task.api.model.Property;
import org.apache.dolphinscheduler.plugin.task.api.parameters.ParametersNode; import org.apache.dolphinscheduler.plugin.task.api.parameters.ParametersNode;
import org.apache.dolphinscheduler.plugin.task.api.parameters.SqlParameters; import org.apache.dolphinscheduler.plugin.task.api.parameters.SqlParameters;
import org.apache.dolphinscheduler.service.cron.CronUtils;
import org.apache.dolphinscheduler.service.model.TaskNode; import org.apache.dolphinscheduler.service.model.TaskNode;
import org.apache.dolphinscheduler.service.process.ProcessService; import org.apache.dolphinscheduler.service.process.ProcessService;
@ -2607,7 +2608,7 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
putMsg(result, Status.SCHEDULE_START_TIME_END_TIME_SAME); putMsg(result, Status.SCHEDULE_START_TIME_END_TIME_SAME);
return result; return result;
} }
if (!org.quartz.CronExpression.isValidExpression(scheduleObj.getCrontab())) { if (!CronUtils.isValidExpression(scheduleObj.getCrontab())) {
log.error("CronExpression verify failure, cron:{}.", scheduleObj.getCrontab()); log.error("CronExpression verify failure, cron:{}.", scheduleObj.getCrontab());
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, scheduleObj.getCrontab()); putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, scheduleObj.getCrontab());
return result; return result;

7
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java

@ -75,7 +75,6 @@ import java.util.stream.Collectors;
import lombok.NonNull; import lombok.NonNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.quartz.CronExpression;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -182,7 +181,7 @@ public class SchedulerServiceImpl extends BaseServiceImpl implements SchedulerSe
scheduleObj.setStartTime(scheduleParam.getStartTime()); scheduleObj.setStartTime(scheduleParam.getStartTime());
scheduleObj.setEndTime(scheduleParam.getEndTime()); scheduleObj.setEndTime(scheduleParam.getEndTime());
if (!org.quartz.CronExpression.isValidExpression(scheduleParam.getCrontab())) { if (!CronUtils.isValidExpression(scheduleParam.getCrontab())) {
log.error("Schedule crontab verify failure, crontab:{}.", scheduleParam.getCrontab()); log.error("Schedule crontab verify failure, crontab:{}.", scheduleParam.getCrontab());
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, scheduleParam.getCrontab()); putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, scheduleParam.getCrontab());
return result; return result;
@ -238,7 +237,7 @@ public class SchedulerServiceImpl extends BaseServiceImpl implements SchedulerSe
if (scheduleParam.getStartTime().getTime() > scheduleParam.getEndTime().getTime()) { if (scheduleParam.getStartTime().getTime() > scheduleParam.getEndTime().getTime()) {
throw new ServiceException(Status.START_TIME_BIGGER_THAN_END_TIME_ERROR); throw new ServiceException(Status.START_TIME_BIGGER_THAN_END_TIME_ERROR);
} }
if (!CronExpression.isValidExpression(scheduleParam.getCrontab())) { if (!CronUtils.isValidExpression(scheduleParam.getCrontab())) {
throw new ServiceException(Status.SCHEDULE_CRON_CHECK_FAILED, scheduleParam.getCrontab()); throw new ServiceException(Status.SCHEDULE_CRON_CHECK_FAILED, scheduleParam.getCrontab());
} }
} }
@ -828,7 +827,7 @@ public class SchedulerServiceImpl extends BaseServiceImpl implements SchedulerSe
schedule.setStartTime(scheduleParam.getStartTime()); schedule.setStartTime(scheduleParam.getStartTime());
schedule.setEndTime(scheduleParam.getEndTime()); schedule.setEndTime(scheduleParam.getEndTime());
if (!org.quartz.CronExpression.isValidExpression(scheduleParam.getCrontab())) { if (!CronUtils.isValidExpression(scheduleParam.getCrontab())) {
log.error("Schedule crontab verify failure, crontab:{}.", scheduleParam.getCrontab()); log.error("Schedule crontab verify failure, crontab:{}.", scheduleParam.getCrontab());
putMsg(result, Status.SCHEDULE_CRON_CHECK_FAILED, scheduleParam.getCrontab()); putMsg(result, Status.SCHEDULE_CRON_CHECK_FAILED, scheduleParam.getCrontab());
return; return;

8
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/SchedulerServiceTest.java

@ -242,6 +242,14 @@ public class SchedulerServiceTest extends BaseServiceTestTool {
() -> schedulerService.createSchedulesV2(user, scheduleCreateRequest)); () -> schedulerService.createSchedulesV2(user, scheduleCreateRequest));
Assertions.assertEquals(Status.SCHEDULE_CRON_CHECK_FAILED.getCode(), ((ServiceException) exception).getCode()); Assertions.assertEquals(Status.SCHEDULE_CRON_CHECK_FAILED.getCode(), ((ServiceException) exception).getCode());
// error schedule crontab
String badCrontab2 = "0 0 13/0 * * ? *";
scheduleCreateRequest.setStartTime(startTime);
scheduleCreateRequest.setCrontab(badCrontab2);
exception = Assertions.assertThrows(ServiceException.class,
() -> schedulerService.createSchedulesV2(user, scheduleCreateRequest));
Assertions.assertEquals(Status.SCHEDULE_CRON_CHECK_FAILED.getCode(), ((ServiceException) exception).getCode());
// error create error // error create error
scheduleCreateRequest.setCrontab(crontab); scheduleCreateRequest.setCrontab(crontab);
Mockito.when(scheduleMapper.insert(isA(Schedule.class))).thenReturn(0); Mockito.when(scheduleMapper.insert(isA(Schedule.class))).thenReturn(0);

20
dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/cron/CronUtils.java

@ -79,11 +79,29 @@ public class CronUtils {
public static Cron parse2Cron(String cronExpression) throws CronParseException { public static Cron parse2Cron(String cronExpression) throws CronParseException {
try { try {
return QUARTZ_CRON_PARSER.parse(cronExpression); return QUARTZ_CRON_PARSER.parse(cronExpression);
} catch (Exception ex) { } catch (IllegalArgumentException ex) {
throw new CronParseException(String.format("Parse corn expression: [%s] error", cronExpression), ex); throw new CronParseException(String.format("Parse corn expression: [%s] error", cronExpression), ex);
} }
} }
/**
* Indicates whether the specified cron expression can be parsed into a
* valid cron expression
*
* @param cronExpression the expression to evaluate
* @return a boolean indicating whether the given expression is a valid cron
* expression
*/
public static boolean isValidExpression(String cronExpression) {
try {
parse2Cron(cronExpression);
} catch (CronParseException e) {
return false;
}
return true;
}
/** /**
* get max cycle * get max cycle
* *

6
dolphinscheduler-service/src/test/java/org/apache/dolphinscheduler/service/cron/CronUtilsTest.java

@ -245,4 +245,10 @@ public class CronUtilsTest {
expirationTime = CronUtils.getExpirationTime(startTime, CycleEnum.YEAR); expirationTime = CronUtils.getExpirationTime(startTime, CycleEnum.YEAR);
Assertions.assertEquals("2020-02-07 18:30:00", DateUtils.dateToString(expirationTime)); Assertions.assertEquals("2020-02-07 18:30:00", DateUtils.dateToString(expirationTime));
} }
@Test
public void testValid() {
Assertions.assertFalse(CronUtils.isValidExpression("0 0 13/0 * * ? *"));
Assertions.assertTrue(CronUtils.isValidExpression("0 0 13-0 * * ? *"));
}
} }

Loading…
Cancel
Save