upgrade(xxl-job): 2.4.2

This commit is contained in:
冷冷 committed 2024-11-25 13:41:10 +08:00
1 parent 8d0f99e781
commit 8e4383ffea
25 files changed
+350 -135

No files matched your search

+1 -1
View File
@@ -40,7 +40,7 @@
<flowable.version>6.8.0</flowable.version>
<security.oauth.version>2.5.2.RELEASE</security.oauth.version>
<fastjson.version>1.2.83</fastjson.version>
<xxl.job.version>2.3.0</xxl.job.version>
<xxl.job.version>2.4.2</xxl.job.version>
<aliyun.version>3.0.52.ALL</aliyun.version>
<aws.version>1.12.261</aws.version>
<javers.version>6.14.0</javers.version>
+19 -2
View File
@@ -11,10 +11,12 @@
<description>xxl job admin 控制台内置方便开发</description>
<packaging>jar</packaging>
<properties>
<mybatis-spring-boot-starter.version>2.3.0</mybatis-spring-boot-starter.version>
<mybatis-spring-boot-starter.version>3.0.3</mybatis-spring-boot-starter.version>
</properties>
<dependencies>
<!--注册中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
@@ -64,8 +66,9 @@
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<artifactId>druid-spring-boot-3-starter</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
@@ -88,6 +91,19 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
@@ -137,4 +153,5 @@
</resource>
</resources>
</build>
</project>
@@ -1,8 +1,8 @@
package com.xxl.job.admin.controller;
import com.xxl.job.admin.controller.annotation.PermissionLimit;
import com.xxl.job.admin.service.LoginService;
import com.xxl.job.admin.service.XxlJobService;
import com.xxl.job.admin.service.impl.LoginService;
import com.xxl.job.core.biz.model.ReturnT;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
@@ -1,5 +1,6 @@
package com.xxl.job.admin.controller;
import com.xxl.job.admin.controller.interceptor.PermissionInterceptor;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobLogGlue;
import com.xxl.job.admin.core.util.I18nUtil;
@@ -45,7 +46,7 @@ public class JobCodeController {
}
// valid permission
JobInfoController.validPermission(request, jobInfo.getJobGroup());
PermissionInterceptor.validJobGroupPermission(request, jobInfo.getJobGroup());
// Glue类型-字典
model.addAttribute("GlueTypeEnum", GlueTypeEnum.values());
@@ -57,7 +58,7 @@ public class JobCodeController {
@RequestMapping("/save")
@ResponseBody
public ReturnT<String> save(Model model, int id, String glueSource, String glueRemark) {
public ReturnT<String> save(HttpServletRequest request, int id, String glueSource, String glueRemark) {
// valid
if (glueRemark == null) {
return new ReturnT<String>(500,
@@ -66,23 +67,26 @@ public class JobCodeController {
if (glueRemark.length() < 4 || glueRemark.length() > 100) {
return new ReturnT<String>(500, I18nUtil.getString("jobinfo_glue_remark_limit"));
}
XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(id);
if (exists_jobInfo == null) {
XxlJobInfo existsJobInfo = xxlJobInfoDao.loadById(id);
if (existsJobInfo == null) {
return new ReturnT<String>(500, I18nUtil.getString("jobinfo_glue_jobid_unvalid"));
}
// update new code
exists_jobInfo.setGlueSource(glueSource);
exists_jobInfo.setGlueRemark(glueRemark);
exists_jobInfo.setGlueUpdatetime(new Date());
// valid permission
PermissionInterceptor.validJobGroupPermission(request, existsJobInfo.getJobGroup());
exists_jobInfo.setUpdateTime(new Date());
xxlJobInfoDao.update(exists_jobInfo);
// update new code
existsJobInfo.setGlueSource(glueSource);
existsJobInfo.setGlueRemark(glueRemark);
existsJobInfo.setGlueUpdatetime(new Date());
existsJobInfo.setUpdateTime(new Date());
xxlJobInfoDao.update(existsJobInfo);
// log old code
XxlJobLogGlue xxlJobLogGlue = new XxlJobLogGlue();
xxlJobLogGlue.setJobId(exists_jobInfo.getId());
xxlJobLogGlue.setGlueType(exists_jobInfo.getGlueType());
xxlJobLogGlue.setJobId(existsJobInfo.getId());
xxlJobLogGlue.setGlueType(existsJobInfo.getGlueType());
xxlJobLogGlue.setGlueSource(glueSource);
xxlJobLogGlue.setGlueRemark(glueRemark);
@@ -91,7 +95,7 @@ public class JobCodeController {
xxlJobLogGlueDao.save(xxlJobLogGlue);
// remove code backup more than 30
xxlJobLogGlueDao.removeOld(exists_jobInfo.getId(), 30);
xxlJobLogGlueDao.removeOld(existsJobInfo.getId(), 30);
return ReturnT.SUCCESS;
}
@@ -1,5 +1,6 @@
package com.xxl.job.admin.controller;
import com.xxl.job.admin.controller.interceptor.PermissionInterceptor;
import com.xxl.job.admin.core.exception.XxlJobException;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo;
@@ -8,16 +9,15 @@ import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum;
import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum;
import com.xxl.job.admin.core.thread.JobScheduleHelper;
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.dao.XxlJobGroupDao;
import com.xxl.job.admin.service.LoginService;
import com.xxl.job.admin.service.XxlJobService;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
import com.xxl.job.core.glue.GlueTypeEnum;
import com.xxl.job.core.util.DateUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
@@ -26,9 +26,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* index controller
@@ -62,7 +63,7 @@ public class JobInfoController {
List<XxlJobGroup> jobGroupList_all = xxlJobGroupDao.findAll();
// filter group
List<XxlJobGroup> jobGroupList = filterJobGroupByRole(request, jobGroupList_all);
List<XxlJobGroup> jobGroupList = PermissionInterceptor.filterJobGroupByRole(request, jobGroupList_all);
if (jobGroupList == null || jobGroupList.size() == 0) {
throw new XxlJobException(I18nUtil.getString("jobgroup_empty"));
}
@@ -73,37 +74,6 @@ public class JobInfoController {
return "jobinfo/jobinfo.index";
}
public static List<XxlJobGroup> filterJobGroupByRole(HttpServletRequest request,
List<XxlJobGroup> jobGroupList_all) {
List<XxlJobGroup> jobGroupList = new ArrayList<>();
if (jobGroupList_all != null && jobGroupList_all.size() > 0) {
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
if (loginUser.getRole() == 1) {
jobGroupList = jobGroupList_all;
}
else {
List<String> groupIdStrs = new ArrayList<>();
if (loginUser.getPermission() != null && loginUser.getPermission().trim().length() > 0) {
groupIdStrs = Arrays.asList(loginUser.getPermission().trim().split(","));
}
for (XxlJobGroup groupItem : jobGroupList_all) {
if (groupIdStrs.contains(String.valueOf(groupItem.getId()))) {
jobGroupList.add(groupItem);
}
}
}
}
return jobGroupList;
}
public static void validPermission(HttpServletRequest request, int jobGroup) {
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
if (!loginUser.validPermission(jobGroup)) {
throw new RuntimeException(
I18nUtil.getString("system_permission_limit") + "[username=" + loginUser.getUsername() + "]");
}
}
@RequestMapping("/pageList")
@ResponseBody
public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,
@@ -115,14 +85,24 @@ public class JobInfoController {
@RequestMapping("/add")
@ResponseBody
public ReturnT<String> add(XxlJobInfo jobInfo) {
return xxlJobService.add(jobInfo);
public ReturnT<String> add(HttpServletRequest request, XxlJobInfo jobInfo) {
// valid permission
PermissionInterceptor.validJobGroupPermission(request, jobInfo.getJobGroup());
// opt
XxlJobUser loginUser = PermissionInterceptor.getLoginUser(request);
return xxlJobService.add(jobInfo, loginUser);
}
@RequestMapping("/update")
@ResponseBody
public ReturnT<String> update(XxlJobInfo jobInfo) {
return xxlJobService.update(jobInfo);
public ReturnT<String> update(HttpServletRequest request, XxlJobInfo jobInfo) {
// valid permission
PermissionInterceptor.validJobGroupPermission(request, jobInfo.getJobGroup());
// opt
XxlJobUser loginUser = PermissionInterceptor.getLoginUser(request);
return xxlJobService.update(jobInfo, loginUser);
}
@RequestMapping("/remove")
@@ -145,15 +125,11 @@ public class JobInfoController {
@RequestMapping("/trigger")
@ResponseBody
// @PermissionLimit(limit = false)
public ReturnT<String> triggerJob(int id, String executorParam, String addressList) {
// force cover job param
if (executorParam == null) {
executorParam = "";
}
JobTriggerPoolHelper.trigger(id, TriggerTypeEnum.MANUAL, -1, null, executorParam, addressList);
return ReturnT.SUCCESS;
public ReturnT<String> triggerJob(HttpServletRequest request, int id, String executorParam, String addressList) {
// login user
XxlJobUser loginUser = PermissionInterceptor.getLoginUser(request);
// trigger
return xxlJobService.trigger(loginUser, id, executorParam, addressList);
}
@RequestMapping("/nextTriggerTime")
@@ -1,5 +1,6 @@
package com.xxl.job.admin.controller;
import com.xxl.job.admin.controller.interceptor.PermissionInterceptor;
import com.xxl.job.admin.core.complete.XxlJobCompleter;
import com.xxl.job.admin.core.exception.XxlJobException;
import com.xxl.job.admin.core.model.XxlJobGroup;
@@ -20,9 +21,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.util.HtmlUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@@ -59,7 +62,7 @@ public class JobLogController {
List<XxlJobGroup> jobGroupList_all = xxlJobGroupDao.findAll();
// filter group
List<XxlJobGroup> jobGroupList = JobInfoController.filterJobGroupByRole(request, jobGroupList_all);
List<XxlJobGroup> jobGroupList = PermissionInterceptor.filterJobGroupByRole(request, jobGroupList_all);
if (jobGroupList == null || jobGroupList.size() == 0) {
throw new XxlJobException(I18nUtil.getString("jobgroup_empty"));
}
@@ -77,7 +80,7 @@ public class JobLogController {
model.addAttribute("jobInfo", jobInfo);
// valid permission
JobInfoController.validPermission(request, jobInfo.getJobGroup());
PermissionInterceptor.validJobGroupPermission(request, jobInfo.getJobGroup());
}
return "joblog/joblog.index";
@@ -98,8 +101,8 @@ public class JobLogController {
String filterTime) {
// valid permission
JobInfoController.validPermission(request, jobGroup); // 仅管理员支持查询全部;普通用户仅支持查询有权限的
// jobGroup
PermissionInterceptor.validJobGroupPermission(request, jobGroup); // 仅管理员支持查询全部;普通用户仅支持查询有权限的
// jobGroup
// parse param
Date triggerTimeStart = null;
@@ -166,6 +169,13 @@ public class JobLogController {
}
}
// fix xss
if (logResult.getContent() != null && StringUtils.hasText(logResult.getContent().getLogContent())) {
String newLogContent = logResult.getContent().getLogContent();
newLogContent = HtmlUtils.htmlEscape(newLogContent, "UTF-8");
logResult.getContent().setLogContent(newLogContent);
}
return logResult;
}
catch (Exception e) {
@@ -213,8 +223,11 @@ public class JobLogController {
@RequestMapping("/clearLog")
@ResponseBody
public ReturnT<String> clearLog(int jobGroup, int jobId, int type) {
public ReturnT<String> clearLog(HttpServletRequest request, int jobGroup, int jobId, int type) {
// valid permission
PermissionInterceptor.validJobGroupPermission(request, jobGroup);
// opt
Date clearBeforeTime = null;
int clearBeforeNum = 0;
if (type == 1) {
@@ -1,12 +1,12 @@
package com.xxl.job.admin.controller;
import com.xxl.job.admin.controller.annotation.PermissionLimit;
import com.xxl.job.admin.controller.interceptor.PermissionInterceptor;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobUser;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.dao.XxlJobGroupDao;
import com.xxl.job.admin.dao.XxlJobUserDao;
import com.xxl.job.admin.service.LoginService;
import com.xxl.job.core.biz.model.ReturnT;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@@ -27,7 +27,7 @@ import java.util.Map;
*/
@Controller
@RequestMapping("/user")
public class UserController {
public class JobUserController {
@Resource
private XxlJobUserDao xxlJobUserDao;
@@ -114,7 +114,7 @@ public class UserController {
public ReturnT<String> update(HttpServletRequest request, XxlJobUser xxlJobUser) {
// avoid opt login seft
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
XxlJobUser loginUser = PermissionInterceptor.getLoginUser(request);
if (loginUser.getUsername().equals(xxlJobUser.getUsername())) {
return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("user_update_loginuser_limit"));
}
@@ -143,7 +143,7 @@ public class UserController {
public ReturnT<String> remove(HttpServletRequest request, int id) {
// avoid opt login seft
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
XxlJobUser loginUser = PermissionInterceptor.getLoginUser(request);
if (loginUser.getId() == id) {
return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("user_update_loginuser_limit"));
}
@@ -154,11 +154,16 @@ public class UserController {
@RequestMapping("/updatePwd")
@ResponseBody
public ReturnT<String> updatePwd(HttpServletRequest request, String password) {
public ReturnT<String> updatePwd(HttpServletRequest request, String password, String oldPassword) {
// valid password
// valid
if (oldPassword == null || oldPassword.trim().length() == 0) {
return new ReturnT<String>(ReturnT.FAIL.getCode(),
I18nUtil.getString("system_please_input") + I18nUtil.getString("change_pwd_field_oldpwd"));
}
if (password == null || password.trim().length() == 0) {
return new ReturnT<String>(ReturnT.FAIL.getCode(), "密码不可为空");
return new ReturnT<String>(ReturnT.FAIL.getCode(),
I18nUtil.getString("system_please_input") + I18nUtil.getString("change_pwd_field_oldpwd"));
}
password = password.trim();
if (!(password.length() >= 4 && password.length() <= 20)) {
@@ -166,13 +171,18 @@ public class UserController {
}
// md5 password
String md5OldPassword = DigestUtils.md5DigestAsHex(oldPassword.getBytes());
String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
// update pwd
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
// do write
// valid old pwd
XxlJobUser loginUser = PermissionInterceptor.getLoginUser(request);
XxlJobUser existUser = xxlJobUserDao.loadByUserName(loginUser.getUsername());
if (!md5OldPassword.equals(existUser.getPassword())) {
return new ReturnT<String>(ReturnT.FAIL.getCode(),
I18nUtil.getString("change_pwd_field_oldpwd") + I18nUtil.getString("system_unvalid"));
}
// write new
existUser.setPassword(md5Password);
xxlJobUserDao.update(existUser);
@@ -1,16 +1,20 @@
package com.xxl.job.admin.controller.interceptor;
import com.xxl.job.admin.controller.annotation.PermissionLimit;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobUser;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.service.LoginService;
import com.xxl.job.admin.service.impl.LoginService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 权限拦截
@@ -51,10 +55,70 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor {
if (needAdminuser && loginUser.getRole() != 1) {
throw new RuntimeException(I18nUtil.getString("system_permission_limit"));
}
request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser);
request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser); // set
// loginUser,
// with
// request
}
return true; // proceed with the next interceptor
}
// -------------------- permission tool --------------------
/**
* get loginUser
* @param request
* @return
*/
public static XxlJobUser getLoginUser(HttpServletRequest request) {
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY); // get
// loginUser,
// with
// request
return loginUser;
}
/**
* valid permission by JobGroup
* @param request
* @param jobGroup
*/
public static void validJobGroupPermission(HttpServletRequest request, int jobGroup) {
XxlJobUser loginUser = getLoginUser(request);
if (!loginUser.validPermission(jobGroup)) {
throw new RuntimeException(
I18nUtil.getString("system_permission_limit") + "[username=" + loginUser.getUsername() + "]");
}
}
/**
* filter XxlJobGroup by role
* @param request
* @param jobGroupList_all
* @return
*/
public static List<XxlJobGroup> filterJobGroupByRole(HttpServletRequest request,
List<XxlJobGroup> jobGroupList_all) {
List<XxlJobGroup> jobGroupList = new ArrayList<>();
if (jobGroupList_all != null && jobGroupList_all.size() > 0) {
XxlJobUser loginUser = PermissionInterceptor.getLoginUser(request);
if (loginUser.getRole() == 1) {
jobGroupList = jobGroupList_all;
}
else {
List<String> groupIdStrs = new ArrayList<>();
if (loginUser.getPermission() != null && loginUser.getPermission().trim().length() > 0) {
groupIdStrs = Arrays.asList(loginUser.getPermission().trim().split(","));
}
for (XxlJobGroup groupItem : jobGroupList_all) {
if (groupIdStrs.contains(String.valueOf(groupItem.getId()))) {
jobGroupList.add(groupItem);
}
}
}
}
return jobGroupList;
}
}
@@ -19,7 +19,16 @@ package com.xxl.job.admin.core.cron;
import java.io.Serializable;
import java.text.ParseException;
import java.util.*;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.SortedSet;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.TreeSet;
/**
* Provides a parser and evaluator for unix-like cron expressions. Cron expressions
@@ -360,9 +369,9 @@ public final class CronExpression implements Serializable, Cloneable {
// the second immediately following it.
while (difference == 1000) {
newDate = getTimeAfter(lastDate);
if (newDate == null)
if (newDate == null) {
break;
}
difference = newDate.getTime() - lastDate.getTime();
if (difference == 1000) {
@@ -657,8 +666,9 @@ public final class CronExpression implements Serializable, Cloneable {
if (c == '-') {
ValueSet vs = getValue(0, s, i + 1);
lastdayOffset = vs.value;
if (lastdayOffset > 30)
if (lastdayOffset > 30) {
throw new ParseException("Offset from last day must be <= 30", i + 1);
}
i = vs.pos;
}
if (s.length() > i) {
@@ -727,8 +737,9 @@ public final class CronExpression implements Serializable, Cloneable {
if (c == 'L') {
if (type == DAY_OF_WEEK) {
if (val < 1 || val > 7)
if (val < 1 || val > 7) {
throw new ParseException("Day-of-Week values must be between 1 and 7", -1);
}
lastdayOfWeek = true;
}
else {
@@ -747,10 +758,11 @@ public final class CronExpression implements Serializable, Cloneable {
else {
throw new ParseException("'W' option is not valid here. (pos=" + i + ")", i);
}
if (val > 31)
if (val > 31) {
throw new ParseException(
"The 'W' option does not make sense with values larger than 31 (max number of days in a month)",
i);
}
TreeSet<Integer> set = getSet(type);
set.add(val);
i++;
@@ -25,9 +25,9 @@
// import org.slf4j.LoggerFactory;
// import org.springframework.util.Assert;
//
// import javax.servlet.ServletException;
// import javax.servlet.http.HttpServletRequest;
// import javax.servlet.http.HttpServletResponse;
// import jakarta.servlet.ServletException;
// import jakarta.servlet.http.HttpServletRequest;
// import jakarta.servlet.http.HttpServletResponse;
// import java.io.IOException;
// import java.util.Date;
// import java.util.concurrent.ConcurrentHashMap;
@@ -427,4 +427,4 @@
// return jobList;
// }*/
//
// }
// }
@@ -1,7 +1,7 @@
package com.xxl.job.admin.core.route.strategy;
import com.xxl.job.admin.core.route.ExecutorRouter;
import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
import com.xxl.job.admin.core.route.ExecutorRouter;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.core.biz.ExecutorBiz;
import com.xxl.job.core.biz.model.IdleBeatParam;
@@ -1,7 +1,7 @@
package com.xxl.job.admin.core.route.strategy;
import com.xxl.job.admin.core.route.ExecutorRouter;
import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
import com.xxl.job.admin.core.route.ExecutorRouter;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.core.biz.ExecutorBiz;
import com.xxl.job.core.biz.model.ReturnT;
@@ -302,18 +302,31 @@ public class JobScheduleHelper {
}
private void refreshNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception {
Date nextValidTime = generateNextValidTime(jobInfo, fromTime);
if (nextValidTime != null) {
jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
jobInfo.setTriggerNextTime(nextValidTime.getTime());
try {
Date nextValidTime = generateNextValidTime(jobInfo, fromTime);
if (nextValidTime != null) {
jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
jobInfo.setTriggerNextTime(nextValidTime.getTime());
}
else {
// generateNextValidTime fail, stop job
jobInfo.setTriggerStatus(0);
jobInfo.setTriggerLastTime(0);
jobInfo.setTriggerNextTime(0);
logger.error(
">>>>>>>>>>> xxl-job, refreshNextValidTime fail for job: jobId={}, scheduleType={}, scheduleConf={}",
jobInfo.getId(), jobInfo.getScheduleType(), jobInfo.getScheduleConf());
}
}
else {
catch (Exception e) {
// generateNextValidTime error, stop job
jobInfo.setTriggerStatus(0);
jobInfo.setTriggerLastTime(0);
jobInfo.setTriggerNextTime(0);
logger.warn(
">>>>>>>>>>> xxl-job, refreshNextValidTime fail for job: jobId={}, scheduleType={}, scheduleConf={}",
jobInfo.getId(), jobInfo.getScheduleType(), jobInfo.getScheduleConf());
logger.error(
">>>>>>>>>>> xxl-job, refreshNextValidTime error for job: jobId={}, scheduleType={}, scheduleConf={}",
jobInfo.getId(), jobInfo.getScheduleType(), jobInfo.getScheduleConf(), e);
}
}
@@ -3,7 +3,6 @@ package com.xxl.job.admin.dao;
import com.xxl.job.admin.core.model.XxlJobUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
@@ -1,6 +1,7 @@
package com.xxl.job.admin.service;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobUser;
import com.xxl.job.core.biz.model.ReturnT;
import java.util.Date;
@@ -31,14 +32,14 @@ public interface XxlJobService {
* @param jobInfo
* @return
*/
public ReturnT<String> add(XxlJobInfo jobInfo);
public ReturnT<String> add(XxlJobInfo jobInfo, XxlJobUser loginUser);
/**
* update job
* @param jobInfo
* @return
*/
public ReturnT<String> update(XxlJobInfo jobInfo);
public ReturnT<String> update(XxlJobInfo jobInfo, XxlJobUser loginUser);
/**
* remove job *
@@ -61,6 +62,16 @@ public interface XxlJobService {
*/
public ReturnT<String> stop(int id);
/**
* trigger
* @param loginUser
* @param jobId
* @param executorParam
* @param addressList
* @return
*/
public ReturnT<String> trigger(XxlJobUser loginUser, int jobId, String executorParam, String addressList);
/**
* dashboard info
* @return
@@ -1,4 +1,4 @@
package com.xxl.job.admin.service;
package com.xxl.job.admin.service.impl;
import com.xxl.job.admin.core.model.XxlJobUser;
import com.xxl.job.admin.core.util.CookieUtil;
@@ -6,18 +6,18 @@ import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.core.util.JacksonUtil;
import com.xxl.job.admin.dao.XxlJobUserDao;
import com.xxl.job.core.biz.model.ReturnT;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.math.BigInteger;
/**
* @author xuxueli 2019-05-04 22:13:264
*/
@Configuration
@Service
public class LoginService {
public static final String LOGIN_IDENTITY_KEY = "XXL_JOB_LOGIN_IDENTITY";
@@ -25,6 +25,8 @@ public class LoginService {
@Resource
private XxlJobUserDao xxlJobUserDao;
// ---------------------- token tool ----------------------
private String makeToken(XxlJobUser xxlJobUser) {
String tokenJson = JacksonUtil.writeValueAsString(xxlJobUser);
String tokenHex = new BigInteger(tokenJson.getBytes()).toString(16);
@@ -40,6 +42,8 @@ public class LoginService {
return xxlJobUser;
}
// ---------------------- login tool, with cookie and db ----------------------
public ReturnT<String> login(HttpServletRequest request, HttpServletResponse response, String username,
String password, boolean ifRemember) {
@@ -4,10 +4,13 @@ import com.xxl.job.admin.core.cron.CronExpression;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobLogReport;
import com.xxl.job.admin.core.model.XxlJobUser;
import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum;
import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum;
import com.xxl.job.admin.core.thread.JobScheduleHelper;
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.dao.*;
import com.xxl.job.admin.service.XxlJobService;
@@ -19,7 +22,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import jakarta.annotation.Resource;
import java.text.MessageFormat;
import java.util.*;
@@ -67,7 +70,7 @@ public class XxlJobServiceImpl implements XxlJobService {
}
@Override
public ReturnT<String> add(XxlJobInfo jobInfo) {
public ReturnT<String> add(XxlJobInfo jobInfo, XxlJobUser loginUser) {
// valid base
XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup());
@@ -155,6 +158,11 @@ public class XxlJobServiceImpl implements XxlJobService {
MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})"
+ I18nUtil.getString("system_not_found")), childJobIdItem));
}
if (!loginUser.validPermission(childJobInfo.getJobGroup())) {
return new ReturnT<String>(ReturnT.FAIL_CODE,
MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})"
+ I18nUtil.getString("system_permission_limit")), childJobIdItem));
}
}
else {
return new ReturnT<String>(ReturnT.FAIL_CODE,
@@ -197,7 +205,7 @@ public class XxlJobServiceImpl implements XxlJobService {
}
@Override
public ReturnT<String> update(XxlJobInfo jobInfo) {
public ReturnT<String> update(XxlJobInfo jobInfo, XxlJobUser loginUser) {
// valid base
if (jobInfo.getJobDesc() == null || jobInfo.getJobDesc().trim().length() == 0) {
@@ -267,6 +275,11 @@ public class XxlJobServiceImpl implements XxlJobService {
MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})"
+ I18nUtil.getString("system_not_found")), childJobIdItem));
}
if (!loginUser.validPermission(childJobInfo.getJobGroup())) {
return new ReturnT<String>(ReturnT.FAIL_CODE,
MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId") + "({0})"
+ I18nUtil.getString("system_permission_limit")), childJobIdItem));
}
}
else {
return new ReturnT<String>(ReturnT.FAIL_CODE,
@@ -404,6 +417,40 @@ public class XxlJobServiceImpl implements XxlJobService {
return ReturnT.SUCCESS;
}
@Override
public ReturnT<String> trigger(XxlJobUser loginUser, int jobId, String executorParam, String addressList) {
// permission
if (loginUser == null) {
return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("system_permission_limit"));
}
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(jobId);
if (xxlJobInfo == null) {
return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("jobinfo_glue_jobid_unvalid"));
}
if (!hasPermission(loginUser, xxlJobInfo.getJobGroup())) {
return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("system_permission_limit"));
}
// force cover job param
if (executorParam == null) {
executorParam = "";
}
JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.MANUAL, -1, null, executorParam, addressList);
return ReturnT.SUCCESS;
}
private boolean hasPermission(XxlJobUser loginUser, int jobGroup) {
if (loginUser.getRole() == 1) {
return true;
}
List<String> groupIdStrs = new ArrayList<>();
if (loginUser.getPermission() != null && loginUser.getPermission().trim().length() > 0) {
groupIdStrs = Arrays.asList(loginUser.getPermission().trim().split(","));
}
return groupIdStrs.contains(String.valueOf(jobGroup));
}
@Override
public Map<String, Object> dashboardInfo() {
@@ -1,6 +1,6 @@
admin_name=Scheduling Center
admin_name_full=Distributed Task Scheduling Platform XXL-JOB
admin_version=2.4.0
admin_version=2.5.0-SNAPSHOT
admin_i18n=en
## system
@@ -91,6 +91,7 @@ logout_fail=Logout fail
## change pwd
change_pwd=Change password
change_pwd_suc_to_logout=Change password successful, about to log out login
change_pwd_field_oldpwd=old password
change_pwd_field_newpwd=new password
## dashboard
@@ -1,6 +1,6 @@
admin_name=任务调度中心
admin_name_full=分布式任务调度平台XXL-JOB
admin_version=2.4.0
admin_version=2.5.0-SNAPSHOT
admin_i18n=
## system
@@ -91,6 +91,7 @@ logout_fail=注销失败
## change pwd
change_pwd=修改密码
change_pwd_suc_to_logout=修改密码成功,即将注销登陆
change_pwd_field_oldpwd=旧密码
change_pwd_field_newpwd=新密码
## dashboard
@@ -1,6 +1,6 @@
admin_name=任務調度中心
admin_name_full=分布式任務調度平臺XXL-JOB
admin_version=2.4.0
admin_version=2.5.0-SNAPSHOT
admin_i18n=
## system
@@ -91,6 +91,7 @@ logout_fail=登出失敗
## change pwd
change_pwd=修改密碼
change_pwd_suc_to_logout=修改密碼成功,即將登出
change_pwd_field_oldpwd=舊密碼
change_pwd_field_newpwd=新密碼
## dashboard
@@ -99,15 +99,23 @@ $(function(){
errorClass : 'help-block',
focusInvalid : true,
rules : {
oldPassword : {
required : true ,
rangelength:[4,20]
},
password : {
required : true ,
rangelength:[4,50]
rangelength:[4,20]
}
},
messages : {
oldPassword : {
required : I18n.system_please_input +I18n.change_pwd_field_oldpwd,
rangelength : "密码长度限制为4~20"
},
password : {
required : '请输入密码' ,
rangelength : "密码长度限制为4~50"
required : I18n.system_please_input +I18n.change_pwd_field_newpwd,
rangelength : "密码长度限制为4~20"
}
},
highlight : function(element) {
@@ -123,7 +123,7 @@ $(function() {
var id = $(this).attr("_id");
var row = tableData['key'+id];
var html = '<div>';
/*var html = '<div>';
if (row.registryList) {
for (var index in row.registryList) {
html += (parseInt(index)+1) + '. <span class="badge bg-green" >' + row.registryList[index] + '</span><br>';
@@ -135,8 +135,19 @@ $(function() {
title: I18n.jobinfo_opt_registryinfo ,
btn: [ I18n.system_ok ],
content: html
});
});*/
var html = '<table class="table table-bordered"><tbody>';
if (row.registryList) {
for (var index in row.registryList) {
html += '<tr><th>' + (parseInt(index)+1) + '</th>';
html += '<th><span class="badge bg-green" >' + row.registryList[index] + '</span></th><tr>';
}
}
html += '</tbody></table>';
$('#showRegistryListModal .data').html(html);
$('#showRegistryListModal').modal({backdrop: false, keyboard: false}).modal('show');
});
@@ -107,9 +107,13 @@
</div>
<div class="modal-body">
<form class="form-horizontal form" role="form" >
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.change_pwd_field_oldpwd}<font color="red">*</font></label>
<div class="col-sm-10"><input type="text" class="form-control" name="oldPassword" placeholder="${I18n.system_please_input} ${I18n.change_pwd_field_oldpwd}" maxlength="20" ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.change_pwd_field_newpwd}<font color="red">*</font></label>
<div class="col-sm-10"><input type="text" class="form-control" name="password" placeholder="${I18n.system_please_input} ${I18n.change_pwd_field_newpwd}" maxlength="18" ></div>
<div class="col-sm-10"><input type="text" class="form-control" name="password" placeholder="${I18n.system_please_input} ${I18n.change_pwd_field_newpwd}" maxlength="20" ></div>
</div>
<hr>
<div class="form-group">
@@ -70,6 +70,25 @@
</section>
</div>
<!-- 注册列表查看.模态框 -->
<div class="modal fade" id="showRegistryListModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" >${I18n.jobinfo_opt_registryinfo}</h4>
</div>
<div class="modal-body">
<div class="data" style="word-wrap: break-word;"></div>
</div>
<div class="modal-footer">
<div class="text-center" >
<button type="button" class="btn btn-info ok" data-dismiss="modal" >${I18n.system_ok}</button>
</div>
</div>
</div>
</div>
</div>
<!-- 新增.模态框 -->
<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog ">
@@ -15,14 +15,14 @@
<@netCommon.commonHeader />
<!-- left -->
<@netCommon.commonLeft "joblog" />
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>${I18n.joblog_name}</h1>
</section>
<!-- Main content -->
<section class="content">
<div class="row">
@@ -30,7 +30,7 @@
<div class="input-group">
<span class="input-group-addon">${I18n.jobinfo_field_jobgroup}</span>
<select class="form-control" id="jobGroup" paramVal="<#if jobInfo?exists>${jobInfo.jobGroup}</#if>" >
<#if Request["XXL_JOB_LOGIN_IDENTITY"].role == 1>
<#if XXL_JOB_LOGIN_IDENTITY == 1>
<option value="0" >${I18n.system_all}</option> <#-- 仅管理员支持查询全部;普通用户仅支持查询有权限的 jobGroup -->
</#if>
<#list JobGroupList as group>
@@ -77,7 +77,7 @@
<button class="btn btn-block btn-default" id="clearLog">${I18n.joblog_clean}</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="box">
@@ -108,7 +108,7 @@
</div>
</section>
</div>
<!-- footer -->
<@netCommon.commonFooter />
</div>