mirror of https://github.com/elunez/eladmin
commit
4e38658746
11
README.md
11
README.md
|
@ -12,11 +12,8 @@
|
|||
|
||||
请勿使用此分支开发
|
||||
|
||||
#### 赞助商 | Sponsor
|
||||
|
||||
<a href="https://www.mingdao.com/?s=utm_79&utm_source=eladmin&utm_medium=banner&utm_campaign=github&utm_content=IT赋能业务" target="_blank">
|
||||
<img src="https://eladmin.vip/images/banner/index.png" alt="明道云零代码构建平台" style="width: 400px;border-radius: 2px;">
|
||||
</a>
|
||||
|
||||
#### 项目捐赠
|
||||
项目的发展离不开你的支持,请作者喝杯咖啡吧☕ [Donate](https://eladmin.vip/donation/)
|
||||
项目的发展离不开你的支持,请作者喝杯咖啡吧☕ [Donate](https://eladmin.vip/pages/030101/)
|
||||
|
||||
#### 反馈交流
|
||||
- QQ交流群:891137268 、947578238、659622532
|
|
@ -9,7 +9,7 @@
|
|||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<properties>
|
||||
<hutool.version>5.8.20</hutool.version>
|
||||
<hutool.version>5.8.21</hutool.version>
|
||||
</properties>
|
||||
|
||||
<artifactId>eladmin-common</artifactId>
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package me.zhengjie.aspect;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import me.zhengjie.annotation.Limit;
|
||||
import me.zhengjie.exception.BadRequestException;
|
||||
|
@ -71,9 +72,9 @@ public class LimitAspect {
|
|||
ImmutableList<Object> keys = ImmutableList.of(StringUtils.join(limit.prefix(), "_", key, "_", request.getRequestURI().replace("/","_")));
|
||||
|
||||
String luaScript = buildLuaScript();
|
||||
RedisScript<Number> redisScript = new DefaultRedisScript<>(luaScript, Number.class);
|
||||
Number count = redisTemplate.execute(redisScript, keys, limit.count(), limit.period());
|
||||
if (null != count && count.intValue() <= limit.count()) {
|
||||
RedisScript<Long> redisScript = new DefaultRedisScript<>(luaScript, Long.class);
|
||||
Long count = redisTemplate.execute(redisScript, keys, limit.count(), limit.period());
|
||||
if (ObjUtil.isNotNull(count) && count.intValue() <= limit.count()) {
|
||||
logger.info("第{}次访问key为 {},描述为 [{}] 的接口", count, keys, limit.name());
|
||||
return joinPoint.proceed();
|
||||
} else {
|
||||
|
|
|
@ -33,8 +33,10 @@ import java.security.MessageDigest;
|
|||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* File工具类,扩展 hutool 工具包
|
||||
|
@ -213,8 +215,25 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
|
|||
String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx";
|
||||
File file = new File(tempPath);
|
||||
BigExcelWriter writer = ExcelUtil.getBigWriter(file);
|
||||
// 处理数据以防止CSV注入
|
||||
List<Map<String, Object>> sanitizedList = list.parallelStream().map(map -> {
|
||||
Map<String, Object> sanitizedMap = new HashMap<>();
|
||||
map.forEach((key, value) -> {
|
||||
if (value instanceof String) {
|
||||
String strValue = (String) value;
|
||||
// 检查并处理以特殊字符开头的值
|
||||
if (strValue.startsWith("=") || strValue.startsWith("+") || strValue.startsWith("-") || strValue.startsWith("@")) {
|
||||
strValue = "'" + strValue; // 添加单引号前缀
|
||||
}
|
||||
sanitizedMap.put(key, strValue);
|
||||
} else {
|
||||
sanitizedMap.put(key, value);
|
||||
}
|
||||
});
|
||||
return sanitizedMap;
|
||||
}).collect(Collectors.toList());
|
||||
// 一次性写出内容,使用默认样式,强制输出标题
|
||||
writer.write(list, true);
|
||||
writer.write(sanitizedList, true);
|
||||
SXSSFSheet sheet = (SXSSFSheet)writer.getSheet();
|
||||
//上面需要强转SXSSFSheet 不然没有trackAllColumnsForAutoSizing方法
|
||||
sheet.trackAllColumnsForAutoSizing();
|
||||
|
|
|
@ -45,6 +45,12 @@
|
|||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- quartz -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-quartz</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- jwt -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
|
@ -62,12 +68,6 @@
|
|||
<version>${jjwt.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- quartz -->
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- linux的管理 -->
|
||||
<dependency>
|
||||
<groupId>ch.ethz.ganymed</groupId>
|
||||
|
|
|
@ -37,24 +37,24 @@ public class DeployHistory implements Serializable {
|
|||
|
||||
@Id
|
||||
@Column(name = "history_id")
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty(value = "应用名称")
|
||||
private String appName;
|
||||
|
||||
@ApiModelProperty(value = "IP")
|
||||
@ApiModelProperty(value = "IP")
|
||||
private String ip;
|
||||
|
||||
@CreationTimestamp
|
||||
@ApiModelProperty(value = "部署时间")
|
||||
@CreationTimestamp
|
||||
@ApiModelProperty(value = "部署时间")
|
||||
private Timestamp deployDate;
|
||||
|
||||
@ApiModelProperty(value = "部署者")
|
||||
@ApiModelProperty(value = "部署者")
|
||||
private String deployUser;
|
||||
|
||||
@ApiModelProperty(value = "部署ID")
|
||||
private Long deployId;
|
||||
@ApiModelProperty(value = "部署ID")
|
||||
private Long deployId;
|
||||
|
||||
public void copy(DeployHistory source){
|
||||
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
|
||||
|
|
|
@ -55,7 +55,7 @@ public class AppController {
|
|||
|
||||
@ApiOperation(value = "查询应用")
|
||||
@GetMapping
|
||||
@PreAuthorize("@el.check('app:list')")
|
||||
@PreAuthorize("@el.check('app:list')")
|
||||
public ResponseEntity<PageResult<AppDto>> queryApp(AppQueryCriteria criteria, Pageable pageable){
|
||||
return new ResponseEntity<>(appService.queryAll(criteria,pageable),HttpStatus.OK);
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public class AppController {
|
|||
@Log("新增应用")
|
||||
@ApiOperation(value = "新增应用")
|
||||
@PostMapping
|
||||
@PreAuthorize("@el.check('app:add')")
|
||||
@PreAuthorize("@el.check('app:add')")
|
||||
public ResponseEntity<Object> createApp(@Validated @RequestBody App resources){
|
||||
appService.create(resources);
|
||||
return new ResponseEntity<>(HttpStatus.CREATED);
|
||||
|
@ -72,7 +72,7 @@ public class AppController {
|
|||
@Log("修改应用")
|
||||
@ApiOperation(value = "修改应用")
|
||||
@PutMapping
|
||||
@PreAuthorize("@el.check('app:edit')")
|
||||
@PreAuthorize("@el.check('app:edit')")
|
||||
public ResponseEntity<Object> updateApp(@Validated @RequestBody App resources){
|
||||
appService.update(resources);
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
|
@ -80,8 +80,8 @@ public class AppController {
|
|||
|
||||
@Log("删除应用")
|
||||
@ApiOperation(value = "删除应用")
|
||||
@DeleteMapping
|
||||
@PreAuthorize("@el.check('app:del')")
|
||||
@DeleteMapping
|
||||
@PreAuthorize("@el.check('app:del')")
|
||||
public ResponseEntity<Object> deleteApp(@RequestBody Set<Long> ids){
|
||||
appService.delete(ids);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
|
|
|
@ -111,8 +111,8 @@ public class DatabaseController {
|
|||
DatabaseDto database = databaseService.findById(id);
|
||||
String fileName;
|
||||
if(database != null){
|
||||
fileName = file.getOriginalFilename();
|
||||
File executeFile = new File(fileSavePath+fileName);
|
||||
fileName = FileUtil.verifyFilename(file.getOriginalFilename());
|
||||
File executeFile = new File(fileSavePath + fileName);
|
||||
FileUtil.del(executeFile);
|
||||
file.transferTo(executeFile);
|
||||
String result = SqlUtils.executeFile(database.getJdbcUrl(), database.getUserName(), database.getPwd(), executeFile);
|
||||
|
|
|
@ -18,6 +18,7 @@ package me.zhengjie.modules.mnt.rest;
|
|||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.zhengjie.annotation.Log;
|
||||
import me.zhengjie.exception.BadRequestException;
|
||||
import me.zhengjie.modules.mnt.domain.Deploy;
|
||||
|
@ -40,13 +41,13 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author zhanghouying
|
||||
* @date 2019-08-24
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@Api(tags = "运维:部署管理")
|
||||
@RequiredArgsConstructor
|
||||
|
@ -68,7 +69,7 @@ public class DeployController {
|
|||
@GetMapping
|
||||
@PreAuthorize("@el.check('deploy:list')")
|
||||
public ResponseEntity<PageResult<DeployDto>> queryDeployData(DeployQueryCriteria criteria, Pageable pageable){
|
||||
return new ResponseEntity<>(deployService.queryAll(criteria,pageable),HttpStatus.OK);
|
||||
return new ResponseEntity<>(deployService.queryAll(criteria,pageable),HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Log("新增部署")
|
||||
|
@ -105,21 +106,21 @@ public class DeployController {
|
|||
Long id = Long.valueOf(request.getParameter("id"));
|
||||
String fileName = "";
|
||||
if(file != null){
|
||||
fileName = file.getOriginalFilename();
|
||||
File deployFile = new File(fileSavePath+fileName);
|
||||
fileName = FileUtil.verifyFilename(file.getOriginalFilename());
|
||||
File deployFile = new File(fileSavePath + fileName);
|
||||
FileUtil.del(deployFile);
|
||||
file.transferTo(deployFile);
|
||||
//文件下一步要根据文件名字来
|
||||
deployService.deploy(fileSavePath+fileName ,id);
|
||||
deployService.deploy(fileSavePath + fileName ,id);
|
||||
}else{
|
||||
System.out.println("没有找到相对应的文件");
|
||||
log.warn("没有找到相对应的文件");
|
||||
}
|
||||
System.out.println("文件上传的原名称为:"+ Objects.requireNonNull(file).getOriginalFilename());
|
||||
Map<String,Object> map = new HashMap<>(2);
|
||||
map.put("errno",0);
|
||||
map.put("error",0);
|
||||
map.put("id",fileName);
|
||||
return new ResponseEntity<>(map,HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Log("系统还原")
|
||||
@ApiOperation(value = "系统还原")
|
||||
@PostMapping(value = "/serverReduction")
|
||||
|
@ -128,14 +129,16 @@ public class DeployController {
|
|||
String result = deployService.serverReduction(resources);
|
||||
return new ResponseEntity<>(result,HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Log("服务运行状态")
|
||||
@ApiOperation(value = "服务运行状态")
|
||||
@PostMapping(value = "/serverStatus")
|
||||
@PreAuthorize("@el.check('deploy:edit')")
|
||||
public ResponseEntity<Object> serverStatus(@Validated @RequestBody Deploy resources){
|
||||
String result = deployService.serverStatus(resources);
|
||||
return new ResponseEntity<>(result,HttpStatus.OK);
|
||||
return new ResponseEntity<>(result,HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Log("启动服务")
|
||||
@ApiOperation(value = "启动服务")
|
||||
@PostMapping(value = "/startServer")
|
||||
|
@ -144,6 +147,7 @@ public class DeployController {
|
|||
String result = deployService.startServer(resources);
|
||||
return new ResponseEntity<>(result,HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Log("停止服务")
|
||||
@ApiOperation(value = "停止服务")
|
||||
@PostMapping(value = "/stopServer")
|
||||
|
|
|
@ -53,14 +53,14 @@ public class DeployHistoryController {
|
|||
|
||||
@ApiOperation(value = "查询部署历史")
|
||||
@GetMapping
|
||||
@PreAuthorize("@el.check('deployHistory:list')")
|
||||
@PreAuthorize("@el.check('deployHistory:list')")
|
||||
public ResponseEntity<PageResult<DeployHistoryDto>> queryDeployHistory(DeployHistoryQueryCriteria criteria, Pageable pageable){
|
||||
return new ResponseEntity<>(deployhistoryService.queryAll(criteria,pageable),HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Log("删除DeployHistory")
|
||||
@ApiOperation(value = "删除部署历史")
|
||||
@DeleteMapping
|
||||
@DeleteMapping
|
||||
@PreAuthorize("@el.check('deployHistory:del')")
|
||||
public ResponseEntity<Object> deleteDeployHistory(@RequestBody Set<String> ids){
|
||||
deployhistoryService.delete(ids);
|
||||
|
|
|
@ -55,15 +55,15 @@ public class ServerDeployController {
|
|||
|
||||
@ApiOperation(value = "查询服务器")
|
||||
@GetMapping
|
||||
@PreAuthorize("@el.check('serverDeploy:list')")
|
||||
@PreAuthorize("@el.check('serverDeploy:list')")
|
||||
public ResponseEntity<PageResult<ServerDeployDto>> queryServerDeploy(ServerDeployQueryCriteria criteria, Pageable pageable){
|
||||
return new ResponseEntity<>(serverDeployService.queryAll(criteria,pageable),HttpStatus.OK);
|
||||
return new ResponseEntity<>(serverDeployService.queryAll(criteria,pageable),HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Log("新增服务器")
|
||||
@ApiOperation(value = "新增服务器")
|
||||
@PostMapping
|
||||
@PreAuthorize("@el.check('serverDeploy:add')")
|
||||
@PreAuthorize("@el.check('serverDeploy:add')")
|
||||
public ResponseEntity<Object> createServerDeploy(@Validated @RequestBody ServerDeploy resources){
|
||||
serverDeployService.create(resources);
|
||||
return new ResponseEntity<>(HttpStatus.CREATED);
|
||||
|
@ -72,7 +72,7 @@ public class ServerDeployController {
|
|||
@Log("修改服务器")
|
||||
@ApiOperation(value = "修改服务器")
|
||||
@PutMapping
|
||||
@PreAuthorize("@el.check('serverDeploy:edit')")
|
||||
@PreAuthorize("@el.check('serverDeploy:edit')")
|
||||
public ResponseEntity<Object> updateServerDeploy(@Validated @RequestBody ServerDeploy resources){
|
||||
serverDeployService.update(resources);
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
|
@ -80,18 +80,18 @@ public class ServerDeployController {
|
|||
|
||||
@Log("删除服务器")
|
||||
@ApiOperation(value = "删除Server")
|
||||
@DeleteMapping
|
||||
@PreAuthorize("@el.check('serverDeploy:del')")
|
||||
@DeleteMapping
|
||||
@PreAuthorize("@el.check('serverDeploy:del')")
|
||||
public ResponseEntity<Object> deleteServerDeploy(@RequestBody Set<Long> ids){
|
||||
serverDeployService.delete(ids);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Log("测试连接服务器")
|
||||
@ApiOperation(value = "测试连接服务器")
|
||||
@PostMapping("/testConnect")
|
||||
@PreAuthorize("@el.check('serverDeploy:add')")
|
||||
public ResponseEntity<Object> testConnectServerDeploy(@Validated @RequestBody ServerDeploy resources){
|
||||
return new ResponseEntity<>(serverDeployService.testConnect(resources),HttpStatus.CREATED);
|
||||
}
|
||||
@Log("测试连接服务器")
|
||||
@ApiOperation(value = "测试连接服务器")
|
||||
@PostMapping("/testConnect")
|
||||
@PreAuthorize("@el.check('serverDeploy:add')")
|
||||
public ResponseEntity<Object> testConnectServerDeploy(@Validated @RequestBody ServerDeploy resources){
|
||||
return new ResponseEntity<>(serverDeployService.testConnect(resources),HttpStatus.CREATED);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,15 +88,15 @@ public class DatabaseServiceImpl implements DatabaseService {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean testConnection(Database resources) {
|
||||
try {
|
||||
return SqlUtils.testConnection(resources.getJdbcUrl(), resources.getUserName(), resources.getPwd());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean testConnection(Database resources) {
|
||||
try {
|
||||
return SqlUtils.testConnection(resources.getJdbcUrl(), resources.getUserName(), resources.getPwd());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void download(List<DatabaseDto> queryAll, HttpServletResponse response) throws IOException {
|
||||
|
|
|
@ -67,22 +67,22 @@ public class ServerDeployServiceImpl implements ServerDeployService {
|
|||
return serverDeployMapper.toDto(deploy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean testConnect(ServerDeploy resources) {
|
||||
ExecuteShellUtil executeShellUtil = null;
|
||||
try {
|
||||
executeShellUtil = new ExecuteShellUtil(resources.getIp(), resources.getAccount(), resources.getPassword(),resources.getPort());
|
||||
return executeShellUtil.execute("ls")==0;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}finally {
|
||||
if (executeShellUtil != null) {
|
||||
executeShellUtil.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Boolean testConnect(ServerDeploy resources) {
|
||||
ExecuteShellUtil executeShellUtil = null;
|
||||
try {
|
||||
executeShellUtil = new ExecuteShellUtil(resources.getIp(), resources.getAccount(), resources.getPassword(),resources.getPort());
|
||||
return executeShellUtil.execute("ls")==0;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}finally {
|
||||
if (executeShellUtil != null) {
|
||||
executeShellUtil.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void create(ServerDeploy resources) {
|
||||
serverDeployRepository.save(resources);
|
||||
|
@ -93,7 +93,7 @@ public class ServerDeployServiceImpl implements ServerDeployService {
|
|||
public void update(ServerDeploy resources) {
|
||||
ServerDeploy serverDeploy = serverDeployRepository.findById(resources.getId()).orElseGet(ServerDeploy::new);
|
||||
ValidationUtil.isNull( serverDeploy.getId(),"ServerDeploy","id",resources.getId());
|
||||
serverDeploy.copy(resources);
|
||||
serverDeploy.copy(resources);
|
||||
serverDeployRepository.save(serverDeploy);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,8 @@ public class SqlUtils {
|
|||
druidDataSource.setDriverClassName(className);
|
||||
}
|
||||
|
||||
// 去掉不安全的参数
|
||||
jdbcUrl = sanitizeJdbcUrl(jdbcUrl);
|
||||
|
||||
druidDataSource.setUrl(jdbcUrl);
|
||||
druidDataSource.setUsername(userName);
|
||||
|
@ -198,4 +200,33 @@ public class SqlUtils {
|
|||
return sqlList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 去除不安全的参数
|
||||
* @param jdbcUrl /
|
||||
* @return /
|
||||
*/
|
||||
private static String sanitizeJdbcUrl(String jdbcUrl) {
|
||||
// 定义不安全参数和其安全替代值
|
||||
String[][] unsafeParams = {
|
||||
// allowLoadLocalInfile:允许使用 LOAD DATA LOCAL INFILE,可能导致文件泄露
|
||||
{"allowLoadLocalInfile", "false"},
|
||||
// allowUrlInLocalInfile:允许在 LOAD DATA LOCAL INFILE 中使用 URL,可能导致未经授权的文件访问
|
||||
{"allowUrlInLocalInfile", "false"},
|
||||
// autoDeserialize:允许自动反序列化对象,可能导致反序列化漏洞
|
||||
{"autoDeserialize", "false"},
|
||||
// allowNanAndInf:允许使用 NaN 和 Infinity 作为数字值,可能导致不一致的数据处理
|
||||
{"allowNanAndInf", "false"},
|
||||
// allowMultiQueries:允许在一个语句中执行多个查询,可能导致 SQL 注入攻击
|
||||
{"allowMultiQueries", "false"},
|
||||
// allowPublicKeyRetrieval:允许从服务器检索公钥,可能导致中间人攻击
|
||||
{"allowPublicKeyRetrieval", "false"}
|
||||
};
|
||||
|
||||
// 替换不安全的参数
|
||||
for (String[] param : unsafeParams) {
|
||||
jdbcUrl = jdbcUrl.replaceAll("(?i)" + param[0] + "=true", param[0] + "=" + param[1]);
|
||||
}
|
||||
return jdbcUrl;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,9 +15,13 @@
|
|||
*/
|
||||
package me.zhengjie.modules.quartz.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.spi.TriggerFiredBundle;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.scheduling.quartz.AdaptableJobFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
@ -26,7 +30,9 @@ import org.springframework.stereotype.Component;
|
|||
* @author /
|
||||
* @date 2019-01-07
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@Scope("singleton")
|
||||
public class QuartzConfig {
|
||||
|
||||
/**
|
||||
|
@ -37,16 +43,24 @@ public class QuartzConfig {
|
|||
|
||||
private final AutowireCapableBeanFactory capableBeanFactory;
|
||||
|
||||
@Autowired
|
||||
public QuartzJobFactory(AutowireCapableBeanFactory capableBeanFactory) {
|
||||
this.capableBeanFactory = capableBeanFactory;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
|
||||
//调用父类的方法,把Job注入到spring中
|
||||
Object jobInstance = super.createJobInstance(bundle);
|
||||
capableBeanFactory.autowireBean(jobInstance);
|
||||
return jobInstance;
|
||||
protected Object createJobInstance(@NonNull TriggerFiredBundle bundle) throws Exception {
|
||||
try {
|
||||
// 调用父类的方法,把Job注入到spring中
|
||||
Object jobInstance = super.createJobInstance(bundle);
|
||||
capableBeanFactory.autowireBean(jobInstance);
|
||||
log.debug("Job instance created and autowired: {}", jobInstance.getClass().getName());
|
||||
return jobInstance;
|
||||
} catch (Exception e) {
|
||||
log.error("Error creating job instance for bundle: {}", bundle, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import me.zhengjie.exception.BadRequestException;
|
|||
import me.zhengjie.modules.quartz.domain.QuartzJob;
|
||||
import org.quartz.*;
|
||||
import org.quartz.impl.triggers.CronTriggerImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
|
@ -57,8 +56,12 @@ public class QuartzManage {
|
|||
//重置启动时间
|
||||
((CronTriggerImpl)cronTrigger).setStartTime(new Date());
|
||||
|
||||
//执行定时任务
|
||||
scheduler.scheduleJob(jobDetail,cronTrigger);
|
||||
//执行定时任务,如果是持久化的,这里会报错,捕获输出
|
||||
try {
|
||||
scheduler.scheduleJob(jobDetail,cronTrigger);
|
||||
} catch (ObjectAlreadyExistsException e) {
|
||||
log.warn("定时任务已存在,跳过加载");
|
||||
}
|
||||
|
||||
// 暂停任务
|
||||
if (quartzJob.getIsPause()) {
|
||||
|
|
|
@ -141,7 +141,6 @@ public class OnlineUserService {
|
|||
* 根据用户名强退用户
|
||||
* @param username /
|
||||
*/
|
||||
@Async
|
||||
public void kickOutForUsername(String username) {
|
||||
String loginKey = properties.getOnlineKey() + username + "*";
|
||||
redisUtils.scanDel(loginKey);
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# 配置 quartz 分布式支持, sql 文件在 sql 目录下,需要导入到数据库,并且需要修改 application.yml 文件的 active: dev 配置
|
||||
spring:
|
||||
quartz:
|
||||
# 必需,指定使用 JDBC 存储
|
||||
job-store-type: jdbc
|
||||
properties:
|
||||
org:
|
||||
quartz:
|
||||
scheduler:
|
||||
# 必需,指定调度器实例的名称
|
||||
instanceName: eladmin
|
||||
# 必需,指定调度器实例的 ID
|
||||
instanceId: auto
|
||||
threadPool:
|
||||
# 可选,线程池的线程数量,可以根据需要调整
|
||||
threadCount: 5
|
||||
jobStore:
|
||||
# 可选,如果你不需要集群,可以去掉
|
||||
isClustered: true
|
||||
# 可选,集群检查间隔时间,可以根据需要调整
|
||||
clusterCheckinInterval: 10000
|
||||
# 必需,指定 JDBC 驱动代理类
|
||||
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
|
||||
# 可选,是否使用属性存储,可以根据需要调整
|
||||
useProperties: false
|
||||
# 必需,指定表的前缀
|
||||
tablePrefix: qrtz_
|
||||
# 可选,指定误触发阈值,可以根据需要调整
|
||||
misfireThreshold: 60000
|
|
@ -8,6 +8,7 @@ spring:
|
|||
freemarker:
|
||||
check-template-location: false
|
||||
profiles:
|
||||
# 激活的环境,如果需要 quartz 分布式支持,需要修改 active: dev,quartz
|
||||
active: dev
|
||||
data:
|
||||
redis:
|
||||
|
|
|
@ -615,7 +615,6 @@ INSERT INTO `sys_roles_menus` VALUES (112, 1);
|
|||
INSERT INTO `sys_roles_menus` VALUES (113, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (114, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (116, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (120, 1);
|
||||
INSERT INTO `sys_roles_menus` VALUES (1, 2);
|
||||
INSERT INTO `sys_roles_menus` VALUES (2, 2);
|
||||
INSERT INTO `sys_roles_menus` VALUES (6, 2);
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
drop table if exists qrtz_fired_triggers;
|
||||
drop table if exists qrtz_paused_trigger_grps;
|
||||
drop table if exists qrtz_scheduler_state;
|
||||
drop table if exists qrtz_locks;
|
||||
drop table if exists qrtz_simple_triggers;
|
||||
drop table if exists qrtz_simprop_triggers;
|
||||
drop table if exists qrtz_cron_triggers;
|
||||
drop table if exists qrtz_blob_triggers;
|
||||
drop table if exists qrtz_triggers;
|
||||
drop table if exists qrtz_job_details;
|
||||
drop table if exists qrtz_calendars;
|
||||
|
||||
create table qrtz_job_details(
|
||||
sched_name varchar(120) not null,
|
||||
job_name varchar(200) not null,
|
||||
job_group varchar(200) not null,
|
||||
description varchar(250) null,
|
||||
job_class_name varchar(250) not null,
|
||||
is_durable varchar(1) not null,
|
||||
is_nonconcurrent varchar(1) not null,
|
||||
is_update_data varchar(1) not null,
|
||||
requests_recovery varchar(1) not null,
|
||||
job_data blob null,
|
||||
primary key (sched_name, job_name, job_group))
|
||||
engine=innodb;
|
||||
|
||||
create table qrtz_triggers (
|
||||
sched_name varchar(120) not null,
|
||||
trigger_name varchar(200) not null,
|
||||
trigger_group varchar(200) not null,
|
||||
job_name varchar(200) not null,
|
||||
job_group varchar(200) not null,
|
||||
description varchar(250) null,
|
||||
next_fire_time bigint(13) null,
|
||||
prev_fire_time bigint(13) null,
|
||||
priority integer null,
|
||||
trigger_state varchar(16) not null,
|
||||
trigger_type varchar(8) not null,
|
||||
start_time bigint(13) not null,
|
||||
end_time bigint(13) null,
|
||||
calendar_name varchar(200) null,
|
||||
misfire_instr smallint(2) null,
|
||||
job_data blob null,
|
||||
primary key (sched_name, trigger_name, trigger_group),
|
||||
foreign key (sched_name, job_name, job_group)
|
||||
references qrtz_job_details(sched_name, job_name, job_group))
|
||||
engine=innodb;
|
||||
|
||||
create table qrtz_simple_triggers (
|
||||
sched_name varchar(120) not null,
|
||||
trigger_name varchar(200) not null,
|
||||
trigger_group varchar(200) not null,
|
||||
repeat_count bigint(7) not null,
|
||||
repeat_interval bigint(12) not null,
|
||||
times_triggered bigint(10) not null,
|
||||
primary key (sched_name, trigger_name, trigger_group),
|
||||
foreign key (sched_name, trigger_name, trigger_group)
|
||||
references qrtz_triggers(sched_name, trigger_name, trigger_group))
|
||||
engine=innodb;
|
||||
|
||||
create table qrtz_cron_triggers (
|
||||
sched_name varchar(120) not null,
|
||||
trigger_name varchar(200) not null,
|
||||
trigger_group varchar(200) not null,
|
||||
cron_expression varchar(120) not null,
|
||||
time_zone_id varchar(80),
|
||||
primary key (sched_name, trigger_name, trigger_group),
|
||||
foreign key (sched_name, trigger_name, trigger_group)
|
||||
references qrtz_triggers(sched_name, trigger_name, trigger_group))
|
||||
engine=innodb;
|
||||
|
||||
create table qrtz_simprop_triggers (
|
||||
sched_name varchar(120) not null,
|
||||
trigger_name varchar(200) not null,
|
||||
trigger_group varchar(200) not null,
|
||||
str_prop_1 varchar(512) null,
|
||||
str_prop_2 varchar(512) null,
|
||||
str_prop_3 varchar(512) null,
|
||||
int_prop_1 int null,
|
||||
int_prop_2 int null,
|
||||
long_prop_1 bigint null,
|
||||
long_prop_2 bigint null,
|
||||
dec_prop_1 numeric(13, 4) null,
|
||||
dec_prop_2 numeric(13, 4) null,
|
||||
bool_prop_1 varchar(1) null,
|
||||
bool_prop_2 varchar(1) null,
|
||||
primary key (sched_name, trigger_name, trigger_group),
|
||||
foreign key (sched_name, trigger_name, trigger_group)
|
||||
references qrtz_triggers(sched_name, trigger_name, trigger_group))
|
||||
engine=innodb;
|
||||
|
||||
create table qrtz_blob_triggers (
|
||||
sched_name varchar(120) not null,
|
||||
trigger_name varchar(200) not null,
|
||||
trigger_group varchar(200) not null,
|
||||
blob_data blob null,
|
||||
primary key (sched_name, trigger_name, trigger_group),
|
||||
index (sched_name, trigger_name, trigger_group),
|
||||
foreign key (sched_name, trigger_name, trigger_group)
|
||||
references qrtz_triggers(sched_name, trigger_name, trigger_group))
|
||||
engine=innodb;
|
||||
|
||||
create table qrtz_calendars (
|
||||
sched_name varchar(120) not null,
|
||||
calendar_name varchar(200) not null,
|
||||
calendar blob not null,
|
||||
primary key (sched_name, calendar_name))
|
||||
engine=innodb;
|
||||
|
||||
create table qrtz_paused_trigger_grps (
|
||||
sched_name varchar(120) not null,
|
||||
trigger_group varchar(200) not null,
|
||||
primary key (sched_name, trigger_group))
|
||||
engine=innodb;
|
||||
|
||||
create table qrtz_fired_triggers (
|
||||
sched_name varchar(120) not null,
|
||||
entry_id varchar(95) not null,
|
||||
trigger_name varchar(200) not null,
|
||||
trigger_group varchar(200) not null,
|
||||
instance_name varchar(200) not null,
|
||||
fired_time bigint(13) not null,
|
||||
sched_time bigint(13) not null,
|
||||
priority integer not null,
|
||||
state varchar(16) not null,
|
||||
job_name varchar(200) null,
|
||||
job_group varchar(200) null,
|
||||
is_nonconcurrent varchar(1) null,
|
||||
requests_recovery varchar(1) null,
|
||||
primary key (sched_name, entry_id))
|
||||
engine=innodb;
|
||||
|
||||
create table qrtz_scheduler_state (
|
||||
sched_name varchar(120) not null,
|
||||
instance_name varchar(200) not null,
|
||||
last_checkin_time bigint(13) not null,
|
||||
checkin_interval bigint(13) not null,
|
||||
primary key (sched_name, instance_name))
|
||||
engine=innodb;
|
||||
|
||||
create table qrtz_locks (
|
||||
sched_name varchar(120) not null,
|
||||
lock_name varchar(40) not null,
|
||||
primary key (sched_name, lock_name))
|
||||
engine=innodb;
|
||||
|
||||
create index idx_qrtz_j_req_recovery on qrtz_job_details(sched_name, requests_recovery);
|
||||
create index idx_qrtz_j_grp on qrtz_job_details(sched_name, job_group);
|
||||
|
||||
create index idx_qrtz_t_j on qrtz_triggers(sched_name, job_name, job_group);
|
||||
create index idx_qrtz_t_jg on qrtz_triggers(sched_name, job_group);
|
||||
create index idx_qrtz_t_c on qrtz_triggers(sched_name, calendar_name);
|
||||
create index idx_qrtz_t_g on qrtz_triggers(sched_name, trigger_group);
|
||||
create index idx_qrtz_t_state on qrtz_triggers(sched_name, trigger_state);
|
||||
create index idx_qrtz_t_n_state on qrtz_triggers(sched_name, trigger_name, trigger_group, trigger_state);
|
||||
create index idx_qrtz_t_n_g_state on qrtz_triggers(sched_name, trigger_group, trigger_state);
|
||||
create index idx_qrtz_t_next_fire_time on qrtz_triggers(sched_name, next_fire_time);
|
||||
create index idx_qrtz_t_nft_st on qrtz_triggers(sched_name, trigger_state, next_fire_time);
|
||||
create index idx_qrtz_t_nft_misfire on qrtz_triggers(sched_name, misfire_instr, next_fire_time);
|
||||
create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(sched_name, misfire_instr, next_fire_time, trigger_state);
|
||||
create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(sched_name, misfire_instr, next_fire_time, trigger_group, trigger_state);
|
||||
|
||||
create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(sched_name, instance_name);
|
||||
create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(sched_name, instance_name, requests_recovery);
|
||||
create index idx_qrtz_ft_j_g on qrtz_fired_triggers(sched_name, job_name, job_group);
|
||||
create index idx_qrtz_ft_jg on qrtz_fired_triggers(sched_name, job_group);
|
||||
create index idx_qrtz_ft_t_g on qrtz_fired_triggers(sched_name, trigger_name, trigger_group);
|
||||
create index idx_qrtz_ft_tg on qrtz_fired_triggers(sched_name, trigger_group);
|
||||
|
||||
commit;
|
Loading…
Reference in New Issue