refactor(xxl-job): 升级xxl-job-admin 3.1.1

This commit is contained in:
PIG AI committed 2025-07-07 10:53:26 +08:00
1 parent c9124d11c6
commit 2fc40ac21a
47 files changed
+693 -713

No files matched your search

+11 -12
View File
@@ -35,15 +35,12 @@
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- starter-web:spring-webmvc + autoconfigure + logback + yaml + tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- freemarker-starter -->
<dependency>
@@ -57,26 +54,28 @@
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- mybatis-starter:mybatis + mybatis-spring + druid(default) -->
<!-- starter-actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- mybatis-starter:mybatis + mybatis-spring + hikari(default) -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmJdbcDriver18</artifactId>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
</dependency>
<!-- xxl-job-core -->
@@ -1,8 +1,8 @@
package com.xxl.job.admin.controller;
import com.xxl.job.admin.controller.annotation.PermissionLimit;
import com.xxl.job.admin.service.impl.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 jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
@@ -21,7 +21,6 @@ import java.util.Map;
/**
* index controller
*
* @author xuxueli 2015-12-19 16:13:16
*/
@Controller
@@ -29,10 +28,10 @@ public class IndexController {
@Resource
private XxlJobService xxlJobService;
@Resource
private LoginService loginService;
@RequestMapping("/")
public String index(Model model) {
@@ -49,7 +48,7 @@ public class IndexController {
ReturnT<Map<String, Object>> chartInfo = xxlJobService.chartInfo(startDate, endDate);
return chartInfo;
}
@RequestMapping("/toLogin")
@PermissionLimit(limit = false)
public ModelAndView toLogin(HttpServletRequest request, HttpServletResponse response, ModelAndView modelAndView) {
@@ -21,7 +21,6 @@ import java.util.List;
/**
* job code controller
*
* @author xuxueli 2015-12-19 16:13:16
*/
@Controller
@@ -30,7 +29,6 @@ public class JobCodeController {
@Resource
private XxlJobInfoDao xxlJobInfoDao;
@Resource
private XxlJobLogGlueDao xxlJobLogGlueDao;
@@ -17,13 +17,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
/**
* job group controller
*
* @author xuxueli 2016-10-02 20:52:56
*/
@Controller
@@ -32,10 +29,8 @@ public class JobGroupController {
@Resource
public XxlJobInfoDao xxlJobInfoDao;
@Resource
public XxlJobGroupDao xxlJobGroupDao;
@Resource
private XxlJobRegistryDao xxlJobRegistryDao;
@@ -163,10 +158,7 @@ public class JobGroupController {
private List<String> findRegistryByAppName(String appnameParam) {
HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
Instant now = Instant.now();
Instant expiredInstant = now.minus(RegistryConfig.DEAD_TIMEOUT, ChronoUnit.SECONDS); // 假设 timeout 单位是秒
Date expiredTime = Date.from(expiredInstant);
List<XxlJobRegistry> list = xxlJobRegistryDao.findAll(expiredTime);
List<XxlJobRegistry> list = xxlJobRegistryDao.findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
if (list != null) {
for (XxlJobRegistry item : list) {
if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
@@ -26,22 +26,22 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* index controller
*
* @author xuxueli 2015-12-19 16:13:16
*/
@Controller
@RequestMapping("/jobinfo")
public class JobInfoController {
private static Logger logger = LoggerFactory.getLogger(JobInfoController.class);
@Resource
private XxlJobGroupDao xxlJobGroupDao;
@Resource
private XxlJobService xxlJobService;
@@ -78,7 +78,7 @@ public class JobInfoController {
@RequestParam("jobGroup") int jobGroup, @RequestParam("triggerStatus") int triggerStatus,
@RequestParam("jobDesc") String jobDesc, @RequestParam("executorHandler") String executorHandler,
@RequestParam("author") String author) {
return xxlJobService.pageList(start, length, jobGroup, triggerStatus, jobDesc, executorHandler, author);
}
@@ -36,21 +36,17 @@ import java.util.Map;
/**
* index controller
*
* @author xuxueli 2015-12-19 16:13:16
*/
@Controller
@RequestMapping("/joblog")
public class JobLogController {
private static Logger logger = LoggerFactory.getLogger(JobLogController.class);
@Resource
private XxlJobGroupDao xxlJobGroupDao;
@Resource
public XxlJobInfoDao xxlJobInfoDao;
@Resource
public XxlJobLogDao xxlJobLogDao;
@@ -104,7 +100,7 @@ public class JobLogController {
// valid permission
PermissionInterceptor.validJobGroupPermission(request, jobGroup); // 仅管理员支持查询全部;普通用户仅支持查询有权限的
// jobGroup
// parse param
Date triggerTimeStart = null;
Date triggerTimeEnd = null;
@@ -121,7 +117,7 @@ public class JobLogController {
logStatus);
int list_count = xxlJobLogDao.pageListCount(start, length, jobGroup, jobId, triggerTimeStart, triggerTimeEnd,
logStatus);
// package result
Map<String, Object> maps = new HashMap<String, Object>();
maps.put("recordsTotal", list_count); // 总记录数
@@ -131,15 +127,18 @@ public class JobLogController {
}
@RequestMapping("/logDetailPage")
public String logDetailPage(@RequestParam("id") int id, Model model) {
public String logDetailPage(HttpServletRequest request, @RequestParam("id") int id, Model model) {
// base check
ReturnT<String> logStatue = ReturnT.SUCCESS;
XxlJobLog jobLog = xxlJobLogDao.load(id);
if (jobLog == null) {
throw new RuntimeException(I18nUtil.getString("joblog_logid_unvalid"));
}
// valid permission
PermissionInterceptor.validJobGroupPermission(request, jobLog.getJobGroup());
// data
model.addAttribute("triggerCode", jobLog.getTriggerCode());
model.addAttribute("handleCode", jobLog.getHandleCode());
model.addAttribute("logId", jobLog.getId());
@@ -173,8 +172,7 @@ 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");
String newLogContent = filter(logResult.getContent().getLogContent());
logResult.getContent().setLogContent(newLogContent);
}
@@ -186,6 +184,37 @@ public class JobLogController {
}
}
/**
* filter xss tag
* @param originData
* @return
*/
private String filter(String originData) {
// exclude tag
Map<String, String> excludeTagMap = new HashMap<String, String>();
excludeTagMap.put("<br>", "###TAG_BR###");
excludeTagMap.put("<b>", "###TAG_BOLD###");
excludeTagMap.put("</b>", "###TAG_BOLD_END###");
// replace
for (String key : excludeTagMap.keySet()) {
String value = excludeTagMap.get(key);
originData = originData.replaceAll(key, value);
}
// htmlEscape
originData = HtmlUtils.htmlEscape(originData, "UTF-8");
// replace back
for (String key : excludeTagMap.keySet()) {
String value = excludeTagMap.get(key);
originData = originData.replaceAll(value, key);
}
return originData;
}
@RequestMapping("/logKill")
@ResponseBody
public ReturnT<String> logKill(@RequestParam("id") int id) {
@@ -1,5 +1,6 @@
package com.xxl.job.admin.controller.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -7,7 +8,6 @@ import java.lang.annotation.Target;
/**
* 权限限制
*
* @author xuxueli 2015-12-12 18:29:02
*/
@Target(ElementType.METHOD)
@@ -30,7 +30,7 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (!(handler instanceof HandlerMethod)) {
return true; // proceed with the next interceptor
}
@@ -63,6 +63,7 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor {
return true; // proceed with the next interceptor
}
// -------------------- permission tool --------------------
/**
@@ -129,4 +130,5 @@ public class PermissionInterceptor implements AsyncHandlerInterceptor {
return jobGroupList;
}
}
@@ -1,8 +1,8 @@
package com.xxl.job.admin.controller.resolver;
import com.xxl.job.admin.core.exception.XxlJobException;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.admin.core.util.JacksonUtil;
import com.xxl.job.core.biz.model.ReturnT;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
@@ -22,7 +22,6 @@ import java.io.IOException;
*/
@Component
public class WebExceptionResolver implements HandlerExceptionResolver {
private static transient Logger logger = LoggerFactory.getLogger(WebExceptionResolver.class);
@Override
@@ -54,7 +54,7 @@ public class XxlJobAdminConfig implements InitializingBean, DisposableBean {
@Value("${xxl.job.accessToken:}")
private String accessToken;
@Value("${xxl.job.timeout:100}")
@Value("${xxl.job.timeout:3}")
private int timeout;
@Value("${spring.mail.from}")
@@ -129,8 +129,8 @@ public class XxlJobAdminConfig implements InitializingBean, DisposableBean {
}
public int getLogretentiondays() {
if (logretentiondays < 7) {
return -1; // Limit greater than or equal to 7, otherwise close
if (logretentiondays < 3) {
return -1; // Limit greater than or equal to 3, otherwise close
}
return logretentiondays;
}
@@ -1,116 +1,93 @@
/*
* All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* 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 com.xxl.job.admin.core.cron;
import java.io.Serializable;
import java.text.ParseException;
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;
import java.util.*;
/**
* Provides a parser and evaluator for unix-like cron expressions. Cron expressions
* provide the ability to specify complex time combinations such as &quot;At 8:00am every
* Monday through Friday&quot; or &quot;At 1:30am every last Friday of the month&quot;.
* <P>
* <p>
* Cron expressions are comprised of 6 required fields and one optional field separated by
* white space. The fields respectively are described as follows:
*
* <table cellspacing="8">
* </p>
* <table>
* <caption>Examples of cron expressions and their meanings.</caption>
* <tr>
* <th align="left">Field Name</th>
* <th align="left">&nbsp;</th>
* <th align="left">Allowed Values</th>
* <th align="left">&nbsp;</th>
* <th align="left">Allowed Special Characters</th>
* <th>Field Name</th>
* <th>&nbsp;</th>
* <th>Allowed Values</th>
* <th>&nbsp;</th>
* <th>Allowed Special Characters</th>
* </tr>
* <tr>
* <td align="left"><code>Seconds</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>0-59</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>, - * /</code></td>
* <td><code>Seconds</code></td>
* <td>&nbsp;</td>
* <td><code>0-59</code></td>
* <td>&nbsp;</td>
* <td><code>, - * /</code></td>
* </tr>
* <tr>
* <td align="left"><code>Minutes</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>0-59</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>, - * /</code></td>
* <td><code>Minutes</code></td>
* <td>&nbsp;</td>
* <td><code>0-59</code></td>
* <td>&nbsp;</td>
* <td><code>, - * /</code></td>
* </tr>
* <tr>
* <td align="left"><code>Hours</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>0-23</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>, - * /</code></td>
* <td><code>Hours</code></td>
* <td>&nbsp;</td>
* <td><code>0-23</code></td>
* <td>&nbsp;</td>
* <td><code>, - * /</code></td>
* </tr>
* <tr>
* <td align="left"><code>Day-of-month</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>1-31</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>, - * ? / L W</code></td>
* <td><code>Day-of-month</code></td>
* <td>&nbsp;</td>
* <td><code>1-31</code></td>
* <td>&nbsp;</td>
* <td><code>, - * ? / L W</code></td>
* </tr>
* <tr>
* <td align="left"><code>Month</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>0-11 or JAN-DEC</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>, - * /</code></td>
* <td><code>Month</code></td>
* <td>&nbsp;</td>
* <td><code>0-11 or JAN-DEC</code></td>
* <td>&nbsp;</td>
* <td><code>, - * /</code></td>
* </tr>
* <tr>
* <td align="left"><code>Day-of-Week</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>1-7 or SUN-SAT</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>, - * ? / L #</code></td>
* <td><code>Day-of-Week</code></td>
* <td>&nbsp;</td>
* <td><code>1-7 or SUN-SAT</code></td>
* <td>&nbsp;</td>
* <td><code>, - * ? / L #</code></td>
* </tr>
* <tr>
* <td align="left"><code>Year (Optional)</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>empty, 1970-2199</code></td>
* <td align="left">&nbsp;</th>
* <td align="left"><code>, - * /</code></td>
* <td><code>Year (Optional)</code></td>
* <td>&nbsp;</td>
* <td><code>empty, 1970-2199</code></td>
* <td>&nbsp;</td>
* <td><code>, - * /</code></td>
* </tr>
* </table>
* <P>
* <p>
* The '*' character is used to specify all values. For example, &quot;*&quot; in the
* minute field means &quot;every minute&quot;.
* <P>
* </p>
* <p>
* The '?' character is allowed for the day-of-month and day-of-week fields. It is used to
* specify 'no specific value'. This is useful when you need to specify something in one
* of the two fields, but not the other.
* <P>
* <p>
* The '-' character is used to specify ranges For example &quot;10-12&quot; in the hour
* field means &quot;the hours 10, 11 and 12&quot;.
* <P>
* <p>
* The ',' character is used to specify additional values. For example
* &quot;MON,WED,FRI&quot; in the day-of-week field means &quot;the days Monday,
* Wednesday, and Friday&quot;.
* <P>
* </p>
* <p>
* The '/' character is used to specify increments. For example &quot;0/15&quot; in the
* seconds field means &quot;the seconds 0, 15, 30, and 45&quot;. And &quot;5/15&quot; in
* the seconds field means &quot;the seconds 5, 20, 35, and 50&quot;. Specifying '*'
@@ -121,7 +98,8 @@ import java.util.TreeSet;
* character simply helps you turn on every &quot;nth&quot; value in the given set. Thus
* &quot;7/6&quot; in the month field only turns on month &quot;7&quot;, it does NOT mean
* every 6th month, please note that subtlety.
* <P>
* </p>
* <p>
* The 'L' character is allowed for the day-of-month and day-of-week fields. This
* character is short-hand for &quot;last&quot;, but it has different meaning in each of
* the two fields. For example, the value &quot;L&quot; in the day-of-month field means
@@ -133,7 +111,8 @@ import java.util.TreeSet;
* last day of the month, such as "L-3" which would mean the third-to-last day of the
* calendar month. <i>When using the 'L' option, it is important not to specify lists, or
* ranges of values, as you'll get confusing/unexpected results.</i>
* <P>
* </p>
* <p>
* The 'W' character is allowed for the day-of-month field. This character is used to
* specify the weekday (Monday-Friday) nearest the given day. As an example, if you were
* to specify &quot;15W&quot; as the value for the day-of-month field, the meaning is:
@@ -144,10 +123,12 @@ import java.util.TreeSet;
* is a Saturday, the trigger will fire on Monday the 3rd, as it will not 'jump' over the
* boundary of a month's days. The 'W' character can only be specified when the
* day-of-month is a single day, not a range or list of days.
* <P>
* </p>
* <p>
* The 'L' and 'W' characters can also be combined for the day-of-month expression to
* yield 'LW', which translates to &quot;last weekday of the month&quot;.
* <P>
* </p>
* <p>
* The '#' character is allowed for the day-of-week field. This character is used to
* specify &quot;the nth&quot; XXX day of the month. For example, the value of
* &quot;6#3&quot; in the day-of-week field means the third Friday of the month (day 6 =
@@ -157,19 +138,20 @@ import java.util.TreeSet;
* the month, then no firing will occur that month. If the '#' character is used, there
* can only be one expression in the day-of-week field (&quot;3#1,6#3&quot; is not valid,
* since there are two expressions).
* <P>
* </p>
* <!--The 'C' character is allowed for the day-of-month and day-of-week fields. This
* character is short-hand for "calendar". This means values are calculated against the
* associated calendar, if any. If no calendar is associated, then it is equivalent to
* having an all-inclusive calendar. A value of "5C" in the day-of-month field means "the
* first day included by the calendar on or after the 5th". A value of "1C" in the
* day-of-week field means "the first day included by the calendar on or after Sunday".-->
* <P>
* <p>
* The legal characters and the names of months and days of the week are not case
* sensitive.
*
* <p>
* <b>NOTES:</b>
* </p>
* <ul>
* <li>Support for specifying both a day-of-week and a day-of-month value is not complete
* (you'll need to use the '?' character in one of these fields).</li>
@@ -180,14 +162,12 @@ import java.util.TreeSet;
* determine which interpretation CronExpression chooses. An example would be "0 0 14-6 ?
* * FRI-MON".</li>
* </ul>
* </p>
*
* @author Sharada Jambula, James House
* @author Contributions from Mads Henderson
* @author Refactoring from CronTrigger to CronExpression by Aaron Craven
*
* Borrowed from quartz v2.3.1
*
* Borrowed from quartz v2.5.0
*/
public final class CronExpression implements Serializable, Cloneable {
@@ -211,13 +191,19 @@ public final class CronExpression implements Serializable, Cloneable {
protected static final int NO_SPEC_INT = 98; // '?'
protected static final int MAX_LAST_DAY_OFFSET = 30;
protected static final int LAST_DAY_OFFSET_START = 32; // "L-30"
protected static final int LAST_DAY_OFFSET_END = LAST_DAY_OFFSET_START + MAX_LAST_DAY_OFFSET; // 'L'
protected static final Integer ALL_SPEC = ALL_SPEC_INT;
protected static final Integer NO_SPEC = NO_SPEC_INT;
protected static final Map<String, Integer> monthMap = new HashMap<String, Integer>(20);
protected static final Map<String, Integer> monthMap = new HashMap<>(20);
protected static final Map<String, Integer> dayMap = new HashMap<String, Integer>(60);
protected static final Map<String, Integer> dayMap = new HashMap<>(60);
static {
monthMap.put("JAN", 0);
monthMap.put("FEB", 1);
@@ -253,21 +239,17 @@ public final class CronExpression implements Serializable, Cloneable {
protected transient TreeSet<Integer> daysOfMonth;
protected transient TreeSet<Integer> nearestWeekdays;
protected transient TreeSet<Integer> months;
protected transient TreeSet<Integer> daysOfWeek;
protected transient TreeSet<Integer> years;
protected transient boolean lastdayOfWeek = false;
protected transient boolean lastDayOfWeek = false;
protected transient int nthdayOfWeek = 0;
protected transient boolean lastdayOfMonth = false;
protected transient boolean nearestWeekday = false;
protected transient int lastdayOffset = 0;
protected transient int nthDayOfWeek = 0;
protected transient boolean expressionParsed = false;
@@ -305,7 +287,7 @@ public final class CronExpression implements Serializable, Cloneable {
buildExpression(cronExpression);
}
catch (ParseException ex) {
throw new AssertionError();
throw new AssertionError("Could not parse expression!", ex);
}
if (expression.getTimeZone() != null) {
setTimeZone((TimeZone) expression.getTimeZone().clone());
@@ -369,9 +351,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) {
@@ -445,39 +427,41 @@ public final class CronExpression implements Serializable, Cloneable {
try {
if (seconds == null) {
seconds = new TreeSet<Integer>();
seconds = new TreeSet<>();
}
if (minutes == null) {
minutes = new TreeSet<Integer>();
minutes = new TreeSet<>();
}
if (hours == null) {
hours = new TreeSet<Integer>();
hours = new TreeSet<>();
}
if (daysOfMonth == null) {
daysOfMonth = new TreeSet<Integer>();
daysOfMonth = new TreeSet<>();
}
if (nearestWeekdays == null) {
nearestWeekdays = new TreeSet<>();
}
if (months == null) {
months = new TreeSet<Integer>();
months = new TreeSet<>();
}
if (daysOfWeek == null) {
daysOfWeek = new TreeSet<Integer>();
daysOfWeek = new TreeSet<>();
}
if (years == null) {
years = new TreeSet<Integer>();
years = new TreeSet<>();
}
int exprOn = SECOND;
StringTokenizer exprsTok = new StringTokenizer(expression, " \t", false);
if (exprsTok.countTokens() > 7) {
throw new ParseException("Invalid expression has too many terms: " + expression, -1);
}
while (exprsTok.hasMoreTokens() && exprOn <= YEAR) {
String expr = exprsTok.nextToken().trim();
// throw an exception if L is used with other days of the month
if (exprOn == DAY_OF_MONTH && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) {
throw new ParseException(
"Support for specifying 'L' and 'LW' with other days of the month is not implemented", -1);
}
// throw an exception if L is used with other days of the week
if (exprOn == DAY_OF_WEEK && expr.indexOf('L') != -1 && expr.length() > 1 && expr.contains(",")) {
throw new ParseException(
@@ -524,7 +508,7 @@ public final class CronExpression implements Serializable, Cloneable {
throw pe;
}
catch (Exception e) {
throw new ParseException("Illegal cron expression format (" + e.toString() + ")", 0);
throw new ParseException("Illegal cron expression format (" + e + ")", 0);
}
}
@@ -575,8 +559,8 @@ public final class CronExpression implements Serializable, Cloneable {
else if (c == '#') {
try {
i += 4;
nthdayOfWeek = Integer.parseInt(s.substring(i));
if (nthdayOfWeek < 1 || nthdayOfWeek > 5) {
nthDayOfWeek = Integer.parseInt(s.substring(i));
if (nthDayOfWeek < 1 || nthDayOfWeek > 5) {
throw new Exception();
}
}
@@ -585,7 +569,7 @@ public final class CronExpression implements Serializable, Cloneable {
}
}
else if (c == 'L') {
lastdayOfWeek = true;
lastDayOfWeek = true;
i++;
}
}
@@ -609,9 +593,8 @@ public final class CronExpression implements Serializable, Cloneable {
if (type != DAY_OF_WEEK && type != DAY_OF_MONTH) {
throw new ParseException("'?' can only be specified for Day-of-Month or Day-of-Week.", i);
}
if (type == DAY_OF_WEEK && !lastdayOfMonth) {
int val = daysOfMonth.last();
if (val == NO_SPEC_INT) {
if (type == DAY_OF_WEEK) {
if (!daysOfMonth.isEmpty() && daysOfMonth.last() == NO_SPEC_INT) {
throw new ParseException("'?' can only be specified for Day-of-Month -OR- Day-of-Week.", i);
}
}
@@ -655,28 +638,35 @@ public final class CronExpression implements Serializable, Cloneable {
}
else if (c == 'L') {
i++;
if (type == DAY_OF_MONTH) {
lastdayOfMonth = true;
}
if (type == DAY_OF_WEEK) {
addToSet(7, 7, 0, type);
}
if (type == DAY_OF_MONTH && s.length() > i) {
c = s.charAt(i);
if (c == '-') {
ValueSet vs = getValue(0, s, i + 1);
lastdayOffset = vs.value;
if (lastdayOffset > 30) {
throw new ParseException("Offset from last day must be <= 30", i + 1);
}
i = vs.pos;
}
if (type == DAY_OF_MONTH) {
int dom = LAST_DAY_OFFSET_END;
boolean nearestWeekday = false;
if (s.length() > i) {
c = s.charAt(i);
if (c == 'W') {
nearestWeekday = true;
i++;
if (c == '-') {
ValueSet vs = getValue(0, s, i + 1);
int offset = vs.value;
if (offset > MAX_LAST_DAY_OFFSET)
throw new ParseException("Offset from last day must be <= " + MAX_LAST_DAY_OFFSET, i + 1);
dom -= offset;
i = vs.pos;
}
if (s.length() > i) {
c = s.charAt(i);
if (c == 'W') {
nearestWeekday = true;
i++;
}
}
}
if (nearestWeekday) {
nearestWeekdays.add(dom);
}
else {
daysOfMonth.add(dom);
}
}
return i;
@@ -737,10 +727,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;
lastDayOfWeek = true;
}
else {
throw new ParseException("'L' option is not valid here. (pos=" + i + ")", i);
@@ -752,19 +741,14 @@ public final class CronExpression implements Serializable, Cloneable {
}
if (c == 'W') {
if (type == DAY_OF_MONTH) {
nearestWeekday = true;
}
else {
if (type != DAY_OF_MONTH) {
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);
nearestWeekdays.add(val);
i++;
return i;
}
@@ -775,8 +759,8 @@ public final class CronExpression implements Serializable, Cloneable {
}
i++;
try {
nthdayOfWeek = Integer.parseInt(s.substring(i));
if (nthdayOfWeek < 1 || nthdayOfWeek > 5) {
nthDayOfWeek = Integer.parseInt(s.substring(i));
if (nthDayOfWeek < 1 || nthDayOfWeek > 5) {
throw new Exception();
}
}
@@ -886,23 +870,20 @@ public final class CronExpression implements Serializable, Cloneable {
buf.append("daysOfMonth: ");
buf.append(getExpressionSetSummary(daysOfMonth));
buf.append("\n");
buf.append("nearestWeekdays: ");
buf.append(getExpressionSetSummary(nearestWeekdays));
buf.append("\n");
buf.append("months: ");
buf.append(getExpressionSetSummary(months));
buf.append("\n");
buf.append("daysOfWeek: ");
buf.append(getExpressionSetSummary(daysOfWeek));
buf.append("\n");
buf.append("lastdayOfWeek: ");
buf.append(lastdayOfWeek);
buf.append("\n");
buf.append("nearestWeekday: ");
buf.append(nearestWeekday);
buf.append("lastDayOfWeek: ");
buf.append(lastDayOfWeek);
buf.append("\n");
buf.append("NthDayOfWeek: ");
buf.append(nthdayOfWeek);
buf.append("\n");
buf.append("lastdayOfMonth: ");
buf.append(lastdayOfMonth);
buf.append(nthDayOfWeek);
buf.append("\n");
buf.append("years: ");
buf.append(getExpressionSetSummary(years));
@@ -1226,7 +1207,7 @@ public final class CronExpression implements Serializable, Cloneable {
// get second.................................................
st = seconds.tailSet(sec);
if (st != null && st.size() != 0) {
if (st != null && !st.isEmpty()) {
sec = st.first();
}
else {
@@ -1242,7 +1223,7 @@ public final class CronExpression implements Serializable, Cloneable {
// get minute.................................................
st = minutes.tailSet(min);
if (st != null && st.size() != 0) {
if (st != null && !st.isEmpty()) {
t = min;
min = st.first();
}
@@ -1264,7 +1245,7 @@ public final class CronExpression implements Serializable, Cloneable {
// get hour...................................................
st = hours.tailSet(hr);
if (st != null && st.size() != 0) {
if (st != null && !st.isEmpty()) {
t = hr;
hr = st.first();
}
@@ -1292,67 +1273,13 @@ public final class CronExpression implements Serializable, Cloneable {
boolean dayOfMSpec = !daysOfMonth.contains(NO_SPEC);
boolean dayOfWSpec = !daysOfWeek.contains(NO_SPEC);
if (dayOfMSpec && !dayOfWSpec) { // get day by day of month rule
st = daysOfMonth.tailSet(day);
if (lastdayOfMonth) {
if (!nearestWeekday) {
t = day;
day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
day -= lastdayOffset;
if (t > day) {
mon++;
if (mon > 12) {
mon = 1;
tmon = 3333; // ensure test of mon != tmon further below
// fails
cl.add(Calendar.YEAR, 1);
}
day = 1;
}
}
else {
t = day;
day = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
day -= lastdayOffset;
java.util.Calendar tcal = java.util.Calendar.getInstance(getTimeZone());
tcal.set(Calendar.SECOND, 0);
tcal.set(Calendar.MINUTE, 0);
tcal.set(Calendar.HOUR_OF_DAY, 0);
tcal.set(Calendar.DAY_OF_MONTH, day);
tcal.set(Calendar.MONTH, mon - 1);
tcal.set(Calendar.YEAR, cl.get(Calendar.YEAR));
int ldom = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
int dow = tcal.get(Calendar.DAY_OF_WEEK);
if (dow == Calendar.SATURDAY && day == 1) {
day += 2;
}
else if (dow == Calendar.SATURDAY) {
day -= 1;
}
else if (dow == Calendar.SUNDAY && day == ldom) {
day -= 2;
}
else if (dow == Calendar.SUNDAY) {
day += 1;
}
tcal.set(Calendar.SECOND, sec);
tcal.set(Calendar.MINUTE, min);
tcal.set(Calendar.HOUR_OF_DAY, hr);
tcal.set(Calendar.DAY_OF_MONTH, day);
tcal.set(Calendar.MONTH, mon - 1);
Date nTime = tcal.getTime();
if (nTime.before(afterTime)) {
day = 1;
mon++;
}
}
}
else if (nearestWeekday) {
t = day;
day = daysOfMonth.first();
Optional<Integer> smallestDay = findSmallestDay(day, mon, cl.get(Calendar.YEAR), daysOfMonth);
Optional<Integer> smallestDayForWeekday = findSmallestDay(day, mon, cl.get(Calendar.YEAR),
nearestWeekdays);
t = day;
day = -1;
if (smallestDayForWeekday.isPresent()) {
day = smallestDayForWeekday.get();
java.util.Calendar tcal = java.util.Calendar.getInstance(getTimeZone());
tcal.set(Calendar.SECOND, 0);
@@ -1385,25 +1312,18 @@ public final class CronExpression implements Serializable, Cloneable {
tcal.set(Calendar.MONTH, mon - 1);
Date nTime = tcal.getTime();
if (nTime.before(afterTime)) {
day = daysOfMonth.first();
mon++;
day = -1;
}
}
else if (st != null && st.size() != 0) {
t = day;
day = st.first();
// make sure we don't over-run a short month, such as february
int lastDay = getLastDayOfMonth(mon, cl.get(Calendar.YEAR));
if (day > lastDay) {
day = daysOfMonth.first();
mon++;
if (smallestDay.isPresent()) {
if (day == -1 || smallestDay.get() < day) {
day = smallestDay.get();
}
}
else {
day = daysOfMonth.first();
else if (day == -1) {
day = 1;
mon++;
}
if (day != t || mon != tmon) {
cl.set(Calendar.SECOND, 0);
cl.set(Calendar.MINUTE, 0);
@@ -1416,7 +1336,7 @@ public final class CronExpression implements Serializable, Cloneable {
}
}
else if (dayOfWSpec && !dayOfMSpec) { // get day by day of week rule
if (lastdayOfWeek) { // are we looking for the last XXX day of
if (lastDayOfWeek) { // are we looking for the last XXX day of
// the month?
int dow = daysOfWeek.first(); // desired
// d-o-w
@@ -1460,7 +1380,7 @@ public final class CronExpression implements Serializable, Cloneable {
}
}
else if (nthdayOfWeek != 0) {
else if (nthDayOfWeek != 0) {
// are we looking for the Nth XXX day in the month?
int dow = daysOfWeek.first(); // desired
// d-o-w
@@ -1473,10 +1393,7 @@ public final class CronExpression implements Serializable, Cloneable {
daysToAdd = dow + (7 - cDow);
}
boolean dayShifted = false;
if (daysToAdd > 0) {
dayShifted = true;
}
boolean dayShifted = daysToAdd > 0;
day += daysToAdd;
int weekOfMonth = day / 7;
@@ -1484,7 +1401,7 @@ public final class CronExpression implements Serializable, Cloneable {
weekOfMonth++;
}
daysToAdd = (nthdayOfWeek - weekOfMonth) * 7;
daysToAdd = (nthDayOfWeek - weekOfMonth) * 7;
day += daysToAdd;
if (daysToAdd < 0 || day > getLastDayOfMonth(mon, cl.get(Calendar.YEAR))) {
cl.set(Calendar.SECOND, 0);
@@ -1510,7 +1427,7 @@ public final class CronExpression implements Serializable, Cloneable {
int dow = daysOfWeek.first(); // desired
// d-o-w
st = daysOfWeek.tailSet(cDow);
if (st != null && st.size() > 0) {
if (st != null && !st.isEmpty()) {
dow = st.first();
}
@@ -1534,7 +1451,7 @@ public final class CronExpression implements Serializable, Cloneable {
// no '- 1' here because we are promoting the month
continue;
}
else if (daysToAdd > 0) { // are we swithing days?
else if (daysToAdd > 0) { // are we switching days?
cl.set(Calendar.SECOND, 0);
cl.set(Calendar.MINUTE, 0);
cl.set(Calendar.HOUR_OF_DAY, 0);
@@ -1566,7 +1483,7 @@ public final class CronExpression implements Serializable, Cloneable {
// get month...................................................
st = months.tailSet(mon);
if (st != null && st.size() != 0) {
if (st != null && !st.isEmpty()) {
t = mon;
mon = st.first();
}
@@ -1594,7 +1511,7 @@ public final class CronExpression implements Serializable, Cloneable {
// get year...................................................
st = years.tailSet(year);
if (st != null && st.size() != 0) {
if (st != null && !st.isEmpty()) {
t = year;
year = st.first();
}
@@ -1688,6 +1605,27 @@ public final class CronExpression implements Serializable, Cloneable {
}
}
private Optional<Integer> findSmallestDay(int day, int mon, int year, TreeSet<Integer> set) {
if (set.isEmpty()) {
return Optional.empty();
}
final int lastDay = getLastDayOfMonth(mon, year);
// For "L", "L-1", etc.
int smallestDay = Optional.ofNullable(set.ceiling(LAST_DAY_OFFSET_END - (lastDay - day)))
.map(d -> d - LAST_DAY_OFFSET_START + 1)
.orElse(Integer.MAX_VALUE);
// For "1", "2", etc.
SortedSet<Integer> st = set.subSet(day, LAST_DAY_OFFSET_START);
// make sure we don't over-run a short month, such as february
if (!st.isEmpty() && st.first() < smallestDay && st.first() <= lastDay) {
smallestDay = st.first();
}
return smallestDay == Integer.MAX_VALUE ? Optional.empty() : Optional.of(smallestDay);
}
private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException {
stream.defaultReadObject();
@@ -1703,7 +1641,6 @@ public final class CronExpression implements Serializable, Cloneable {
public Object clone() {
return new CronExpression(this);
}
}
class ValueSet {
@@ -1711,5 +1648,4 @@ class ValueSet {
public int value;
public int pos;
}
}
@@ -12,11 +12,9 @@ public class XxlJobInfo {
private int id; // 主键ID
private int jobGroup; // 执行器主键ID
private String jobDesc;
private Date addTime;
private Date updateTime;
private String author; // 负责人
@@ -57,6 +55,7 @@ public class XxlJobInfo {
private long triggerNextTime; // 下次调度时间
public int getId() {
return id;
}
@@ -248,5 +247,4 @@ public class XxlJobInfo {
public void setTriggerNextTime(long triggerNextTime) {
this.triggerNextTime = triggerNextTime;
}
}
@@ -13,32 +13,23 @@ public class XxlJobLog {
// job info
private int jobGroup;
private int jobId;
// execute info
private String executorAddress;
private String executorHandler;
private String executorParam;
private String executorShardingParam;
private int executorFailRetryCount;
// trigger info
private Date triggerTime;
private int triggerCode;
private String triggerMsg;
// handle info
private Date handleTime;
private int handleCode;
private String handleMsg;
// alarm info
@@ -4,7 +4,6 @@ import java.util.Date;
/**
* xxl-job log for glue, used to track job code process
*
* @author xuxueli 2016-5-19 17:57:46
*/
public class XxlJobLogGlue {
@@ -14,13 +13,9 @@ public class XxlJobLogGlue {
private int jobId; // 任务主键ID
private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum
private String glueSource;
private String glueRemark;
private Date addTime;
private Date updateTime;
public int getId() {
@@ -53,5 +53,4 @@ public class XxlJobLogReport {
public void setFailCount(int failCount) {
this.failCount = failCount;
}
}
@@ -56,5 +56,4 @@ public class XxlJobRegistry {
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
@@ -1,7 +1,7 @@
package com.xxl.job.admin.core.route.strategy;
import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
import com.xxl.job.admin.core.route.ExecutorRouter;
import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
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.scheduler.XxlJobScheduler;
import com.xxl.job.admin.core.route.ExecutorRouter;
import com.xxl.job.admin.core.scheduler.XxlJobScheduler;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.core.biz.ExecutorBiz;
import com.xxl.job.core.biz.model.ReturnT;
@@ -49,5 +49,4 @@ public class ExecutorRouteFailover extends ExecutorRouter {
return new ReturnT<String>(ReturnT.FAIL_CODE, beatResultSB.toString());
}
}
@@ -20,7 +20,6 @@ import java.util.concurrent.*;
* @author xuxueli 2015-9-1 18:05:56
*/
public class JobCompleteHelper {
private static Logger logger = LoggerFactory.getLogger(JobCompleteHelper.class);
private static JobCompleteHelper instance = new JobCompleteHelper();
@@ -32,9 +31,7 @@ public class JobCompleteHelper {
// ---------------------- monitor ----------------------
private ThreadPoolExecutor callbackThreadPool = null;
private Thread monitorThread;
private volatile boolean toStop = false;
public void start() {
@@ -55,6 +52,7 @@ public class JobCompleteHelper {
}
});
// for monitor
monitorThread = new Thread(new Runnable() {
@@ -137,6 +135,7 @@ public class JobCompleteHelper {
}
}
// ---------------------- helper ----------------------
public ReturnT<String> callback(List<HandleCallbackParam> callbackParamList) {
@@ -190,4 +189,5 @@ public class JobCompleteHelper {
return ReturnT.SUCCESS;
}
}
@@ -17,7 +17,6 @@ import java.util.concurrent.TimeUnit;
* @author xuxueli 2015-9-1 18:05:56
*/
public class JobFailMonitorHelper {
private static Logger logger = LoggerFactory.getLogger(JobFailMonitorHelper.class);
private static JobFailMonitorHelper instance = new JobFailMonitorHelper();
@@ -29,7 +28,6 @@ public class JobFailMonitorHelper {
// ---------------------- monitor ----------------------
private Thread monitorThread;
private volatile boolean toStop = false;
public void start() {
@@ -10,214 +10,216 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.*;
/**
* job registry instance
*
* @author xuxueli 2016-10-02 19:10:24
*/
public class JobRegistryHelper {
private static Logger logger = LoggerFactory.getLogger(JobRegistryHelper.class);
private static Logger logger = LoggerFactory.getLogger(JobRegistryHelper.class);
private static JobRegistryHelper instance = new JobRegistryHelper();
private static JobRegistryHelper instance = new JobRegistryHelper();
private ThreadPoolExecutor registryOrRemoveThreadPool = null;
private Thread registryMonitorThread;
private volatile boolean toStop = false;
public static JobRegistryHelper getInstance() {
return instance;
}
public static JobRegistryHelper getInstance() {
return instance;
}
private ThreadPoolExecutor registryOrRemoveThreadPool = null;
public void start() {
private Thread registryMonitorThread;
// for registry or remove
registryOrRemoveThreadPool = new ThreadPoolExecutor(2, 10, 30L, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(2000), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r,
"xxl-job, admin JobRegistryMonitorHelper-registryOrRemoveThreadPool-" + r.hashCode());
}
}, new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
r.run();
logger.warn(
">>>>>>>>>>> xxl-job, registry or remove too fast, match threadpool rejected handler(run now).");
}
});
private volatile boolean toStop = false;
// for monitor
registryMonitorThread = new Thread(new Runnable() {
@Override
public void run() {
while (!toStop) {
try {
// auto registry group
List<XxlJobGroup> groupList = XxlJobAdminConfig.getAdminConfig()
.getXxlJobGroupDao()
.findByAddressType(0);
if (groupList != null && !groupList.isEmpty()) {
public void start() {
// remove dead address (admin/executor)
List<Integer> ids = XxlJobAdminConfig.getAdminConfig()
.getXxlJobRegistryDao()
.findDead(RegistryConfig.DEAD_TIMEOUT, new Date());
if (ids != null && ids.size() > 0) {
XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids);
}
// for registry or remove
registryOrRemoveThreadPool = new ThreadPoolExecutor(2, 10, 30L, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(2000), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r,
"xxl-job, admin JobRegistryMonitorHelper-registryOrRemoveThreadPool-" + r.hashCode());
}
}, new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
r.run();
logger.warn(
">>>>>>>>>>> xxl-job, registry or remove too fast, match threadpool rejected handler(run now).");
}
});
// fresh online address (admin/executor)
HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
List<XxlJobRegistry> list = XxlJobAdminConfig.getAdminConfig()
.getXxlJobRegistryDao()
.findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
if (list != null) {
for (XxlJobRegistry item : list) {
if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
String appname = item.getRegistryKey();
List<String> registryList = appAddressMap.get(appname);
if (registryList == null) {
registryList = new ArrayList<String>();
}
// for monitor
registryMonitorThread = new Thread(new Runnable() {
@Override
public void run() {
while (!toStop) {
try {
// auto registry group
List<XxlJobGroup> groupList = XxlJobAdminConfig.getAdminConfig()
.getXxlJobGroupDao()
.findByAddressType(0);
if (groupList != null && !groupList.isEmpty()) {
if (!registryList.contains(item.getRegistryValue())) {
registryList.add(item.getRegistryValue());
}
appAddressMap.put(appname, registryList);
}
}
}
// remove dead address (admin/executor)
Instant now = Instant.now();
Instant expiredInstant = now.minus(RegistryConfig.DEAD_TIMEOUT, ChronoUnit.SECONDS); // 假设 timeout 单位是秒
Date expiredTime = Date.from(expiredInstant);
List<Integer> ids = XxlJobAdminConfig.getAdminConfig()
.getXxlJobRegistryDao()
.findDead(expiredTime);
if (ids != null && ids.size() > 0) {
XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids);
}
// fresh group address
for (XxlJobGroup group : groupList) {
List<String> registryList = appAddressMap.get(group.getAppname());
String addressListStr = null;
if (registryList != null && !registryList.isEmpty()) {
Collections.sort(registryList);
StringBuilder addressListSB = new StringBuilder();
for (String item : registryList) {
addressListSB.append(item).append(",");
}
addressListStr = addressListSB.toString();
addressListStr = addressListStr.substring(0, addressListStr.length() - 1);
}
group.setAddressList(addressListStr);
group.setUpdateTime(new Date());
// fresh online address (admin/executor)
HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
List<XxlJobRegistry> list = XxlJobAdminConfig.getAdminConfig()
.getXxlJobRegistryDao()
.findAll(expiredTime);
if (list != null) {
for (XxlJobRegistry item : list) {
if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
String appname = item.getRegistryKey();
List<String> registryList = appAddressMap.get(appname);
if (registryList == null) {
registryList = new ArrayList<String>();
}
XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().update(group);
}
}
}
catch (Throwable e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
}
}
try {
TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT);
}
catch (Throwable e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
}
}
}
logger.info(">>>>>>>>>>> xxl-job, job registry monitor thread stop");
}
});
registryMonitorThread.setDaemon(true);
registryMonitorThread.setName("xxl-job, admin JobRegistryMonitorHelper-registryMonitorThread");
registryMonitorThread.start();
}
if (!registryList.contains(item.getRegistryValue())) {
registryList.add(item.getRegistryValue());
}
appAddressMap.put(appname, registryList);
}
}
}
public void toStop() {
toStop = true;
// fresh group address
for (XxlJobGroup group : groupList) {
List<String> registryList = appAddressMap.get(group.getAppname());
String addressListStr = null;
if (registryList != null && !registryList.isEmpty()) {
Collections.sort(registryList);
StringBuilder addressListSB = new StringBuilder();
for (String item : registryList) {
addressListSB.append(item).append(",");
}
addressListStr = addressListSB.toString();
addressListStr = addressListStr.substring(0, addressListStr.length() - 1);
}
group.setAddressList(addressListStr);
group.setUpdateTime(new Date());
// stop registryOrRemoveThreadPool
registryOrRemoveThreadPool.shutdownNow();
XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().update(group);
}
}
} catch (Exception e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
}
}
try {
TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT);
} catch (InterruptedException e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
}
}
}
logger.info(">>>>>>>>>>> xxl-job, job registry monitor thread stop");
}
});
registryMonitorThread.setDaemon(true);
registryMonitorThread.setName("xxl-job, admin JobRegistryMonitorHelper-registryMonitorThread");
registryMonitorThread.start();
}
// stop monitir (interrupt and wait)
registryMonitorThread.interrupt();
try {
registryMonitorThread.join();
}
catch (Throwable e) {
logger.error(e.getMessage(), e);
}
}
public void toStop() {
toStop = true;
// ---------------------- helper ----------------------
// stop registryOrRemoveThreadPool
registryOrRemoveThreadPool.shutdownNow();
public ReturnT<String> registry(RegistryParam registryParam) {
// stop monitir (interrupt and wait)
registryMonitorThread.interrupt();
try {
registryMonitorThread.join();
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
// valid
if (!StringUtils.hasText(registryParam.getRegistryGroup())
|| !StringUtils.hasText(registryParam.getRegistryKey())
|| !StringUtils.hasText(registryParam.getRegistryValue())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument.");
}
// ---------------------- helper ----------------------
// async execute
registryOrRemoveThreadPool.execute(new Runnable() {
@Override
public void run() {
// 0-fail; 1-save suc; 2-update suc;
int ret = XxlJobAdminConfig.getAdminConfig()
.getXxlJobRegistryDao()
.registrySaveOrUpdate(registryParam.getRegistryGroup(), registryParam.getRegistryKey(),
registryParam.getRegistryValue(), new Date());
if (ret == 1) {
// fresh (add)
freshGroupRegistryInfo(registryParam);
}
/*
* int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().
* registryUpdate(registryParam.getRegistryGroup(),
* registryParam.getRegistryKey(), registryParam.getRegistryValue(), new
* Date()); if (ret < 1) {
* XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registrySave(
* registryParam.getRegistryGroup(), registryParam.getRegistryKey(),
* registryParam.getRegistryValue(), new Date());
*
* // fresh freshGroupRegistryInfo(registryParam); }
*/
}
});
public ReturnT<String> registry(RegistryParam registryParam) {
return ReturnT.SUCCESS;
}
// valid
if (!StringUtils.hasText(registryParam.getRegistryGroup())
|| !StringUtils.hasText(registryParam.getRegistryKey())
|| !StringUtils.hasText(registryParam.getRegistryValue())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument.");
}
public ReturnT<String> registryRemove(RegistryParam registryParam) {
// async execute
registryOrRemoveThreadPool.execute(new Runnable() {
@Override
public void run() {
int ret = XxlJobAdminConfig.getAdminConfig()
.getXxlJobRegistryDao()
.registryUpdate(registryParam.getRegistryGroup(), registryParam.getRegistryKey(),
registryParam.getRegistryValue(), new Date());
if (ret < 1) {
XxlJobAdminConfig.getAdminConfig()
.getXxlJobRegistryDao()
.registrySave(registryParam.getRegistryGroup(), registryParam.getRegistryKey(),
registryParam.getRegistryValue(), new Date());
// valid
if (!StringUtils.hasText(registryParam.getRegistryGroup())
|| !StringUtils.hasText(registryParam.getRegistryKey())
|| !StringUtils.hasText(registryParam.getRegistryValue())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument.");
}
// fresh
freshGroupRegistryInfo(registryParam);
}
}
});
// async execute
registryOrRemoveThreadPool.execute(new Runnable() {
@Override
public void run() {
int ret = XxlJobAdminConfig.getAdminConfig()
.getXxlJobRegistryDao()
.registryDelete(registryParam.getRegistryGroup(), registryParam.getRegistryKey(),
registryParam.getRegistryValue());
if (ret > 0) {
// fresh (delete)
freshGroupRegistryInfo(registryParam);
}
}
});
return ReturnT.SUCCESS;
}
return ReturnT.SUCCESS;
}
public ReturnT<String> registryRemove(RegistryParam registryParam) {
private void freshGroupRegistryInfo(RegistryParam registryParam) {
// Under consideration, prevent affecting core tables
}
// valid
if (!StringUtils.hasText(registryParam.getRegistryGroup())
|| !StringUtils.hasText(registryParam.getRegistryKey())
|| !StringUtils.hasText(registryParam.getRegistryValue())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument.");
}
// async execute
registryOrRemoveThreadPool.execute(new Runnable() {
@Override
public void run() {
int ret = XxlJobAdminConfig.getAdminConfig()
.getXxlJobRegistryDao()
.registryDelete(registryParam.getRegistryGroup(), registryParam.getRegistryKey(),
registryParam.getRegistryValue());
if (ret > 0) {
// fresh
freshGroupRegistryInfo(registryParam);
}
}
});
return ReturnT.SUCCESS;
}
private void freshGroupRegistryInfo(RegistryParam registryParam) {
// Under consideration, prevent affecting core tables
}
}
@@ -419,7 +419,7 @@ public class JobScheduleHelper {
* FIX_DELAY ==
* scheduleTypeEnum
*/) {
return new Date(fromTime.getTime() + Integer.valueOf(jobInfo.getScheduleConf()) * 1000);
return new Date(fromTime.getTime() + Long.parseLong(jobInfo.getScheduleConf()) * 1000L);
}
return null;
}
@@ -57,6 +57,7 @@ public class JobTriggerPoolHelper {
});
}
public void stop() {
// triggerPool.shutdown();
fastTriggerPool.shutdownNow();
@@ -13,7 +13,6 @@ public class CookieUtil {
// 默认缓存时间,单位/秒, 2H
private static final int COOKIE_MAX_AGE = Integer.MAX_VALUE;
// 保存路径,根路径
private static final String COOKIE_PATH = "/";
@@ -12,13 +12,12 @@ import java.io.IOException;
/**
* Jackson util
*
*
* 1、obj need private and set/get; 2、do not support inner class;
*
*
* @author xuxueli 2015-9-25 18:02:56
*/
public class JacksonUtil {
private static Logger logger = LoggerFactory.getLogger(JacksonUtil.class);
private final static ObjectMapper objectMapper = new ObjectMapper();
@@ -96,5 +95,4 @@ public class JacksonUtil {
}
return null;
}
}
@@ -55,6 +55,7 @@ public class LocalCacheUtil {
}
/**
* set cache
* @param key
@@ -6,9 +6,9 @@ import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* job info
*
* @author xuxueli 2016-1-12 18:03:45
*/
@Mapper
@@ -23,7 +23,7 @@ public interface XxlJobInfoDao {
@Param("jobGroup") int jobGroup, @Param("triggerStatus") int triggerStatus,
@Param("jobDesc") String jobDesc, @Param("executorHandler") String executorHandler,
@Param("author") String author);
public int save(XxlJobInfo info);
public XxlJobInfo loadById(@Param("id") int id);
@@ -54,4 +54,5 @@ public interface XxlJobInfoDao {
*/
public int scheduleUpdate(XxlJobInfo xxlJobInfo);
}
@@ -10,7 +10,6 @@ import java.util.Map;
/**
* job log
*
* @author xuxueli 2016-1-12 18:03:06
*/
@Mapper
@@ -26,7 +25,7 @@ public interface XxlJobLogDao {
@Param("jobGroup") int jobGroup, @Param("jobId") int jobId,
@Param("triggerTimeStart") Date triggerTimeStart, @Param("triggerTimeEnd") Date triggerTimeEnd,
@Param("logStatus") int logStatus);
public XxlJobLog load(@Param("id") long id);
public long save(XxlJobLog xxlJobLog);
@@ -42,7 +41,6 @@ public interface XxlJobLogDao {
public List<Long> findClearLogIds(@Param("jobGroup") int jobGroup, @Param("jobId") int jobId,
@Param("clearBeforeTime") Date clearBeforeTime, @Param("clearBeforeNum") int clearBeforeNum,
@Param("pagesize") int pagesize);
public int clearLog(@Param("logIds") List<Long> logIds);
public List<Long> findFailJobLogIds(@Param("pagesize") int pagesize);
@@ -8,7 +8,6 @@ import java.util.List;
/**
* job log for glue
*
* @author xuxueli 2016-5-19 18:04:56
*/
@Mapper
@@ -9,7 +9,6 @@ import java.util.List;
/**
* job log
*
* @author xuxueli 2019-11-22
*/
@Mapper
@@ -13,17 +13,33 @@ import java.util.List;
@Mapper
public interface XxlJobRegistryDao {
public List<Integer> findDead(@Param("expiredTime") Date expiredTime);
public List<Integer> findDead(@Param("timeout") int timeout, @Param("nowTime") Date nowTime);
public int removeDead(@Param("ids") List<Integer> ids);
public List<XxlJobRegistry> findAll(@Param("expiredTime") Date expiredTime);
public List<XxlJobRegistry> findAll(@Param("timeout") int timeout, @Param("nowTime") Date nowTime);
public int registryUpdate(@Param("registryGroup") String registryGroup, @Param("registryKey") String registryKey,
@Param("registryValue") String registryValue, @Param("updateTime") Date updateTime);
public int registrySaveOrUpdate(@Param("registryGroup") String registryGroup,
@Param("registryKey") String registryKey, @Param("registryValue") String registryValue,
@Param("updateTime") Date updateTime);
public int registrySave(@Param("registryGroup") String registryGroup, @Param("registryKey") String registryKey,
@Param("registryValue") String registryValue, @Param("updateTime") Date updateTime);
/*
* public int registryUpdate(@Param("registryGroup") String registryGroup,
*
* @Param("registryKey") String registryKey,
*
* @Param("registryValue") String registryValue,
*
* @Param("updateTime") Date updateTime);
*
* public int registrySave(@Param("registryGroup") String registryGroup,
*
* @Param("registryKey") String registryKey,
*
* @Param("registryValue") String registryValue,
*
* @Param("updateTime") Date updateTime);
*/
public int registryDelete(@Param("registryGroup") String registryGroup, @Param("registryKey") String registryKey,
@Param("registryValue") String registryValue);
@@ -1,5 +1,6 @@
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;
@@ -9,7 +10,7 @@ import java.util.Map;
/**
* core job action for xxl-job
*
*
* @author xuxueli 2016-5-28 15:30:33
*/
public interface XxlJobService {
@@ -106,4 +106,5 @@ public class LoginService {
return null;
}
}
@@ -28,26 +28,20 @@ import java.util.*;
/**
* core job action for xxl-job
*
* @author xuxueli 2016-5-28 15:30:33
*/
@Service
public class XxlJobServiceImpl implements XxlJobService {
private static Logger logger = LoggerFactory.getLogger(XxlJobServiceImpl.class);
@Resource
private XxlJobGroupDao xxlJobGroupDao;
@Resource
private XxlJobInfoDao xxlJobInfoDao;
@Resource
public XxlJobLogDao xxlJobLogDao;
@Resource
private XxlJobLogGlueDao xxlJobLogGlueDao;
@Resource
private XxlJobLogReportDao xxlJobLogReportDao;
@@ -60,7 +54,7 @@ public class XxlJobServiceImpl implements XxlJobService {
author);
int list_count = xxlJobInfoDao.pageListCount(start, length, jobGroup, triggerStatus, jobDesc, executorHandler,
author);
// package result
Map<String, Object> maps = new HashMap<String, Object>();
maps.put("recordsTotal", list_count); // 总记录数
@@ -185,6 +179,8 @@ public class XxlJobServiceImpl implements XxlJobService {
jobInfo.setAddTime(new Date());
jobInfo.setUpdateTime(new Date());
jobInfo.setGlueUpdatetime(new Date());
// remove the whitespace
jobInfo.setExecutorHandler(jobInfo.getExecutorHandler().trim());
xxlJobInfoDao.save(jobInfo);
if (jobInfo.getId() < 1) {
return new ReturnT<String>(ReturnT.FAIL_CODE,
@@ -349,7 +345,8 @@ public class XxlJobServiceImpl implements XxlJobService {
exists_jobInfo.setScheduleConf(jobInfo.getScheduleConf());
exists_jobInfo.setMisfireStrategy(jobInfo.getMisfireStrategy());
exists_jobInfo.setExecutorRouteStrategy(jobInfo.getExecutorRouteStrategy());
exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler());
// remove the whitespace
exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler().trim());
exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam());
exists_jobInfo.setExecutorBlockStrategy(jobInfo.getExecutorBlockStrategy());
exists_jobInfo.setExecutorTimeout(jobInfo.getExecutorTimeout());
@@ -360,6 +357,7 @@ public class XxlJobServiceImpl implements XxlJobService {
exists_jobInfo.setUpdateTime(new Date());
xxlJobInfoDao.update(exists_jobInfo);
return ReturnT.SUCCESS;
}
@@ -378,7 +376,11 @@ public class XxlJobServiceImpl implements XxlJobService {
@Override
public ReturnT<String> start(int id) {
// load and valid
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
if (xxlJobInfo == null) {
return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("jobinfo_glue_jobid_unvalid"));
}
// valid
ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(xxlJobInfo.getScheduleType(), ScheduleTypeEnum.NONE);
@@ -414,8 +416,13 @@ public class XxlJobServiceImpl implements XxlJobService {
@Override
public ReturnT<String> stop(int id) {
// load and valid
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
if (xxlJobInfo == null) {
return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("jobinfo_glue_jobid_unvalid"));
}
// stop
xxlJobInfo.setTriggerStatus(0);
xxlJobInfo.setTriggerLastTime(0);
xxlJobInfo.setTriggerNextTime(0);
@@ -425,6 +432,7 @@ public class XxlJobServiceImpl implements XxlJobService {
return ReturnT.SUCCESS;
}
@Override
public ReturnT<String> trigger(XxlJobUser loginUser, int jobId, String executorParam, String addressList) {
// permission
@@ -1,6 +1,6 @@
admin_name=Scheduling Center
admin_name_full=Distributed Task Scheduling Platform XXL-JOB
admin_version=3.0.0
admin_version=3.1.1
admin_i18n=en
## system
@@ -1,6 +1,6 @@
admin_name=任务调度中心
admin_name_full=分布式任务调度平台XXL-JOB
admin_version=3.0.0
admin_version=3.1.1
admin_i18n=
## system
@@ -1,6 +1,6 @@
admin_name=任務調度中心
admin_name_full=分布式任務調度平臺XXL-JOB
admin_version=3.0.0
admin_version=3.1.1
admin_i18n=
## system
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxl.job.admin.dao.XxlJobGroupDao">
<resultMap id="XxlJobGroup" type="com.xxl.job.admin.core.model.XxlJobGroup" >
<resultMap id="XxlJobGroup" type="com.xxl.job.admin.core.model.XxlJobGroup" >
<result column="id" property="id" />
<result column="app_name" property="appname" />
<result column="title" property="title" />
<result column="app_name" property="appname"/>
<result column="title" property="title"/>
<result column="address_type" property="addressType" />
<result column="address_list" property="addressList" />
<result column="update_time" property="updateTime" />
@@ -35,17 +35,17 @@
</select>
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobGroup" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO xxl_job_group ( app_name, title, address_type, address_list, update_time)
INSERT INTO xxl_job_group ( `app_name`, `title`, `address_type`, `address_list`, `update_time`)
values ( #{appname}, #{title}, #{addressType}, #{addressList}, #{updateTime} );
</insert>
<update id="update" parameterType="com.xxl.job.admin.core.model.XxlJobGroup" >
UPDATE xxl_job_group
SET app_name = #{appname},
title = #{title},
address_type = #{addressType},
address_list = #{addressList},
update_time = #{updateTime}
SET `app_name` = #{appname},
`title` = #{title},
`address_type` = #{addressType},
`address_list` = #{addressList},
`update_time` = #{updateTime}
WHERE id = #{id}
</update>
@@ -88,4 +88,4 @@
</trim>
</select>
</mapper>
</mapper>
@@ -188,8 +188,8 @@
executor_handler = #{executorHandler},
executor_param = #{executorParam},
executor_block_strategy = #{executorBlockStrategy},
executor_timeout = ${executorTimeout},
executor_fail_retry_count = ${executorFailRetryCount},
executor_timeout = #{executorTimeout},
executor_fail_retry_count = #{executorFailRetryCount},
glue_type = #{glueType},
glue_source = #{glueSource},
glue_remark = #{glueRemark},
@@ -232,11 +232,12 @@
UPDATE xxl_job_info
SET
trigger_last_time = #{triggerLastTime},
trigger_next_time = #{triggerNextTime}
<if test="triggerStatus gte 0">
, trigger_status = #{triggerStatus}
</if>
trigger_next_time = #{triggerNextTime}
<if test="triggerStatus gte 0">
, trigger_status = #{triggerStatus}
</if>
WHERE id = #{id}
AND trigger_status = 1
</update>
</mapper>
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxl.job.admin.dao.XxlJobLogGlueDao">
<resultMap id="XxlJobLogGlue" type="com.xxl.job.admin.core.model.XxlJobLogGlue" >
<resultMap id="XxlJobLogGlue" type="com.xxl.job.admin.core.model.XxlJobLogGlue" >
<result column="id" property="id" />
<result column="job_id" property="jobId" />
<result column="job_id" property="jobId"/>
<result column="glue_type" property="glueType" />
<result column="glue_source" property="glueSource" />
<result column="glue_remark" property="glueRemark" />
<result column="add_time" property="addTime" />
<result column="update_time" property="updateTime" />
<result column="glue_source" property="glueSource"/>
<result column="glue_remark" property="glueRemark"/>
<result column="add_time" property="addTime"/>
<result column="update_time" property="updateTime"/>
</resultMap>
<sql id="Base_Column_List">
@@ -23,49 +23,49 @@
t.update_time
</sql>
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobLogGlue" useGeneratedKeys="true" keyProperty="id" >
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobLogGlue" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO xxl_job_logglue (
job_id,
glue_type,
glue_source,
glue_remark,
add_time,
update_time
`job_id`,
`glue_type`,
`glue_source`,
`glue_remark`,
`add_time`,
`update_time`
) VALUES (
#{jobId},
#{glueType},
#{glueSource},
#{glueRemark},
#{addTime},
#{updateTime}
#{jobId},
#{glueType},
#{glueSource},
#{glueRemark},
#{addTime},
#{updateTime}
);
<!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID()
SELECT LAST_INSERT_ID()
</selectKey>-->
</insert>
<select id="findByJobId" parameterType="java.lang.Integer" resultMap="XxlJobLogGlue">
<select id="findByJobId" parameterType="java.lang.Integer" resultMap="XxlJobLogGlue">
SELECT <include refid="Base_Column_List" />
FROM xxl_job_logglue AS t
WHERE t.job_id = #{jobId}
ORDER BY id DESC
</select>
<delete id="removeOld" >
<delete id="removeOld" >
DELETE FROM xxl_job_logglue
WHERE id NOT in(
SELECT id FROM(
SELECT id FROM xxl_job_logglue
WHERE job_id = #{jobId}
ORDER BY update_time desc
LIMIT 0, #{limit}
) t1
) AND job_id = #{jobId}
SELECT id FROM(
SELECT id FROM xxl_job_logglue
WHERE `job_id` = #{jobId}
ORDER BY update_time desc
LIMIT 0, #{limit}
) t1
) AND `job_id` = #{jobId}
</delete>
<delete id="deleteByJobId" parameterType="java.lang.Integer" >
<delete id="deleteByJobId" parameterType="java.lang.Integer" >
DELETE FROM xxl_job_logglue
WHERE job_id = #{jobId}
WHERE `job_id` = #{jobId}
</delete>
</mapper>
</mapper>
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxl.job.admin.dao.XxlJobLogDao">
<resultMap id="XxlJobLog" type="com.xxl.job.admin.core.model.XxlJobLog" >
<resultMap id="XxlJobLog" type="com.xxl.job.admin.core.model.XxlJobLog" >
<result column="id" property="id" />
<result column="job_group" property="jobGroup" />
@@ -11,17 +11,17 @@
<result column="executor_address" property="executorAddress" />
<result column="executor_handler" property="executorHandler" />
<result column="executor_param" property="executorParam" />
<result column="executor_param" property="executorParam"/>
<result column="executor_sharding_param" property="executorShardingParam" />
<result column="executor_fail_retry_count" property="executorFailRetryCount" />
<result column="trigger_time" property="triggerTime" />
<result column="trigger_code" property="triggerCode" />
<result column="trigger_msg" property="triggerMsg" />
<result column="trigger_time" property="triggerTime"/>
<result column="trigger_code" property="triggerCode"/>
<result column="trigger_msg" property="triggerMsg"/>
<result column="handle_time" property="handleTime" />
<result column="handle_code" property="handleCode" />
<result column="handle_msg" property="handleMsg" />
<result column="handle_time" property="handleTime"/>
<result column="handle_code" property="handleCode"/>
<result column="handle_msg" property="handleMsg"/>
<result column="alarm_status" property="alarmStatus" />
</resultMap>
@@ -44,7 +44,7 @@
t.alarm_status
</sql>
<select id="pageList" resultMap="XxlJobLog">
<select id="pageList" resultMap="XxlJobLog">
SELECT <include refid="Base_Column_List" />
FROM xxl_job_log AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" >
@@ -65,8 +65,8 @@
</if>
<if test="logStatus == 2" >
AND (
t.trigger_code NOT IN (0, 200) OR
t.handle_code NOT IN (0, 200)
t.trigger_code NOT IN (0, 200) OR
t.handle_code NOT IN (0, 200)
)
</if>
<if test="logStatus == 3" >
@@ -78,7 +78,7 @@
LIMIT #{offset}, #{pagesize}
</select>
<select id="pageListCount" resultType="int">
<select id="pageListCount" resultType="int">
SELECT count(1)
FROM xxl_job_log AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" >
@@ -99,8 +99,8 @@
</if>
<if test="logStatus == 2" >
AND (
t.trigger_code NOT IN (0, 200) OR
t.handle_code NOT IN (0, 200)
t.trigger_code NOT IN (0, 200) OR
t.handle_code NOT IN (0, 200)
)
</if>
<if test="logStatus == 3" >
@@ -110,80 +110,80 @@
</trim>
</select>
<select id="load" parameterType="java.lang.Long" resultMap="XxlJobLog">
<select id="load" parameterType="java.lang.Long" resultMap="XxlJobLog">
SELECT <include refid="Base_Column_List" />
FROM xxl_job_log AS t
WHERE t.id = #{id}
</select>
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobLog" useGeneratedKeys="true" keyProperty="id" >
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobLog" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO xxl_job_log (
job_group,
job_id,
trigger_time,
trigger_code,
handle_code
`job_group`,
`job_id`,
`trigger_time`,
`trigger_code`,
`handle_code`
) VALUES (
#{jobGroup},
#{jobId},
#{triggerTime},
#{triggerCode},
#{handleCode}
#{jobGroup},
#{jobId},
#{triggerTime},
#{triggerCode},
#{handleCode}
);
<!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID()
SELECT LAST_INSERT_ID()
</selectKey>-->
</insert>
<update id="updateTriggerInfo" >
UPDATE xxl_job_log
SET
trigger_time= #{triggerTime},
trigger_code= #{triggerCode},
trigger_msg= #{triggerMsg},
executor_address= #{executorAddress},
executor_handler=#{executorHandler},
executor_param= #{executorParam},
executor_sharding_param= #{executorShardingParam},
executor_fail_retry_count= #{executorFailRetryCount}
WHERE id= #{id}
`trigger_time`= #{triggerTime},
`trigger_code`= #{triggerCode},
`trigger_msg`= #{triggerMsg},
`executor_address`= #{executorAddress},
`executor_handler`=#{executorHandler},
`executor_param`= #{executorParam},
`executor_sharding_param`= #{executorShardingParam},
`executor_fail_retry_count`= #{executorFailRetryCount}
WHERE `id`= #{id}
</update>
<update id="updateHandleInfo">
UPDATE xxl_job_log
SET
handle_time= #{handleTime},
handle_code= #{handleCode},
handle_msg= #{handleMsg}
WHERE id= #{id}
SET
`handle_time`= #{handleTime},
`handle_code`= #{handleCode},
`handle_msg`= #{handleMsg}
WHERE `id`= #{id}
</update>
<delete id="delete" >
<delete id="delete" >
delete from xxl_job_log
WHERE job_id = #{jobId}
</delete>
<!--<select id="triggerCountByDay" resultType="java.util.Map" >
SELECT
DATE_FORMAT(trigger_time,'%Y-%m-%d') triggerDay,
COUNT(handle_code) triggerDayCount,
SUM(CASE WHEN (trigger_code in (0, 200) and handle_code = 0) then 1 else 0 end) as triggerDayCountRunning,
SUM(CASE WHEN handle_code = 200 then 1 else 0 end) as triggerDayCountSuc
FROM xxl_job_log
WHERE trigger_time BETWEEN #{from} and #{to}
GROUP BY triggerDay
ORDER BY triggerDay
</select>-->
<select id="findLogReport" resultType="java.util.Map" >
<!--<select id="triggerCountByDay" resultType="java.util.Map" >
SELECT
COUNT(handle_code) triggerDayCount,
SUM(CASE WHEN (trigger_code in (0, 200) and handle_code = 0) then 1 else 0 end) as triggerDayCountRunning,
SUM(CASE WHEN handle_code = 200 then 1 else 0 end) as triggerDayCountSuc
DATE_FORMAT(trigger_time,'%Y-%m-%d') triggerDay,
COUNT(handle_code) triggerDayCount,
SUM(CASE WHEN (trigger_code in (0, 200) and handle_code = 0) then 1 else 0 end) as triggerDayCountRunning,
SUM(CASE WHEN handle_code = 200 then 1 else 0 end) as triggerDayCountSuc
FROM xxl_job_log
WHERE trigger_time BETWEEN #{from} and #{to}
</select>
GROUP BY triggerDay
ORDER BY triggerDay
</select>-->
<select id="findLogReport" resultType="java.util.Map">
SELECT
COUNT(handle_code) `triggerDayCount`,
SUM(CASE WHEN (trigger_code in (0, 200) and handle_code = 0) then 1 else 0 end) as `triggerDayCountRunning`,
SUM(CASE WHEN handle_code = 200 then 1 else 0 end) as `triggerDayCountSuc`
FROM xxl_job_log
WHERE trigger_time BETWEEN #{from} and #{to}
</select>
<select id="findClearLogIds" resultType="long" >
SELECT id FROM xxl_job_log
@@ -228,15 +228,13 @@
</delete>
<select id="findFailJobLogIds" resultType="long" >
SELECT id
FROM xxl_job_log
WHERE
NOT (
(trigger_code IN (0, 200) AND handle_code = 0)
OR
(handle_code = 200)
SELECT id FROM `xxl_job_log`
WHERE !(
(trigger_code in (0, 200) and handle_code = 0)
OR
(handle_code = 200)
)
AND alarm_status = 0
AND `alarm_status` = 0
ORDER BY id ASC
LIMIT #{pagesize}
</select>
@@ -244,20 +242,32 @@
<update id="updateAlarmStatus" >
UPDATE xxl_job_log
SET
alarm_status = #{newAlarmStatus}
WHERE id= #{logId} AND alarm_status = #{oldAlarmStatus}
`alarm_status` = #{newAlarmStatus}
WHERE `id`= #{logId} AND `alarm_status` = #{oldAlarmStatus}
</update>
<select id="findLostJobIds" resultType="long" >
SELECT
t.id
t.id
FROM
xxl_job_log t
LEFT JOIN xxl_job_registry t2 ON t.executor_address = t2.registry_value
xxl_job_log t
LEFT JOIN xxl_job_registry t2 ON t.executor_address = t2.registry_value
WHERE
t.trigger_code = 200
AND t.handle_code = 0
AND t.trigger_time <![CDATA[ <= ]]> #{losedTime}
AND t2.id IS NULL;
t.trigger_code = 200
AND t.handle_code = 0
AND t.trigger_time <![CDATA[ <= ]]> #{losedTime}
AND t2.id IS NULL;
</select>
</mapper>
<!--
SELECT t.id
FROM xxl_job_log AS t
WHERE t.trigger_code = 200
and t.handle_code = 0
and t.trigger_time <![CDATA[ <= ]]> #{losedTime}
and t.executor_address not in (
SELECT t2.registry_value
FROM xxl_job_registry AS t2
)
-->
</mapper>
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxl.job.admin.dao.XxlJobLogReportDao">
<resultMap id="XxlJobLogReport" type="com.xxl.job.admin.core.model.XxlJobLogReport" >
<resultMap id="XxlJobLogReport" type="com.xxl.job.admin.core.model.XxlJobLogReport" >
<result column="id" property="id" />
<result column="trigger_day" property="triggerDay" />
<result column="trigger_day" property="triggerDay"/>
<result column="running_count" property="runningCount" />
<result column="suc_count" property="sucCount" />
<result column="fail_count" property="failCount" />
<result column="suc_count" property="sucCount"/>
<result column="fail_count" property="failCount"/>
</resultMap>
<sql id="Base_Column_List">
@@ -19,30 +19,30 @@
t.fail_count
</sql>
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobLogReport" useGeneratedKeys="true" keyProperty="id" >
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobLogReport" useGeneratedKeys="true" keyProperty="id" >
INSERT INTO xxl_job_log_report (
trigger_day,
running_count,
suc_count,
fail_count
`trigger_day`,
`running_count`,
`suc_count`,
`fail_count`
) VALUES (
#{triggerDay},
#{runningCount},
#{sucCount},
#{failCount}
#{triggerDay},
#{runningCount},
#{sucCount},
#{failCount}
);
<!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID()
SELECT LAST_INSERT_ID()
</selectKey>-->
</insert>
<update id="update" >
UPDATE xxl_job_log_report
SET running_count = #{runningCount},
suc_count = #{sucCount},
fail_count = #{failCount}
WHERE trigger_day = #{triggerDay}
</update>
UPDATE xxl_job_log_report
SET `running_count` = #{runningCount},
`suc_count` = #{sucCount},
`fail_count` = #{failCount}
WHERE `trigger_day` = #{triggerDay}
</update>
<select id="queryLogReport" resultMap="XxlJobLogReport">
SELECT <include refid="Base_Column_List" />
@@ -53,10 +53,10 @@
<select id="queryLogReportTotal" resultMap="XxlJobLogReport">
SELECT
SUM(running_count) running_count,
SUM(suc_count) suc_count,
SUM(fail_count) fail_count
SUM(running_count) running_count,
SUM(suc_count) suc_count,
SUM(fail_count) fail_count
FROM xxl_job_log_report AS t
</select>
</mapper>
</mapper>
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxl.job.admin.dao.XxlJobRegistryDao">
<resultMap id="XxlJobRegistry" type="com.xxl.job.admin.core.model.XxlJobRegistry" >
<resultMap id="XxlJobRegistry" type="com.xxl.job.admin.core.model.XxlJobRegistry" >
<result column="id" property="id" />
<result column="registry_group" property="registryGroup" />
<result column="registry_key" property="registryKey" />
<result column="registry_value" property="registryValue" />
<result column="registry_group" property="registryGroup"/>
<result column="registry_key" property="registryKey"/>
<result column="registry_value" property="registryValue"/>
<result column="update_time" property="updateTime" />
</resultMap>
@@ -22,10 +22,10 @@
<select id="findDead" parameterType="java.util.HashMap" resultType="java.lang.Integer" >
SELECT t.id
FROM xxl_job_registry AS t
WHERE t.update_time <![CDATA[ < ]]> #{expiredTime}
WHERE t.update_time <![CDATA[ < ]]> DATE_ADD(#{nowTime},INTERVAL -#{timeout} SECOND)
</select>
<delete id="removeDead" parameterType="java.lang.Integer" >
<delete id="removeDead" parameterType="java.lang.Integer" >
DELETE FROM xxl_job_registry
WHERE id in
<foreach collection="ids" item="item" open="(" close=")" separator="," >
@@ -36,27 +36,36 @@
<select id="findAll" parameterType="java.util.HashMap" resultMap="XxlJobRegistry">
SELECT <include refid="Base_Column_List" />
FROM xxl_job_registry AS t
WHERE t.update_time > #{expiredTime}
WHERE t.update_time <![CDATA[ > ]]> DATE_ADD(#{nowTime},INTERVAL -#{timeout} SECOND)
</select>
<update id="registryUpdate" >
UPDATE xxl_job_registry
SET update_time = #{updateTime}
WHERE registry_group = #{registryGroup}
AND registry_key = #{registryKey}
AND registry_value = #{registryValue}
</update>
<insert id="registrySaveOrUpdate">
INSERT INTO xxl_job_registry( `registry_group` , `registry_key` , `registry_value`, `update_time`)
VALUES( #{registryGroup} , #{registryKey} , #{registryValue}, #{updateTime})
ON DUPLICATE KEY UPDATE
`update_time` = #{updateTime}
</insert>
<insert id="registrySave" >
INSERT INTO xxl_job_registry( registry_group , registry_key , registry_value, update_time)
VALUES( #{registryGroup} , #{registryKey} , #{registryValue}, #{updateTime})
</insert>
<!--
<update id="registryUpdate" >
UPDATE xxl_job_registry
SET `update_time` = #{updateTime}
WHERE `registry_group` = #{registryGroup}
AND `registry_key` = #{registryKey}
AND `registry_value` = #{registryValue}
</update>
<insert id="registrySave" >
INSERT INTO xxl_job_registry( `registry_group` , `registry_key` , `registry_value`, `update_time`)
VALUES( #{registryGroup} , #{registryKey} , #{registryValue}, #{updateTime})
</insert>
-->
<delete id="registryDelete" >
DELETE FROM xxl_job_registry
WHERE registry_group = #{registryGroup}
AND registry_key = #{registryKey}
AND registry_value = #{registryValue}
AND registry_key = #{registryKey}
AND registry_value = #{registryValue}
</delete>
</mapper>
</mapper>
@@ -258,24 +258,27 @@
var weekly3 = $("<div/>",{"class":"line"});
$("<input/>",{type : "radio", value : "3", name : "week"}).appendTo(weekly3);
$(weekly3).append("周期 从星期");
$(weekly3).append("周期 每周第");
$("<input/>",{type : "text", id : "weekStart_0", value : "1", style:"width:35px; height:20px; text-align: center; margin: 0 3px;"}).appendTo(weekly3);
$(weekly3).append("-");
$(weekly3).append("天-第");
$("<input/>",{type : "text", id : "weekEnd_0", value : "2", style:"width:35px; height:20px; text-align: center; margin: 0 3px;"}).appendTo(weekly3);
$(weekly3).append("天");
$(weekly3).appendTo(weeklyTab);
var weekly4 = $("<div/>",{"class":"line"});
$("<input/>",{type : "radio", value : "4", name : "week"}).appendTo(weekly4);
$(weekly4).append("第");
$(weekly4).append("从第");
$("<input/>",{type : "text", id : "weekStart_1", value : "1", style:"width:35px; height:20px; text-align: center; margin: 0 3px;"}).appendTo(weekly4);
$(weekly4).append("周的星期");
$(weekly4).append("天开始,间隔");
$("<input/>",{type : "text", id : "weekEnd_1", value : "1", style:"width:35px; height:20px; text-align: center; margin: 0 3px;"}).appendTo(weekly4);
$(weekly4).append("天执行一次");
$(weekly4).appendTo(weeklyTab);
var weekly5 = $("<div/>",{"class":"line"});
$("<input/>",{type : "radio", value : "5", name : "week"}).appendTo(weekly5);
$(weekly5).append("本月最后一个星期");
$(weekly5).append("本月最后一周的第");
$("<input/>",{type : "text", id : "weekStart_2", value : "1", style:"width:35px; height:20px; text-align: center; margin: 0 3px;"}).appendTo(weekly5);
$(weekly5).append("天");
$(weekly5).appendTo(weeklyTab);
var weekly6 = $("<div/>",{"class":"line"});
@@ -283,7 +286,7 @@
$(weekly6).append("指定");
$(weekly6).appendTo(weeklyTab);
$(weeklyTab).append('<div class="imp weekList"><input type="checkbox" disabled="disabled" style="margin-left: 5px" value="1">1<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="2">2<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="3">3<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="4">4<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="5">5<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="6">6<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="7">7</div>');
$(weeklyTab).append('<div class="imp weekList"><input type="checkbox" disabled="disabled" style="margin-left: 5px" value="1">周日<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="2">周一<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="3">周二<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="4">周三<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="5">周四<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="6">周五<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="7">周六</div>');
$("<input/>",{type : "hidden", id : "weekHidden"}).appendTo(weeklyTab);
$(weeklyTab).appendTo(tabContent);
@@ -268,7 +268,7 @@
$("<input/>",{type : "radio", value : "4", name : "week"}).appendTo(weekly4);
$(weekly4).append("The");
$("<input/>",{type : "text", id : "weekStart_1", value : "1", style:"width:35px; height:20px; text-align: center; margin: 0 3px;"}).appendTo(weekly4);
$(weekly4).append("th week, and day ");
$(weekly4).append("th week, once every ");
$("<input/>",{type : "text", id : "weekEnd_1", value : "1", style:"width:35px; height:20px; text-align: center; margin: 0 3px;"}).appendTo(weekly4);
$(weekly4).appendTo(weeklyTab);
@@ -283,7 +283,7 @@
$(weekly6).append("specify");
$(weekly6).appendTo(weeklyTab);
$(weeklyTab).append('<div class="imp weekList"><input type="checkbox" disabled="disabled" style="margin-left: 5px" value="1">1<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="2">2<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="3">3<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="4">4<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="5">5<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="6">6<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="7">7</div>');
$(weeklyTab).append('<div class="imp weekList"><input type="checkbox" disabled="disabled" style="margin-left: 5px" value="1">SUN<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="2">MON<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="3">TUE<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="4">WED<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="5">THU<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="6">FRI<input type="checkbox" disabled="disabled" style="margin-left: 5px" value="7">SAT</div>');
$("<input/>",{type : "hidden", id : "weekHidden"}).appendTo(weeklyTab);
$(weeklyTab).appendTo(tabContent);
@@ -59,7 +59,7 @@
<#list jobLogGlues as glue>
<li>
<a href="javascript:;" class="source_version" version="version_${glue.id}" glueType="${glue.glueType}" >
<#list GlueTypeEnum as item><#if item == glue.glueType>${item.desc}</#if></#list>: ${glue.glueRemark}
${glue.addTime?string["yyyy-MM-dd HH:mm:ss"]}: ${glue.glueRemark}
</a>
</li>
<textarea id="version_${glue.id}" style="display:none;" >${glue.glueSource}</textarea>
+1 -1
View File
@@ -54,7 +54,7 @@
<ttl.version>2.12.6</ttl.version>
<jimu.version>2.0.0</jimu.version>
<aws.version>1.12.261</aws.version>
<xxl.job.version>3.0.0</xxl.job.version>
<xxl.job.version>3.1.1</xxl.job.version>
<docker.registry>registry.cn-hangzhou.aliyuncs.com</docker.registry>
<docker.host>http://127.0.0.1:2375</docker.host>
<docker.namespace>pigcloudx</docker.namespace>