feat:任务模板方法
This commit is contained in:
17
src/main/java/com/xiang/common/enums/ScheduleEnums.java
Normal file
17
src/main/java/com/xiang/common/enums/ScheduleEnums.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.xiang.common.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ScheduleEnums {
|
||||
|
||||
DOMAIN_DYNAMIC_ANALYSIS_TASK(4, "domain", "domainDynamicAnalysisTask"),
|
||||
|
||||
;
|
||||
|
||||
private final Integer modeleCode;
|
||||
private final String module;
|
||||
private final String taskName;
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package com.xiang.common.factory.schedule;
|
||||
|
||||
import com.xiang.common.pojo.schedule.ScheduleOpeningConfigDO;
|
||||
import com.xiang.common.pojo.schedule.TaskResult;
|
||||
import com.xiang.common.pojo.schedule.ValidationResult;
|
||||
import com.xiang.common.service.IScheduleOpeningConfigService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class BaseScheduleTaskTemplate {
|
||||
|
||||
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
private final IScheduleOpeningConfigService scheduleOpeningConfigService;
|
||||
|
||||
protected BaseScheduleTaskTemplate(IScheduleOpeningConfigService scheduleOpeningConfigService) {
|
||||
this.scheduleOpeningConfigService = scheduleOpeningConfigService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 模板方法 - 定义任务执行的标准流程
|
||||
* 子类不应覆写此方法
|
||||
*/
|
||||
public final void run() {
|
||||
String taskName = getTaskName();
|
||||
Integer module = getModule();
|
||||
LocalDateTime startTime = LocalDateTime.now();
|
||||
logger.info("【{}】任务开始执行,开始时间:{}", taskName, startTime.format(formatter));
|
||||
|
||||
try {
|
||||
// 1. 参数校验
|
||||
logger.info("【{}】开始参数校验...", taskName);
|
||||
ValidationResult validate = validate(module, taskName);
|
||||
|
||||
if (!validate.isValid()) {
|
||||
logger.error("【{}】参数校验失败:{}", taskName, validate.getMessage());
|
||||
onValidationFailure(validate);
|
||||
return;
|
||||
}
|
||||
logger.info("【{}】参数校验通过", taskName);
|
||||
|
||||
// 2. 执行业务逻辑
|
||||
logger.info("【{}】开始执行业务逻辑...", taskName);
|
||||
TaskResult result = doExecute(validate.getValidatedParams());
|
||||
|
||||
// 3. 记录成功结果
|
||||
recordSuccess(result, startTime);
|
||||
} catch (Exception e) {
|
||||
// 4. 记录失败结果
|
||||
logger.error("【{}】任务执行异常", taskName, e);
|
||||
recordFailure(e, startTime);
|
||||
}
|
||||
|
||||
LocalDateTime endTime = LocalDateTime.now();
|
||||
logger.info("【{}】任务结束,结束时间:{}", taskName, endTime.format(formatter));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任务名称(子类必须实现)
|
||||
*/
|
||||
protected abstract String getTaskName();
|
||||
|
||||
/**
|
||||
* 获取模块名称(子类必须实现)
|
||||
* @return
|
||||
*/
|
||||
protected abstract Integer getModule();
|
||||
|
||||
/**
|
||||
* 任务校验(子类必须实现)
|
||||
* @return 校验结果,包含是否通过、错误信息、校验通过的参数对象
|
||||
*/
|
||||
private ValidationResult validate(Integer moduleCode, String taskName) {
|
||||
ValidationResult validationResult = new ValidationResult();
|
||||
boolean flag = checkTaskOpening(moduleCode, taskName);
|
||||
validationResult.setValidatedParams(null);
|
||||
validationResult.setValid(flag);
|
||||
validationResult.setMessage(flag ? "" : "任务未开启");
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验任务是否开启
|
||||
* @param moduleCode 模块id
|
||||
* @param taskName 任务名称
|
||||
* @return
|
||||
*/
|
||||
private boolean checkTaskOpening(Integer moduleCode, String taskName) {
|
||||
ScheduleOpeningConfigDO configsByModule = scheduleOpeningConfigService.getConfigByModule(moduleCode, taskName);
|
||||
if (Objects.isNull(configsByModule)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(configsByModule.getStatus(), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 具体的业务逻辑执行(子类必须实现)
|
||||
* @param validatedParams 校验通过的参数
|
||||
* @return 任务执行结果
|
||||
*/
|
||||
protected abstract TaskResult doExecute(Object validatedParams);
|
||||
|
||||
/**
|
||||
* 记录成功结果 - 子类可选择性覆写
|
||||
*/
|
||||
protected void recordSuccess(TaskResult result, LocalDateTime startTime) {
|
||||
LocalDateTime endTime = LocalDateTime.now();
|
||||
long duration = java.time.Duration.between(startTime, endTime).toMillis();
|
||||
|
||||
logger.info("【{}】任务执行成功,耗时:{}ms,结果概要:{}",
|
||||
getTaskName(), duration, result.getSummary());
|
||||
|
||||
// 可在此扩展:写入数据库、发送通知等
|
||||
// 例如:saveTaskLog(getTaskName(), "SUCCESS", duration, result.getDetail());
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录失败结果 - 子类可选择性覆写
|
||||
*/
|
||||
protected void recordFailure(Exception e, LocalDateTime startTime) {
|
||||
LocalDateTime endTime = LocalDateTime.now();
|
||||
long duration = java.time.Duration.between(startTime, endTime).toMillis();
|
||||
|
||||
logger.error("【{}】任务执行失败,耗时:{}ms,错误:{}",
|
||||
getTaskName(), duration, e.getMessage());
|
||||
|
||||
// 可在此扩展:写入数据库、发送告警等
|
||||
// 例如:saveTaskLog(getTaskName(), "FAILURE", duration, e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数校验失败时的处理 - 子类可选择性覆写
|
||||
*/
|
||||
protected void onValidationFailure(ValidationResult result) {
|
||||
// 默认实现:仅记录日志
|
||||
logger.warn("【{}】参数校验失败,跳过任务执行", getTaskName());
|
||||
// 可在此扩展:发送通知、写入失败日志等
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.xiang.common.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.xiang.common.pojo.schedule.ScheduleOpeningConfigDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Mapper
|
||||
@Repository
|
||||
public interface ScheduleOpeningConfigDao extends BaseMapper<ScheduleOpeningConfigDO> {
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.xiang.common.pojo.schedule;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName("schedule_opening_config")
|
||||
public class ScheduleOpeningConfigDO {
|
||||
private Long id;
|
||||
/**
|
||||
* 模块id(0:glados 1:芬玩岛 2:江体小程序 3:江体zlb 4:ddns)
|
||||
*/
|
||||
private Integer module;
|
||||
private String beanName;
|
||||
private Integer status;
|
||||
private LocalDateTime createTime;
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
17
src/main/java/com/xiang/common/pojo/schedule/TaskResult.java
Normal file
17
src/main/java/com/xiang/common/pojo/schedule/TaskResult.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.xiang.common.pojo.schedule;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class TaskResult {
|
||||
/**
|
||||
* 是否成功
|
||||
*/
|
||||
private boolean success;
|
||||
private String summary;
|
||||
private Object detail;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.xiang.common.pojo.schedule;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.checkerframework.checker.units.qual.A;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ValidationResult {
|
||||
private boolean valid;
|
||||
private String message;
|
||||
private Object validatedParams;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.xiang.common.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.xiang.common.pojo.schedule.ScheduleOpeningConfigDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IScheduleOpeningConfigService extends IService<ScheduleOpeningConfigDO> {
|
||||
|
||||
/**
|
||||
* 根据模块id和任务名称查询
|
||||
* @param moduleCode
|
||||
* @param taskName
|
||||
* @return
|
||||
*/
|
||||
ScheduleOpeningConfigDO getConfigByModule(Integer moduleCode, String taskName);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.xiang.common.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.xiang.common.mapper.ScheduleOpeningConfigDao;
|
||||
import com.xiang.common.pojo.schedule.ScheduleOpeningConfigDO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
@Service
|
||||
public class ScheduleOpeningConfigServiceImpl extends ServiceImpl<ScheduleOpeningConfigDao, ScheduleOpeningConfigDO> implements IScheduleOpeningConfigService {
|
||||
@Override
|
||||
public ScheduleOpeningConfigDO getConfigByModule(Integer moduleCode, String taskName) {
|
||||
LambdaQueryWrapper<ScheduleOpeningConfigDO> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(ScheduleOpeningConfigDO::getModule, moduleCode);
|
||||
lqw.eq(ScheduleOpeningConfigDO::getBeanName, taskName);
|
||||
return baseMapper.selectOne(lqw);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,39 @@
|
||||
package com.xiang.service.module.domain.schedule;
|
||||
|
||||
import com.xiang.common.enums.ScheduleEnums;
|
||||
import com.xiang.common.factory.schedule.BaseScheduleTaskTemplate;
|
||||
import com.xiang.common.pojo.schedule.TaskResult;
|
||||
import com.xiang.common.service.IScheduleOpeningConfigService;
|
||||
import com.xiang.common.utils.IpUtils;
|
||||
import com.xiang.service.module.domain.service.IDomainService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class DomainDynamicAnalysisTask {
|
||||
@Component
|
||||
public class DomainDynamicAnalysisTask extends BaseScheduleTaskTemplate {
|
||||
private final IDomainService IDomainService;
|
||||
|
||||
@Scheduled(cron = "0 0/30 * * * ? ")
|
||||
public void dynamicDomainSchedule() {
|
||||
public DomainDynamicAnalysisTask(IScheduleOpeningConfigService scheduleOpeningConfigService, IDomainService IDomainService) {
|
||||
super(scheduleOpeningConfigService);
|
||||
this.IDomainService = IDomainService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer getModule() {
|
||||
return ScheduleEnums.DOMAIN_DYNAMIC_ANALYSIS_TASK.getModeleCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTaskName() {
|
||||
return ScheduleEnums.DOMAIN_DYNAMIC_ANALYSIS_TASK.getTaskName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TaskResult doExecute(Object validatedParams) {
|
||||
String publicIp = "";
|
||||
TaskResult taskResult = new TaskResult();
|
||||
try {
|
||||
publicIp = IpUtils.getPublicIp();
|
||||
} catch (Exception e) {
|
||||
@@ -27,5 +46,10 @@ public class DomainDynamicAnalysisTask {
|
||||
log.error("动态解析公网ip失败, ip:{}", publicIp, e);
|
||||
}
|
||||
}
|
||||
taskResult.setSuccess(true);
|
||||
taskResult.setSummary("");
|
||||
taskResult.setDetail(null);
|
||||
return taskResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.xiang.service.module.domain.schedule;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
public class DomainDynamicAnalysisTaskConfig {
|
||||
|
||||
private final DomainDynamicAnalysisTask domainDynamicAnalysisTask;
|
||||
|
||||
@Scheduled(cron = "0 0/30 * * * ? ")
|
||||
@GetMapping("/test")
|
||||
public void dynamicDomainSchedule() {
|
||||
domainDynamicAnalysisTask.run();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user