This is an automated email from the ASF dual-hosted git repository.
chengshiwen pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new a925f64 [Feature][api] schedule add timezone support #5259 (#5465)
a925f64 is described below
commit a925f645719edec4afdb994ef57029c45c55d27e
Author: ruanwenjun <[email protected]>
AuthorDate: Mon May 17 21:08:20 2021 +0800
[Feature][api] schedule add timezone support #5259 (#5465)
* [Feature][api] schedule add timezone support #5259
* import moment-timezone
* fix code smell
---
.../api/controller/SchedulerController.java | 3 +-
.../dolphinscheduler/api/dto/ScheduleParam.java | 112 ++--
.../api/service/impl/SchedulerServiceImpl.java | 17 +-
.../dolphinscheduler/common/utils/DateUtils.java | 30 ++
.../common/utils/DateUtilsTest.java | 13 +
.../dolphinscheduler/dao/entity/Schedule.java | 567 +++++++++++----------
.../dolphinscheduler/dao/mapper/ScheduleMapper.xml | 4 +-
dolphinscheduler-dist/release-docs/LICENSE | 1 +
.../licenses/ui-licenses/LICENSE-moment-timezone | 20 +
.../service/quartz/QuartzExecutors.java | 45 +-
dolphinscheduler-ui/package.json | 1 +
.../pages/definition/pages/list/_source/timing.vue | 22 +-
.../src/js/module/i18n/locale/en_US.js | 1 +
.../src/js/module/i18n/locale/zh_CN.js | 1 +
sql/dolphinscheduler_mysql.sql | 1 +
sql/dolphinscheduler_postgre.sql | 1 +
.../1.4.0_schema/mysql/dolphinscheduler_ddl.sql | 20 +
.../postgresql/dolphinscheduler_ddl.sql | 17 +
18 files changed, 510 insertions(+), 366 deletions(-)
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/SchedulerController.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/SchedulerController.java
index 772fdce..20b668a 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/SchedulerController.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/SchedulerController.java
@@ -94,7 +94,8 @@ public class SchedulerController extends BaseController {
@ApiOperation(value = "createSchedule", notes = "CREATE_SCHEDULE_NOTES")
@ApiImplicitParams({
@ApiImplicitParam(name = "processDefinitionId", value =
"PROCESS_DEFINITION_ID", required = true, dataType = "Int", example = "100"),
- @ApiImplicitParam(name = "schedule", value = "SCHEDULE", dataType
= "String", example = "{'startTime':'2019-06-10 00:00:00','endTime':'2019-06-13
00:00:00','crontab':'0 0 3/6 * * ? *'}"),
+ @ApiImplicitParam(name = "schedule", value = "SCHEDULE", dataType
= "String",
+ example = "{'startTime':'2019-06-10
00:00:00','endTime':'2019-06-13
00:00:00','timezoneId':'America/Phoenix','crontab':'0 0 3/6 * * ? *'}"),
@ApiImplicitParam(name = "warningType", value = "WARNING_TYPE",
type = "WarningType"),
@ApiImplicitParam(name = "warningGroupId", value =
"WARNING_GROUP_ID", dataType = "Int", example = "100"),
@ApiImplicitParam(name = "failureStrategy", value =
"FAILURE_STRATEGY", type = "FailureStrategy"),
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/ScheduleParam.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/ScheduleParam.java
index a7cdfcf..6d957bf 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/ScheduleParam.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/dto/ScheduleParam.java
@@ -14,62 +14,74 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dolphinscheduler.api.dto;
-import com.fasterxml.jackson.annotation.JsonFormat;
+package org.apache.dolphinscheduler.api.dto;
import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
/**
* schedule parameters
*/
public class ScheduleParam {
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
- private Date startTime;
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
- private Date endTime;
- private String crontab;
-
- public ScheduleParam() {
- }
-
- public ScheduleParam(Date startTime, Date endTime, String crontab) {
- this.startTime = startTime;
- this.endTime = endTime;
- this.crontab = crontab;
- }
-
- public Date getStartTime() {
- return startTime;
- }
-
- public void setStartTime(Date startTime) {
- this.startTime = startTime;
- }
-
- public Date getEndTime() {
- return endTime;
- }
-
- public void setEndTime(Date endTime) {
- this.endTime = endTime;
- }
-
- public String getCrontab() {
- return crontab;
- }
-
- public void setCrontab(String crontab) {
- this.crontab = crontab;
- }
-
-
- @Override
- public String toString() {
- return "ScheduleParam{" +
- "startTime=" + startTime +
- ", endTime=" + endTime +
- ", crontab='" + crontab + '\'' +
- '}';
- }
+
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date startTime;
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date endTime;
+ private String crontab;
+ private String timezoneId;
+
+ public ScheduleParam() {
+ }
+
+ public ScheduleParam(Date startTime, Date endTime, String timezoneId,
String crontab) {
+ this.startTime = startTime;
+ this.endTime = endTime;
+ this.timezoneId = timezoneId;
+ this.crontab = crontab;
+ }
+
+ public Date getStartTime() {
+ return startTime;
+ }
+
+ public void setStartTime(Date startTime) {
+ this.startTime = startTime;
+ }
+
+ public Date getEndTime() {
+ return endTime;
+ }
+
+ public void setEndTime(Date endTime) {
+ this.endTime = endTime;
+ }
+
+ public String getCrontab() {
+ return crontab;
+ }
+
+ public void setCrontab(String crontab) {
+ this.crontab = crontab;
+ }
+
+ public String getTimezoneId() {
+ return timezoneId;
+ }
+
+ public void setTimezoneId(String timezoneId) {
+ this.timezoneId = timezoneId;
+ }
+
+ @Override
+ public String toString() {
+ return "ScheduleParam{"
+ + "startTime=" + startTime
+ + ", endTime=" + endTime
+ + ", crontab='" + crontab + '\''
+ + ", timezoneId='" + timezoneId + '\''
+ + '}';
+ }
}
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java
index 5955a44..5f17e80 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java
@@ -157,6 +157,7 @@ public class SchedulerServiceImpl extends BaseServiceImpl
implements SchedulerSe
return result;
}
scheduleObj.setCrontab(scheduleParam.getCrontab());
+ scheduleObj.setTimezoneId(scheduleParam.getTimezoneId());
scheduleObj.setWarningType(warningType);
scheduleObj.setWarningGroupId(warningGroupId);
scheduleObj.setFailureStrategy(failureStrategy);
@@ -258,6 +259,7 @@ public class SchedulerServiceImpl extends BaseServiceImpl
implements SchedulerSe
return result;
}
schedule.setCrontab(scheduleParam.getCrontab());
+ schedule.setTimezoneId(scheduleParam.getTimezoneId());
}
if (warningType != null) {
@@ -471,20 +473,9 @@ public class SchedulerServiceImpl extends BaseServiceImpl
implements SchedulerSe
}
public void setSchedule(int projectId, Schedule schedule) {
- int scheduleId = schedule.getId();
- logger.info("set schedule, project id: {}, scheduleId: {}", projectId,
scheduleId);
-
- Date startDate = schedule.getStartTime();
- Date endDate = schedule.getEndTime();
-
- String jobName = QuartzExecutors.buildJobName(scheduleId);
- String jobGroupName = QuartzExecutors.buildJobGroupName(projectId);
-
- Map<String, Object> dataMap = QuartzExecutors.buildDataMap(projectId,
scheduleId, schedule);
-
- QuartzExecutors.getInstance().addJob(ProcessScheduleJob.class,
jobName, jobGroupName, startDate, endDate,
- schedule.getCrontab(), dataMap);
+ logger.info("set schedule, project id: {}, scheduleId: {}", projectId,
schedule.getId());
+ QuartzExecutors.getInstance().addJob(ProcessScheduleJob.class,
projectId, schedule);
}
/**
diff --git
a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/DateUtils.java
b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/DateUtils.java
index c484dc0..6ea527a 100644
---
a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/DateUtils.java
+++
b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/DateUtils.java
@@ -22,9 +22,11 @@ import org.apache.dolphinscheduler.common.Constants;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
+import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
+import java.util.TimeZone;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -492,6 +494,34 @@ public class DateUtils {
return getCurrentTime(Constants.YYYYMMDDHHMMSSSSS);
}
+ /**
+ * transform date to target timezone date
+ * <p>e.g.
+ * <p> if input date is 2020-01-01 00:00:00 current timezone is CST
+ * <p>targetTimezoneId is MST
+ * <p>this method will return 2020-01-01 15:00:00
+ */
+ public static Date getTimezoneDate(Date date, String targetTimezoneId) {
+ if (StringUtils.isEmpty(targetTimezoneId)) {
+ return date;
+ }
+
+ String dateToString = dateToString(date);
+ LocalDateTime localDateTime = LocalDateTime.parse(dateToString,
DateTimeFormatter.ofPattern(Constants.YYYY_MM_DD_HH_MM_SS));
+ ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime,
TimeZone.getTimeZone(targetTimezoneId).toZoneId());
+ return Date.from(zonedDateTime.toInstant());
+ }
+
+ /**
+ * get timezone by timezoneId
+ */
+ public static TimeZone getTimezone(String timezoneId) {
+ if (StringUtils.isEmpty(timezoneId)) {
+ return null;
+ }
+ return TimeZone.getTimeZone(timezoneId);
+ }
+
static final long C0 = 1L;
static final long C1 = C0 * 1000L;
static final long C2 = C1 * 1000L;
diff --git
a/dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/DateUtilsTest.java
b/dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/DateUtilsTest.java
index 4a88085..38ab720 100644
---
a/dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/DateUtilsTest.java
+++
b/dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/DateUtilsTest.java
@@ -20,6 +20,7 @@ package org.apache.dolphinscheduler.common.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.TimeZone;
import org.junit.Assert;
import org.junit.Test;
@@ -204,4 +205,16 @@ public class DateUtilsTest {
Assert.assertNull(DateUtils.format2Duration(d1, d2));
}
+ @Test
+ public void testTransformToTimezone() {
+ Date date = new Date();
+ Date mst = DateUtils.getTimezoneDate(date,
TimeZone.getDefault().getID());
+ Assert.assertEquals(DateUtils.dateToString(date),
DateUtils.dateToString(mst));
+ }
+
+ @Test
+ public void testGetTimezone() {
+ Assert.assertNull(DateUtils.getTimezone(null));
+ Assert.assertEquals(TimeZone.getTimeZone("MST"),
DateUtils.getTimezone("MST"));
+ }
}
diff --git
a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/Schedule.java
b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/Schedule.java
index 5d2bc38..74ed5c1 100644
---
a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/Schedule.java
+++
b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/Schedule.java
@@ -14,13 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.apache.dolphinscheduler.dao.entity;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.dolphinscheduler.common.enums.FailureStrategy;
import org.apache.dolphinscheduler.common.enums.Priority;
import org.apache.dolphinscheduler.common.enums.ReleaseState;
@@ -28,6 +24,12 @@ import org.apache.dolphinscheduler.common.enums.WarningType;
import java.util.Date;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
/**
* schedule
*
@@ -35,278 +37,285 @@ import java.util.Date;
@TableName("t_ds_schedules")
public class Schedule {
- @TableId(value="id", type=IdType.AUTO)
- private int id;
- /**
- * process definition id
- */
- private int processDefinitionId;
-
- /**
- * process definition name
- */
- @TableField(exist = false)
- private String processDefinitionName;
-
- /**
- * project name
- */
- @TableField(exist = false)
- private String projectName;
-
- /**
- * schedule description
- */
- @TableField(exist = false)
- private String definitionDescription;
-
- /**
- * schedule start time
- */
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
- private Date startTime;
-
- /**
- * schedule end time
- */
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
- private Date endTime;
-
- /**
- * crontab expression
- */
- private String crontab;
-
- /**
- * failure strategy
- */
- private FailureStrategy failureStrategy;
-
- /**
- * warning type
- */
- private WarningType warningType;
-
- /**
- * create time
- */
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
- private Date createTime;
-
- /**
- * update time
- */
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
- private Date updateTime;
-
- /**
- * created user id
- */
- private int userId;
-
- /**
- * created user name
- */
- @TableField(exist = false)
- private String userName;
-
- /**
- * release state
- */
- private ReleaseState releaseState;
-
- /**
- * warning group id
- */
- private int warningGroupId;
-
-
- /**
- * process instance priority
- */
- private Priority processInstancePriority;
-
- /**
- * worker group
- */
- private String workerGroup;
-
- public int getWarningGroupId() {
- return warningGroupId;
- }
-
- public void setWarningGroupId(int warningGroupId) {
- this.warningGroupId = warningGroupId;
- }
-
-
-
- public Schedule() {
- }
-
- public String getProjectName() {
- return projectName;
- }
-
- public void setProjectName(String projectName) {
- this.projectName = projectName;
- }
-
-
-
- public Date getStartTime() {
-
- return startTime;
- }
-
- public void setStartTime(Date startTime) {
- this.startTime = startTime;
- }
-
- public Date getEndTime() {
- return endTime;
- }
-
- public void setEndTime(Date endTime) {
- this.endTime = endTime;
- }
-
- public String getCrontab() {
- return crontab;
- }
-
- public void setCrontab(String crontab) {
- this.crontab = crontab;
- }
-
- public FailureStrategy getFailureStrategy() {
- return failureStrategy;
- }
-
- public void setFailureStrategy(FailureStrategy failureStrategy) {
- this.failureStrategy = failureStrategy;
- }
-
- public WarningType getWarningType() {
- return warningType;
- }
-
- public void setWarningType(WarningType warningType) {
- this.warningType = warningType;
- }
-
- public Date getCreateTime() {
- return createTime;
- }
-
- public void setCreateTime(Date createTime) {
- this.createTime = createTime;
- }
-
-
- public ReleaseState getReleaseState() {
- return releaseState;
- }
-
- public void setReleaseState(ReleaseState releaseState) {
- this.releaseState = releaseState;
- }
-
-
-
- public int getProcessDefinitionId() {
- return processDefinitionId;
- }
-
- public void setProcessDefinitionId(int processDefinitionId) {
- this.processDefinitionId = processDefinitionId;
- }
-
- public String getProcessDefinitionName() {
- return processDefinitionName;
- }
-
- public void setProcessDefinitionName(String processDefinitionName) {
- this.processDefinitionName = processDefinitionName;
- }
-
- public Date getUpdateTime() {
- return updateTime;
- }
-
- public void setUpdateTime(Date updateTime) {
- this.updateTime = updateTime;
- }
-
- public int getUserId() {
- return userId;
- }
-
- public void setUserId(int userId) {
- this.userId = userId;
- }
-
- public String getUserName() {
- return userName;
- }
-
- public void setUserName(String userName) {
- this.userName = userName;
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public Priority getProcessInstancePriority() {
- return processInstancePriority;
- }
-
- public void setProcessInstancePriority(Priority processInstancePriority) {
- this.processInstancePriority = processInstancePriority;
- }
-
- public String getWorkerGroup() {
- return workerGroup;
- }
-
- public void setWorkerGroup(String workerGroup) {
- this.workerGroup = workerGroup;
- }
-
- @Override
- public String toString() {
- return "Schedule{" +
- "id=" + id +
- ", processDefinitionId=" + processDefinitionId +
- ", processDefinitionName='" + processDefinitionName + '\'' +
- ", projectName='" + projectName + '\'' +
- ", description='" + definitionDescription + '\'' +
- ", startTime=" + startTime +
- ", endTime=" + endTime +
- ", crontab='" + crontab + '\'' +
- ", failureStrategy=" + failureStrategy +
- ", warningType=" + warningType +
- ", createTime=" + createTime +
- ", updateTime=" + updateTime +
- ", userId=" + userId +
- ", userName='" + userName + '\'' +
- ", releaseState=" + releaseState +
- ", warningGroupId=" + warningGroupId +
- ", processInstancePriority=" + processInstancePriority +
- ", workerGroup='" + workerGroup + '\'' +
- '}';
- }
-
- public String getDefinitionDescription() {
- return definitionDescription;
- }
-
- public void setDefinitionDescription(String definitionDescription) {
- this.definitionDescription = definitionDescription;
- }
+ @TableId(value = "id", type = IdType.AUTO)
+ private int id;
+ /**
+ * process definition id
+ */
+ private int processDefinitionId;
+
+ /**
+ * process definition name
+ */
+ @TableField(exist = false)
+ private String processDefinitionName;
+
+ /**
+ * project name
+ */
+ @TableField(exist = false)
+ private String projectName;
+
+ /**
+ * schedule description
+ */
+ @TableField(exist = false)
+ private String definitionDescription;
+
+ /**
+ * schedule start time
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private Date startTime;
+
+ /**
+ * schedule end time
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private Date endTime;
+
+ /**
+ * timezoneId
+ * <p>see {@link java.util.TimeZone#getTimeZone(String)}
+ */
+ private String timezoneId;
+
+ /**
+ * crontab expression
+ */
+ private String crontab;
+
+ /**
+ * failure strategy
+ */
+ private FailureStrategy failureStrategy;
+
+ /**
+ * warning type
+ */
+ private WarningType warningType;
+
+ /**
+ * create time
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private Date createTime;
+
+ /**
+ * update time
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private Date updateTime;
+
+ /**
+ * created user id
+ */
+ private int userId;
+
+ /**
+ * created user name
+ */
+ @TableField(exist = false)
+ private String userName;
+
+ /**
+ * release state
+ */
+ private ReleaseState releaseState;
+
+ /**
+ * warning group id
+ */
+ private int warningGroupId;
+
+
+ /**
+ * process instance priority
+ */
+ private Priority processInstancePriority;
+
+ /**
+ * worker group
+ */
+ private String workerGroup;
+
+ public int getWarningGroupId() {
+ return warningGroupId;
+ }
+
+ public void setWarningGroupId(int warningGroupId) {
+ this.warningGroupId = warningGroupId;
+ }
+
+ public Schedule() {
+ }
+
+ public String getProjectName() {
+ return projectName;
+ }
+
+ public void setProjectName(String projectName) {
+ this.projectName = projectName;
+ }
+
+ public Date getStartTime() {
+ return startTime;
+ }
+
+ public void setStartTime(Date startTime) {
+ this.startTime = startTime;
+ }
+
+ public Date getEndTime() {
+ return endTime;
+ }
+
+ public void setEndTime(Date endTime) {
+ this.endTime = endTime;
+ }
+
+ public String getTimezoneId() {
+ return timezoneId;
+ }
+
+ public void setTimezoneId(String timezoneId) {
+ this.timezoneId = timezoneId;
+ }
+
+ public String getCrontab() {
+ return crontab;
+ }
+
+ public void setCrontab(String crontab) {
+ this.crontab = crontab;
+ }
+
+ public FailureStrategy getFailureStrategy() {
+ return failureStrategy;
+ }
+
+ public void setFailureStrategy(FailureStrategy failureStrategy) {
+ this.failureStrategy = failureStrategy;
+ }
+
+ public WarningType getWarningType() {
+ return warningType;
+ }
+
+ public void setWarningType(WarningType warningType) {
+ this.warningType = warningType;
+ }
+
+ public Date getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Date createTime) {
+ this.createTime = createTime;
+ }
+
+ public ReleaseState getReleaseState() {
+ return releaseState;
+ }
+
+ public void setReleaseState(ReleaseState releaseState) {
+ this.releaseState = releaseState;
+ }
+
+ public int getProcessDefinitionId() {
+ return processDefinitionId;
+ }
+
+ public void setProcessDefinitionId(int processDefinitionId) {
+ this.processDefinitionId = processDefinitionId;
+ }
+
+ public String getProcessDefinitionName() {
+ return processDefinitionName;
+ }
+
+ public void setProcessDefinitionName(String processDefinitionName) {
+ this.processDefinitionName = processDefinitionName;
+ }
+
+ public Date getUpdateTime() {
+ return updateTime;
+ }
+
+ public void setUpdateTime(Date updateTime) {
+ this.updateTime = updateTime;
+ }
+
+ public int getUserId() {
+ return userId;
+ }
+
+ public void setUserId(int userId) {
+ this.userId = userId;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public Priority getProcessInstancePriority() {
+ return processInstancePriority;
+ }
+
+ public void setProcessInstancePriority(Priority processInstancePriority) {
+ this.processInstancePriority = processInstancePriority;
+ }
+
+ public String getWorkerGroup() {
+ return workerGroup;
+ }
+
+ public void setWorkerGroup(String workerGroup) {
+ this.workerGroup = workerGroup;
+ }
+
+ @Override
+ public String toString() {
+ return "Schedule{"
+ + "id=" + id
+ + ", processDefinitionId=" + processDefinitionId
+ + ", processDefinitionName='" + processDefinitionName + '\''
+ + ", projectName='" + projectName + '\''
+ + ", description='" + definitionDescription + '\''
+ + ", startTime=" + startTime
+ + ", endTime=" + endTime
+ + ", timezoneId='" + timezoneId + +'\''
+ + ", crontab='" + crontab + '\''
+ + ", failureStrategy=" + failureStrategy
+ + ", warningType=" + warningType
+ + ", createTime=" + createTime
+ + ", updateTime=" + updateTime
+ + ", userId=" + userId
+ + ", userName='" + userName + '\''
+ + ", releaseState=" + releaseState
+ + ", warningGroupId=" + warningGroupId
+ + ", processInstancePriority=" + processInstancePriority
+ + ", workerGroup='" + workerGroup + '\''
+ + '}';
+ }
+
+ public String getDefinitionDescription() {
+ return definitionDescription;
+ }
+
+ public void setDefinitionDescription(String definitionDescription) {
+ this.definitionDescription = definitionDescription;
+ }
}
diff --git
a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ScheduleMapper.xml
b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ScheduleMapper.xml
index ae95655..587680f 100644
---
a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ScheduleMapper.xml
+++
b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ScheduleMapper.xml
@@ -19,11 +19,11 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="org.apache.dolphinscheduler.dao.mapper.ScheduleMapper">
<sql id="baseSql">
- id, process_definition_id, start_time, end_time, crontab,
failure_strategy, user_id, release_state,
+ id, process_definition_id, start_time, end_time, timezone_id, crontab,
failure_strategy, user_id, release_state,
warning_type, warning_group_id, process_instance_priority,
worker_group, create_time, update_time
</sql>
<sql id="baseSqlV2">
- ${alias}.id, ${alias}.process_definition_id, ${alias}.start_time,
${alias}.end_time, ${alias}.crontab, ${alias}.failure_strategy,
${alias}.user_id, ${alias}.release_state,
+ ${alias}.id, ${alias}.process_definition_id, ${alias}.start_time,
${alias}.end_time, ${alias}.timezone_id, ${alias}.crontab,
${alias}.failure_strategy, ${alias}.user_id, ${alias}.release_state,
${alias}.warning_type, ${alias}.warning_group_id,
${alias}.process_instance_priority, ${alias}.worker_group,
${alias}.create_time, ${alias}.update_time
</sql>
<select id="queryByProcessDefineIdPaging"
resultType="org.apache.dolphinscheduler.dao.entity.Schedule">
diff --git a/dolphinscheduler-dist/release-docs/LICENSE
b/dolphinscheduler-dist/release-docs/LICENSE
index bc18daf..2308359 100644
--- a/dolphinscheduler-dist/release-docs/LICENSE
+++ b/dolphinscheduler-dist/release-docs/LICENSE
@@ -539,6 +539,7 @@ MIT licenses
js-cookie 2.2.1: https://github.com/js-cookie/js-cookie MIT
jsplumb 2.8.6: https://github.com/jsplumb/jsplumb MIT and GPLv2
lodash 4.17.11: https://github.com/lodash/lodash MIT
+ moment-timezone 0.5.33: https://github.com/moment/moment-timezone MIT
vue-treeselect 0.4.0: https://github.com/riophae/vue-treeselect MIT
vue 2.5.17: https://github.com/vuejs/vue MIT
vue-router 2.7.0: https://github.com/vuejs/vue-router MIT
diff --git
a/dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-moment-timezone
b/dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-moment-timezone
new file mode 100644
index 0000000..f0bb3b4
--- /dev/null
+++
b/dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-moment-timezone
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) JS Foundation and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git
a/dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/quartz/QuartzExecutors.java
b/dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/quartz/QuartzExecutors.java
index 7f53f8e..487abad 100644
---
a/dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/quartz/QuartzExecutors.java
+++
b/dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/quartz/QuartzExecutors.java
@@ -60,6 +60,7 @@ import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
+import org.apache.dolphinscheduler.common.utils.DateUtils;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.common.utils.PropertyUtils;
import org.apache.dolphinscheduler.common.utils.StringUtils;
@@ -220,16 +221,18 @@ public class QuartzExecutors {
* add task trigger , if this task already exists, return this task with
updated trigger
*
* @param clazz job class name
- * @param jobName job name
- * @param jobGroupName job group name
- * @param startDate job start date
- * @param endDate job end date
- * @param cronExpression cron expression
- * @param jobDataMap job parameters data map
+ * @param projectId projectId
+ * @param schedule schedule
*/
- public void addJob(Class<? extends Job> clazz, String jobName, String
jobGroupName, Date startDate, Date endDate,
- String cronExpression,
- Map<String, Object> jobDataMap) {
+ public void addJob(Class<? extends Job> clazz, int projectId, final
Schedule schedule) {
+ String jobName = QuartzExecutors.buildJobName(schedule.getId());
+ String jobGroupName = QuartzExecutors.buildJobGroupName(projectId);
+ Date startDate = schedule.getStartTime();
+ Date endDate = schedule.getEndTime();
+ Map<String, Object> jobDataMap =
QuartzExecutors.buildDataMap(projectId, schedule);
+ String cronExpression = schedule.getCrontab();
+ String timezoneId = schedule.getTimezoneId();
+
lock.writeLock().lock();
try {
@@ -239,15 +242,11 @@ public class QuartzExecutors {
if (scheduler.checkExists(jobKey)) {
jobDetail = scheduler.getJobDetail(jobKey);
- if (jobDataMap != null) {
- jobDetail.getJobDataMap().putAll(jobDataMap);
- }
+ jobDetail.getJobDataMap().putAll(jobDataMap);
} else {
jobDetail = newJob(clazz).withIdentity(jobKey).build();
- if (jobDataMap != null) {
- jobDetail.getJobDataMap().putAll(jobDataMap);
- }
+ jobDetail.getJobDataMap().putAll(jobDataMap);
scheduler.addJob(jobDetail, false, true);
@@ -263,8 +262,15 @@ public class QuartzExecutors {
* current time (taking into account any associated Calendar),
* but it does not want to be fired now.
*/
- CronTrigger cronTrigger =
newTrigger().withIdentity(triggerKey).startAt(startDate).endAt(endDate)
-
.withSchedule(cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing())
+ CronTrigger cronTrigger = newTrigger()
+ .withIdentity(triggerKey)
+ .startAt(DateUtils.getTimezoneDate(startDate, timezoneId))
+ .endAt(DateUtils.getTimezoneDate(endDate, timezoneId))
+ .withSchedule(
+ cronSchedule(cronExpression)
+ .withMisfireHandlingInstructionDoNothing()
+
.inTimeZone(DateUtils.getTimezone(timezoneId))
+ )
.forJob(jobDetail).build();
if (scheduler.checkExists(triggerKey)) {
@@ -368,14 +374,13 @@ public class QuartzExecutors {
* add params to map
*
* @param projectId project id
- * @param scheduleId schedule id
* @param schedule schedule
* @return data map
*/
- public static Map<String, Object> buildDataMap(int projectId, int
scheduleId, Schedule schedule) {
+ public static Map<String, Object> buildDataMap(int projectId, Schedule
schedule) {
Map<String, Object> dataMap = new HashMap<>(8);
dataMap.put(PROJECT_ID, projectId);
- dataMap.put(SCHEDULE_ID, scheduleId);
+ dataMap.put(SCHEDULE_ID, schedule.getId());
dataMap.put(SCHEDULE, JSONUtils.toJsonString(schedule));
return dataMap;
diff --git a/dolphinscheduler-ui/package.json b/dolphinscheduler-ui/package.json
index 12a2cee..417dbad 100644
--- a/dolphinscheduler-ui/package.json
+++ b/dolphinscheduler-ui/package.json
@@ -33,6 +33,7 @@
"js-cookie": "^2.2.1",
"jsplumb": "^2.8.6",
"lodash": "^4.17.11",
+ "moment-timezone": "^0.5.33",
"normalize.css": "^8.0.1",
"remixicon": "^2.5.0",
"vue": "^2.5.17",
diff --git
a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/timing.vue
b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/timing.vue
index 9fa497f..08e06cd 100644
---
a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/timing.vue
+++
b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/timing.vue
@@ -62,6 +62,21 @@
</div>
</div>
<div class="clearfix list">
+ <div class="text">
+ {{$t('Timezone')}}
+ </div>
+ <div class="cont">
+ <el-select v-model=timezoneId filterable placeholder="Timezone">
+ <el-option
+ v-for="item in availableTimezoneIDList"
+ :key="item"
+ :label="item"
+ :value="item">
+ </el-option>
+ </el-select>
+ </div>
+ </div>
+ <div class="clearfix list">
<div style = "padding-left: 150px;">{{$t('Next five execution
times')}}</div>
<ul style = "padding-left: 150px;">
<li v-for="(time,i) in previewTimes" :key='i'>{{time}}</li>
@@ -144,6 +159,7 @@
</div>
</template>
<script>
+ import moment from 'moment-timezone'
import i18n from '@/module/i18n'
import store from '@/conf/home/store'
import { warningTypeList } from './util'
@@ -160,12 +176,14 @@
processDefinitionId: 0,
failureStrategy: 'CONTINUE',
warningTypeList: warningTypeList,
+ availableTimezoneIDList: moment.tz.names(),
warningType: 'NONE',
notifyGroupList: [],
warningGroupId: '',
spinnerLoading: false,
scheduleTime: '',
crontab: '0 0 * * * ? *',
+ timezoneId: moment.tz.guess(),
cronPopover: false,
i18n: i18n.globalScope.LOCALE,
processInstancePriority: 'MEDIUM',
@@ -204,7 +222,8 @@
schedule: JSON.stringify({
startTime: this.scheduleTime[0],
endTime: this.scheduleTime[1],
- crontab: this.crontab
+ crontab: this.crontab,
+ timezoneId: this.timezoneId
}),
failureStrategy: this.failureStrategy,
warningType: this.warningType,
@@ -323,6 +342,7 @@
if (this.timingData.item.crontab) {
this.crontab = item.crontab
this.scheduleTime = [formatDate(item.startTime),
formatDate(item.endTime)]
+ this.timezoneId = item.timezoneId === null ? moment.tz.guess() :
item.timezoneId
this.failureStrategy = item.failureStrategy
this.warningType = item.warningType
this.processInstancePriority = item.processInstancePriority
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
index 0ee852c..bc05c65 100755
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
+++ b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
@@ -399,6 +399,7 @@ export default {
'Import process': 'Import process',
'Timing state': 'Timing state',
Timing: 'Timing',
+ Timezone: 'Timezone',
TreeView: 'TreeView',
'Mailbox already exists! Recipients and copyers cannot repeat': 'Mailbox
already exists! Recipients and copyers cannot repeat',
'Mailbox input is illegal': 'Mailbox input is illegal',
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
index d67113a..478f675 100755
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
+++ b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
@@ -399,6 +399,7 @@ export default {
'Import process': '导入工作流',
'Timing state': '定时状态',
Timing: '定时',
+ Timezone: '时区',
TreeView: '树形图',
'Mailbox already exists! Recipients and copyers cannot repeat':
'邮箱已存在!收件人和抄送人不能重复',
'Mailbox input is illegal': '邮箱输入不合法',
diff --git a/sql/dolphinscheduler_mysql.sql b/sql/dolphinscheduler_mysql.sql
index 864b327..47fe310 100644
--- a/sql/dolphinscheduler_mysql.sql
+++ b/sql/dolphinscheduler_mysql.sql
@@ -750,6 +750,7 @@ CREATE TABLE `t_ds_schedules` (
`process_definition_id` int(11) NOT NULL COMMENT 'process definition id',
`start_time` datetime NOT NULL COMMENT 'start time',
`end_time` datetime NOT NULL COMMENT 'end time',
+ `timezone_id` varchar(40) DEFAULT NULL COMMENT 'timezoneId',
`crontab` varchar(256) NOT NULL COMMENT 'crontab description',
`failure_strategy` tinyint(4) NOT NULL COMMENT 'failure strategy.
0:end,1:continue',
`user_id` int(11) NOT NULL COMMENT 'user id',
diff --git a/sql/dolphinscheduler_postgre.sql b/sql/dolphinscheduler_postgre.sql
index fd9c1ec..f9299cd 100644
--- a/sql/dolphinscheduler_postgre.sql
+++ b/sql/dolphinscheduler_postgre.sql
@@ -614,6 +614,7 @@ CREATE TABLE t_ds_schedules (
process_definition_id int NOT NULL ,
start_time timestamp NOT NULL ,
end_time timestamp NOT NULL ,
+ timezone_id varchar(40) default NULL ,
crontab varchar(256) NOT NULL ,
failure_strategy int NOT NULL ,
user_id int NOT NULL ,
diff --git a/sql/upgrade/1.4.0_schema/mysql/dolphinscheduler_ddl.sql
b/sql/upgrade/1.4.0_schema/mysql/dolphinscheduler_ddl.sql
index 744294a..b9d9c72 100644
--- a/sql/upgrade/1.4.0_schema/mysql/dolphinscheduler_ddl.sql
+++ b/sql/upgrade/1.4.0_schema/mysql/dolphinscheduler_ddl.sql
@@ -316,6 +316,26 @@ d//
delimiter ;
CALL uc_dolphin_T_t_ds_datasource_A_add_UN_datasourceName();
DROP PROCEDURE uc_dolphin_T_t_ds_datasource_A_add_UN_datasourceName;
+
+-- uc_dolphin_T_t_ds_schedules_A_add_timezone
+drop PROCEDURE if EXISTS uc_dolphin_T_t_ds_schedules_A_add_timezone;
+delimiter d//
+CREATE PROCEDURE uc_dolphin_T_t_ds_schedules_A_add_timezone()
+BEGIN
+ IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS
+ WHERE TABLE_NAME='t_ds_schedules'
+ AND TABLE_SCHEMA=(SELECT DATABASE())
+ AND COLUMN_NAME ='timezone_id')
+ THEN
+ ALTER TABLE t_ds_schedules ADD COLUMN `timezone_id` varchar(40)
default NULL COMMENT 'schedule timezone id' AFTER `end_time`;
+ END IF;
+END;
+
+d//
+
+delimiter ;
+CALL uc_dolphin_T_t_ds_schedules_A_add_timezone();
+DROP PROCEDURE uc_dolphin_T_t_ds_schedules_A_add_timezone;
-- ----------------------------
-- These columns will not be used in the new version,if you determine that the
historical data is useless, you can delete it using the sql below
-- ----------------------------
diff --git a/sql/upgrade/1.4.0_schema/postgresql/dolphinscheduler_ddl.sql
b/sql/upgrade/1.4.0_schema/postgresql/dolphinscheduler_ddl.sql
index 13aa298..0fadd71 100644
--- a/sql/upgrade/1.4.0_schema/postgresql/dolphinscheduler_ddl.sql
+++ b/sql/upgrade/1.4.0_schema/postgresql/dolphinscheduler_ddl.sql
@@ -304,6 +304,23 @@ delimiter ;
SELECT uc_dolphin_T_t_ds_datasource_A_add_UN_datasourceName();
DROP FUNCTION IF EXISTS uc_dolphin_T_t_ds_datasource_A_add_UN_datasourceName();
+-- uc_dolphin_T_t_ds_schedules_A_add_timezone
+delimiter d//
+CREATE OR REPLACE FUNCTION uc_dolphin_T_t_ds_schedules_A_add_timezone()
RETURNS void AS $$
+BEGIN
+ IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS
+ WHERE TABLE_NAME='t_ds_schedules'
+ AND COLUMN_NAME ='timezone_id')
+ THEN
+ALTER TABLE t_ds_schedules ADD COLUMN timezone_id varchar(40) DEFAULT NULL;
+END IF;
+END;
+$$ LANGUAGE plpgsql;
+d//
+
+delimiter ;
+SELECT uc_dolphin_T_t_ds_schedules_A_add_timezone();
+DROP FUNCTION IF EXISTS uc_dolphin_T_t_ds_schedules_A_add_timezone();
-- ----------------------------
-- These columns will not be used in the new version,if you determine that the
historical data is useless, you can delete it using the sql below
-- ----------------------------