Commit 89a06fa6 by yuwei

2.0.0项目初始化

parent 49ee9e02
......@@ -2,49 +2,49 @@
spring:
redis:
database: 1
host: 192.168.234.101
host: 127.0.0.1
port: 6379
password: 1234@abcd # 密码(默认为空)
timeout: 6000ms # 连接超时时长(毫秒)
password: # 密码(默认为空)
timeout: 6000ms # 连接超时时长(毫秒)
lettuce:
pool:
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 5 # 连接池中的最小空闲连接
datasource:
dynamic:
type: com.zaxxer.hikari.HikariDataSource
hikari:
auto-commit: false
connection-timeout: 30000
idle-timeout: 25000
login-timeout: 5
max-lifetime: 30000
read-only: false
validation-timeout: 3000
maximum-pool-size: 15
minimum-idle: 5
pool-name: DataxHikariCP
connection-test-query: SELECT 1 FROM DUAL
data-source-properties:
cachePrepStmts: true
prepStmtCacheSize: 250
prepStmtCacheSqlLimit: 2048
useServerPrepStmts: true
useLocalSessionState: true
rewriteBatchedStatements: true
cacheResultSetMetadata: true
cacheServerConfiguration: true
elideSetAutoCommits: true
maintainTimeStats: false
primary: mysql
datasource:
mysql:
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://192.168.234.100:3306/data_cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 1234@abcd
datasource:
dynamic:
type: com.zaxxer.hikari.HikariDataSource
hikari:
auto-commit: false
connection-timeout: 30000
idle-timeout: 25000
login-timeout: 5
max-lifetime: 30000
read-only: false
validation-timeout: 3000
maximum-pool-size: 15
minimum-idle: 5
pool-name: DataxHikariCP
connection-test-query: SELECT 1 FROM DUAL
data-source-properties:
cachePrepStmts: true
prepStmtCacheSize: 250
prepStmtCacheSqlLimit: 2048
useServerPrepStmts: true
useLocalSessionState: true
rewriteBatchedStatements: true
cacheResultSetMetadata: true
cacheServerConfiguration: true
elideSetAutoCommits: true
maintainTimeStats: false
primary: mysql
datasource:
mysql:
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://127.0.0.1:3306/data_cloud?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 1234@abcd
quartz:
job-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。
auto-startup: true # Quartz 是否自动启动
......@@ -57,18 +57,20 @@ spring:
org:
quartz:
datasource:
# 新版驱动从com.mysql.jdbc.Driver变更为com.mysql.cj.jdbc.Driver
driver-class-name: com.mysql.cj.jdbc.Driver
# 数据源需要添加时间标准和指定编码格式解决乱码 You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
url: jdbc:mysql://192.168.234.100:3306/data_cloud_quartz?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 1234@abcd
quartzDataSource:
# 新版驱动从com.mysql.jdbc.Driver变更为com.mysql.cj.jdbc.Driver
driver-class-name: com.mysql.cj.jdbc.Driver
# 数据源需要添加时间标准和指定编码格式解决乱码 You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
url: jdbc:mysql://127.0.0.1:3306/data_cloud_quartz?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 1234@abcd
scheduler:
instancName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #StdJDBCDelegate说明支持集群
dataSource: quartzDataSource
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 1000
......@@ -103,4 +105,11 @@ security:
scope: all
resource:
loadBalanced: true
token-info-uri: http://localhost:8612/auth/oauth/check_token
\ No newline at end of file
token-info-uri: http://localhost:8612/auth/oauth/check_token
datasource:
scheduler:
url: jdbc:mysql://127.0.0.1:3306/data_cloud_quartz?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 1234@abcd
driver-class-name: com.mysql.cj.jdbc.Driver
\ No newline at end of file
......@@ -3,7 +3,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quartz-service-parent</artifactId>
<artifactId>system-service-parent</artifactId>
<groupId>cn.datax</groupId>
<version>2.0.0</version>
</parent>
......
package cn.datax.service.quartz.api.dto;
import cn.datax.common.validate.ValidationGroups;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* <p>
* 定时任务信息表 实体DTO
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@ApiModel(value = "定时任务信息表Model")
@Data
public class QrtzJobDto implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "主键ID")
@NotBlank(message = "主键ID不能为空", groups = {ValidationGroups.Update.class})
private String id;
@ApiModelProperty(value = "任务名称")
@NotBlank(message = "任务名称不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private String jobName;
@ApiModelProperty(value = "Spring Bean名称")
@NotBlank(message = "Spring Bean名称不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private String beanName;
@ApiModelProperty(value = "方法名称")
@NotBlank(message = "方法名称不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private String methodName;
@ApiModelProperty(value = "方法参数")
private String methodParams;
@ApiModelProperty(value = "cron表达式")
@NotBlank(message = "cron表达式不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private String cronExpression;
}
package cn.datax.service.quartz.api.dto;
import cn.datax.common.validate.ValidationGroups;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* <p>
* 定时任务日志信息表 实体DTO
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@ApiModel(value = "定时任务日志信息表Model")
@Data
public class QrtzJobLogDto implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "主键ID")
@NotBlank(message = "主键ID不能为空", groups = {ValidationGroups.Update.class})
private String id;
@ApiModelProperty(value = "任务ID")
@NotBlank(message = "任务ID不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private String jobId;
@ApiModelProperty(value = "信息记录")
@NotBlank(message = "信息记录不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private String msg;
}
package cn.datax.service.quartz.api.entity;
import cn.datax.common.base.DataScopeBaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 定时任务信息表
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("qrtz_job")
public class QrtzJobEntity extends DataScopeBaseEntity {
private static final long serialVersionUID=1L;
/**
* 任务名称
*/
private String jobName;
/**
* Spring Bean名称
*/
private String beanName;
/**
* 方法名称
*/
private String methodName;
/**
* 方法参数
*/
private String methodParams;
/**
* cron表达式
*/
private String cronExpression;
}
package cn.datax.service.quartz.api.entity;
import cn.datax.common.base.DataScopeBaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 定时任务日志信息表
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("qrtz_job_log")
public class QrtzJobLogEntity extends DataScopeBaseEntity {
private static final long serialVersionUID=1L;
/**
* 任务ID
*/
private String jobId;
/**
* 信息记录
*/
private String msg;
}
package cn.datax.service.quartz.api.query;
import cn.datax.common.base.BaseQueryParams;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 定时任务日志信息表 查询实体
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class QrtzJobLogQuery extends BaseQueryParams {
private static final long serialVersionUID=1L;
}
package cn.datax.service.quartz.api.query;
import cn.datax.common.base.BaseQueryParams;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 定时任务信息表 查询实体
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class QrtzJobQuery extends BaseQueryParams {
private static final long serialVersionUID=1L;
private String jobName;
}
package cn.datax.service.quartz.api.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 定时任务日志信息表 实体VO
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@Data
public class QrtzJobLogVo implements Serializable {
private static final long serialVersionUID=1L;
private String id;
private Integer status;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
private String jobId;
private String msg;
}
package cn.datax.service.quartz.api.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 定时任务信息表 实体VO
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@Data
public class QrtzJobVo implements Serializable {
private static final long serialVersionUID=1L;
private String id;
private Integer status;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
private String jobName;
private String beanName;
private String methodName;
private String methodParams;
private String cronExpression;
}
package cn.datax.service.quartz.config;
import cn.datax.service.quartz.quartz.utils.ScheduleUtil;
import com.zaxxer.hikari.HikariDataSource;
import org.quartz.Scheduler;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.quartz.QuartzDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
@Configuration
public class QuartzConfig {
@Bean
@Bean(name = "quartzDataSourceProperties")
@ConfigurationProperties(prefix = "datasource.scheduler")
public DataSourceProperties quartzDataSourceProperties() {
return new DataSourceProperties();
}
@Bean(name = "quartzDataSource")
@QuartzDataSource
@ConfigurationProperties(prefix = "spring.quartz.properties.org.quartz.datasource")
DataSource quartzDataSource(){
// 创建 HikariDataSource 对象
HikariDataSource dataSource = new DataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
// 设置线程池名
dataSource.setPoolName("QuartzHikariCP");
return dataSource;
@ConfigurationProperties(prefix = "datasource.scheduler")
public DataSource quartzDataSource(){
DataSource datasource = quartzDataSourceProperties().initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
return datasource;
}
/**
* 该类主要是为了把 job 对象的注入到 spring 中
*/
@Component("quartzJobFactory")
public static class QuartzJobFactory extends AdaptableJobFactory {
//这个对象可以通过 ApplicationContext.getAutowireCapableBeanFactory()获取
private final AutowireCapableBeanFactory capableBeanFactory;
public QuartzJobFactory(AutowireCapableBeanFactory capableBeanFactory) {
this.capableBeanFactory = capableBeanFactory;
}
/**
* Job 对象的实例化过程是在Quartz中进行的,通过重写此方法 把job 实例注入到spring容器中
*/
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
//调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
//注入到spring容器
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
/**
* 注入scheduler到spring
* @param quartzJobFactory
* @return Scheduler
* @throws Exception
*/
@Bean(name = "scheduler")
public Scheduler scheduler(QuartzJobFactory quartzJobFactory) throws Exception {
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
factoryBean.setJobFactory(quartzJobFactory);
factoryBean.afterPropertiesSet();
Scheduler scheduler = factoryBean.getScheduler();
scheduler.start();
// 设置ScheduleUtil的定时处理对象
ScheduleUtil.setScheduler(scheduler);
return scheduler;
}
}
package cn.datax.service.quartz.config;
import cn.datax.common.redis.serializer.DataRedisSerializer;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
/**
* 在没有指定缓存Key的情况下,key生成策略
* @return
*/
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append("#" + method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
return new RedisCacheManager(
RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
this.redisCacheConfigurationWithTtl(30),
this.redisCacheConfigurationMap()
);
}
private Map<String, RedisCacheConfiguration> redisCacheConfigurationMap() {
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
redisCacheConfigurationMap.put("data:quartz:jobs", redisCacheConfigurationWithTtl(30));
return redisCacheConfigurationMap;
}
private RedisCacheConfiguration redisCacheConfigurationWithTtl(Integer minutes) {
DataRedisSerializer serializer = new DataRedisSerializer();
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer))
.entryTtl(Duration.ofMinutes(minutes));
return redisCacheConfiguration;
}
}
\ No newline at end of file
package cn.datax.service.quartz.controller;
import cn.datax.common.core.JsonPage;
import cn.datax.common.core.R;
import cn.datax.common.validate.ValidationGroups;
import cn.datax.service.quartz.api.dto.QrtzJobDto;
import cn.datax.service.quartz.api.entity.QrtzJobEntity;
import cn.datax.service.quartz.api.vo.QrtzJobVo;
import cn.datax.service.quartz.api.query.QrtzJobQuery;
import cn.datax.service.quartz.mapstruct.QrtzJobMapper;
import cn.datax.service.quartz.service.QrtzJobService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import cn.datax.common.base.BaseController;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 定时任务信息表 前端控制器
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@Api(tags = {"定时任务信息表"})
@RestController
@RequestMapping("/jobs")
public class QrtzJobController extends BaseController {
@Autowired
private QrtzJobService qrtzJobService;
@Autowired
private QrtzJobMapper qrtzJobMapper;
/**
* 通过ID查询信息
*
* @param id
* @return
*/
@ApiOperation(value = "获取详细信息", notes = "根据url的id来获取详细信息")
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
@GetMapping("/{id}")
public R getQrtzJobById(@PathVariable String id) {
QrtzJobVo qrtzJobVo = qrtzJobService.getQrtzJobById(id);
return R.ok().setData(qrtzJobVo);
}
/**
* 分页查询信息
*
* @param qrtzJobQuery
* @return
*/
@ApiOperation(value = "分页查询", notes = "")
@ApiImplicitParams({
@ApiImplicitParam(name = "qrtzJobQuery", value = "查询实体qrtzJobQuery", required = true, dataTypeClass = QrtzJobQuery.class)
})
@GetMapping("/page")
public R getQrtzJobPage(QrtzJobQuery qrtzJobQuery) {
QueryWrapper<QrtzJobEntity> queryWrapper = new QueryWrapper<>();
IPage<QrtzJobEntity> page = qrtzJobService.page(new Page<>(qrtzJobQuery.getPageNum(), qrtzJobQuery.getPageSize()), queryWrapper);
List<QrtzJobVo> collect = page.getRecords().stream().map(qrtzJobMapper::toVO).collect(Collectors.toList());
JsonPage<QrtzJobVo> jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect);
return R.ok().setData(jsonPage);
}
/**
* 添加
* @param qrtzJob
* @return
*/
@ApiOperation(value = "添加信息", notes = "根据qrtzJob对象添加信息")
@ApiImplicitParam(name = "qrtzJob", value = "详细实体qrtzJob", required = true, dataType = "QrtzJobDto")
@PostMapping()
public R saveQrtzJob(@RequestBody @Validated({ValidationGroups.Insert.class}) QrtzJobDto qrtzJob) {
qrtzJobService.saveQrtzJob(qrtzJob);
return R.ok();
}
/**
* 修改
* @param qrtzJob
* @return
*/
@ApiOperation(value = "修改信息", notes = "根据url的id来指定修改对象,并根据传过来的信息来修改详细信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"),
@ApiImplicitParam(name = "qrtzJob", value = "详细实体qrtzJob", required = true, dataType = "QrtzJobDto")
})
@PutMapping("/{id}")
public R updateQrtzJob(@PathVariable String id, @RequestBody @Validated({ValidationGroups.Update.class}) QrtzJobDto qrtzJob) {
qrtzJobService.updateQrtzJob(qrtzJob);
return R.ok();
}
/**
* 删除
* @param id
* @return
*/
@ApiOperation(value = "删除", notes = "根据url的id来指定删除对象")
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
@DeleteMapping("/{id}")
public R deleteQrtzJobById(@PathVariable String id) {
qrtzJobService.deleteQrtzJobById(id);
return R.ok();
}
}
package cn.datax.service.quartz.controller;
import cn.datax.common.core.JsonPage;
import cn.datax.common.core.R;
import cn.datax.common.validate.ValidationGroups;
import cn.datax.service.quartz.api.dto.QrtzJobLogDto;
import cn.datax.service.quartz.api.entity.QrtzJobLogEntity;
import cn.datax.service.quartz.api.vo.QrtzJobLogVo;
import cn.datax.service.quartz.api.query.QrtzJobLogQuery;
import cn.datax.service.quartz.mapstruct.QrtzJobLogMapper;
import cn.datax.service.quartz.service.QrtzJobLogService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import cn.datax.common.base.BaseController;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 定时任务日志信息表 前端控制器
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@Api(tags = {"定时任务日志信息表"})
@RestController
@RequestMapping("/logs")
public class QrtzJobLogController extends BaseController {
@Autowired
private QrtzJobLogService qrtzJobLogService;
@Autowired
private QrtzJobLogMapper qrtzJobLogMapper;
/**
* 通过ID查询信息
*
* @param id
* @return
*/
@ApiOperation(value = "获取详细信息", notes = "根据url的id来获取详细信息")
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
@GetMapping("/{id}")
public R getQrtzJobLogById(@PathVariable String id) {
QrtzJobLogVo qrtzJobLogVo = qrtzJobLogService.getQrtzJobLogById(id);
return R.ok().setData(qrtzJobLogVo);
}
/**
* 分页查询信息
*
* @param qrtzJobLogQuery
* @return
*/
@ApiOperation(value = "分页查询", notes = "")
@ApiImplicitParams({
@ApiImplicitParam(name = "qrtzJobLogQuery", value = "查询实体qrtzJobLogQuery", required = true, dataTypeClass = QrtzJobLogQuery.class)
})
@GetMapping("/page")
public R getQrtzJobLogPage(QrtzJobLogQuery qrtzJobLogQuery) {
QueryWrapper<QrtzJobLogEntity> queryWrapper = new QueryWrapper<>();
IPage<QrtzJobLogEntity> page = qrtzJobLogService.page(new Page<>(qrtzJobLogQuery.getPageNum(), qrtzJobLogQuery.getPageSize()), queryWrapper);
List<QrtzJobLogVo> collect = page.getRecords().stream().map(qrtzJobLogMapper::toVO).collect(Collectors.toList());
JsonPage<QrtzJobLogVo> jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect);
return R.ok().setData(jsonPage);
}
/**
* 添加
* @param qrtzJobLog
* @return
*/
@ApiOperation(value = "添加信息", notes = "根据qrtzJobLog对象添加信息")
@ApiImplicitParam(name = "qrtzJobLog", value = "详细实体qrtzJobLog", required = true, dataType = "QrtzJobLogDto")
@PostMapping()
public R saveQrtzJobLog(@RequestBody @Validated({ValidationGroups.Insert.class}) QrtzJobLogDto qrtzJobLog) {
qrtzJobLogService.saveQrtzJobLog(qrtzJobLog);
return R.ok();
}
/**
* 修改
* @param qrtzJobLog
* @return
*/
@ApiOperation(value = "修改信息", notes = "根据url的id来指定修改对象,并根据传过来的信息来修改详细信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"),
@ApiImplicitParam(name = "qrtzJobLog", value = "详细实体qrtzJobLog", required = true, dataType = "QrtzJobLogDto")
})
@PutMapping("/{id}")
public R updateQrtzJobLog(@PathVariable String id, @RequestBody @Validated({ValidationGroups.Update.class}) QrtzJobLogDto qrtzJobLog) {
qrtzJobLogService.updateQrtzJobLog(qrtzJobLog);
return R.ok();
}
/**
* 删除
* @param id
* @return
*/
@ApiOperation(value = "删除", notes = "根据url的id来指定删除对象")
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
@DeleteMapping("/{id}")
public R deleteQrtzJobLogById(@PathVariable String id) {
qrtzJobLogService.deleteQrtzJobLogById(id);
return R.ok();
}
}
package cn.datax.service.quartz.dao;
import cn.datax.common.base.BaseDao;
import cn.datax.service.quartz.api.entity.QrtzJobEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 定时任务信息表 Mapper 接口
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@Mapper
public interface QrtzJobDao extends BaseDao<QrtzJobEntity> {
}
package cn.datax.service.quartz.dao;
import cn.datax.common.base.BaseDao;
import cn.datax.service.quartz.api.entity.QrtzJobLogEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 定时任务日志信息表 Mapper 接口
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@Mapper
public interface QrtzJobLogDao extends BaseDao<QrtzJobLogEntity> {
}
package cn.datax.service.quartz.mapstruct;
import cn.datax.common.mapstruct.EntityMapper;
import cn.datax.service.quartz.api.dto.QrtzJobLogDto;
import cn.datax.service.quartz.api.entity.QrtzJobLogEntity;
import cn.datax.service.quartz.api.vo.QrtzJobLogVo;
import org.mapstruct.Mapper;
/**
* <p>
* 定时任务日志信息表 Mapper 实体映射
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@Mapper(componentModel = "spring")
public interface QrtzJobLogMapper extends EntityMapper<QrtzJobLogDto, QrtzJobLogEntity, QrtzJobLogVo> {
}
package cn.datax.service.quartz.mapstruct;
import cn.datax.common.mapstruct.EntityMapper;
import cn.datax.service.quartz.api.dto.QrtzJobDto;
import cn.datax.service.quartz.api.entity.QrtzJobEntity;
import cn.datax.service.quartz.api.vo.QrtzJobVo;
import org.mapstruct.Mapper;
/**
* <p>
* 定时任务信息表 Mapper 实体映射
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@Mapper(componentModel = "spring")
public interface QrtzJobMapper extends EntityMapper<QrtzJobDto, QrtzJobEntity, QrtzJobVo> {
}
package cn.datax.service.quartz.quartz;
import java.time.LocalDateTime;
import java.util.concurrent.*;
import cn.datax.common.utils.ThrowableUtil;
import cn.datax.service.quartz.api.entity.QrtzJobEntity;
import cn.datax.service.quartz.api.entity.QrtzJobLogEntity;
import cn.datax.service.quartz.quartz.utils.ScheduleUtil;
import cn.datax.service.quartz.service.QrtzJobLogService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
@Slf4j
@DisallowConcurrentExecution
public class ScheduleJob extends QuartzJobBean {
@Autowired
private QrtzJobLogService qrtzJobLogService;
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 30, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(50));
@Override
protected void executeInternal(JobExecutionContext context) {
QrtzJobEntity job = (QrtzJobEntity) context.getMergedJobDataMap().get(ScheduleUtil.JOB_DATA_MAP);
log.info("运行任务{}", job);
// QrtzJobLogService qrtzJobLogService = SpringContextHolder.getBean(QrtzJobLogService.class);
QrtzJobLogEntity jobLog = new QrtzJobLogEntity();
jobLog.setJobId(job.getId());
jobLog.setCreateTime(LocalDateTime.now());
long startTime = System.currentTimeMillis();
try {
// 执行任务
ScheduleRunnable task = new ScheduleRunnable(job.getBeanName(), job.getMethodName(), job.getMethodParams());
executor.execute(task);
long times = System.currentTimeMillis() - startTime;
// 任务状态 0:失败 1:成功
jobLog.setStatus(1);
jobLog.setMsg("【" + job.getJobName() + "】任务执行结束,总共耗时:" + times + "毫秒");
} catch (Exception e) {
jobLog.setMsg("【" + job.getJobName() + "】任务执行失败");
// 任务状态 0:失败 1:成功
jobLog.setStatus(0);
log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e));
} finally {
qrtzJobLogService.save(jobLog);
}
}
}
\ No newline at end of file
package cn.datax.service.quartz.quartz;
import java.lang.reflect.Method;
import cn.datax.common.utils.SpringContextHolder;
import org.springframework.util.ReflectionUtils;
import cn.hutool.core.util.StrUtil;
public class ScheduleRunnable implements Runnable {
private Object target;
private Method method;
private String params;
public ScheduleRunnable(String beanName, String methodName, String params) throws NoSuchMethodException, SecurityException {
this.target = SpringContextHolder.getBean(beanName);
this.params = params;
if (StrUtil.isNotEmpty(params)) {
this.method = target.getClass().getDeclaredMethod(methodName, String.class);
} else {
this.method = target.getClass().getDeclaredMethod(methodName);
}
}
@Override
public void run() {
try {
ReflectionUtils.makeAccessible(method);
if (StrUtil.isNotEmpty(params)) {
method.invoke(target, params);
} else {
method.invoke(target);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
package cn.datax.service.quartz.quartz.tasks;
import org.springframework.stereotype.Component;
@Component("quartzTask")
public class QuartzTask {
public void withParams(String params) {
System.out.println("执行有参方法:" + params);
}
public void withoutParams() {
System.out.println("执行无参方法");
}
}
\ No newline at end of file
package cn.datax.service.quartz.quartz.utils;
import cn.datax.common.core.DataConstant;
import cn.datax.common.exception.DataException;
import cn.datax.service.quartz.api.entity.QrtzJobEntity;
import cn.datax.service.quartz.quartz.ScheduleJob;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
public class ScheduleUtil {
public static final String QUARTZ_TASK_KEY = "__QUARTZ_TASK_KEY__";
public static final String JOB_DATA_MAP = "__JOB_DATA_MAP__";
private static Scheduler scheduler;
public static void setScheduler(Scheduler scheduler) {
ScheduleUtil.scheduler = scheduler;
}
/**
* 获取jobKey
*/
public static JobKey getJobKey(String jobId) {
return JobKey.jobKey(QUARTZ_TASK_KEY + jobId);
}
/**
* 获取表达式触发器
*/
public static CronTrigger getCronTrigger(String jobId) {
try {
return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId));
} catch (SchedulerException e) {
throw new DataException("获取定时任务CronTrigger出现异常", e);
}
}
/**
* 获取触发器key
*/
public static TriggerKey getTriggerKey(String jobId) {
return TriggerKey.triggerKey(QUARTZ_TASK_KEY + jobId);
}
/**
* 创建定时任务
*/
public static void createScheduleJob(QrtzJobEntity job) {
try {
// 构建job信息
JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(job.getId())).build();
// 表达式调度构建器
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
// 按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(job.getId())).withSchedule(cronScheduleBuilder).build();
// 放入参数,运行时的方法可以获取
jobDetail.getJobDataMap().put(JOB_DATA_MAP, job);
// 交给scheduler去调度
scheduler.scheduleJob(jobDetail, trigger);
// 暂停任务
if (job.getStatus() == DataConstant.EnableState.DISABLE.getKey()) {
pauseJob(job.getId());
}
} catch (SchedulerException e) {
throw new DataException("创建定时任务失败", e);
}
}
/**
* 更新定时任务
*/
public static void updateScheduleJob(QrtzJobEntity job) {
try {
TriggerKey triggerKey = getTriggerKey(job.getId());
// 表达式调度构建器
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
CronTrigger trigger = getCronTrigger(job.getId());
// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
// 参数
trigger.getJobDataMap().put(JOB_DATA_MAP, job);
scheduler.rescheduleJob(triggerKey, trigger);
// 暂停任务
if (job.getStatus() == DataConstant.EnableState.DISABLE.getKey()) {
pauseJob(job.getId());
}
} catch (SchedulerException e) {
throw new DataException("更新定时任务失败", e);
}
}
/**
* 暂停任务
*/
public static void pauseJob(String jobId) {
try {
scheduler.pauseJob(getJobKey(jobId));
} catch (SchedulerException e) {
throw new DataException("暂停定时任务失败", e);
}
}
/**
* 恢复任务
*/
public static void resumeJob(String jobId) {
try {
scheduler.resumeJob(getJobKey(jobId));
} catch (SchedulerException e) {
throw new DataException("恢复定时任务失败", e);
}
}
/**
* 立即执行任务
*/
public static void runJob(QrtzJobEntity job) {
try {
JobDataMap dataMap = new JobDataMap();
dataMap.put(JOB_DATA_MAP, job);
scheduler.triggerJob(getJobKey(job.getId()), dataMap);
} catch (SchedulerException e) {
throw new DataException("立即执行定时任务失败", e);
}
}
/**
* 移除任务
*/
public static void deleteJob(String id) {
try {
TriggerKey triggerKey = getTriggerKey(id);
// 停止触发器
scheduler.pauseTrigger(triggerKey);
// 移除触发器
scheduler.unscheduleJob(triggerKey);
// 暂停任务
scheduler.pauseJob(getJobKey(id));
// 删除任务
scheduler.deleteJob(getJobKey(id));
} catch (SchedulerException e) {
throw new DataException("删除定时任务失败", e);
}
}
}
\ No newline at end of file
package cn.datax.service.quartz.service;
import cn.datax.service.quartz.api.entity.QrtzJobLogEntity;
import cn.datax.service.quartz.api.dto.QrtzJobLogDto;
import cn.datax.common.base.BaseService;
import cn.datax.service.quartz.api.vo.QrtzJobLogVo;
/**
* <p>
* 定时任务日志信息表 服务类
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
public interface QrtzJobLogService extends BaseService<QrtzJobLogEntity> {
void saveQrtzJobLog(QrtzJobLogDto qrtzJobLog);
void updateQrtzJobLog(QrtzJobLogDto qrtzJobLog);
QrtzJobLogVo getQrtzJobLogById(String id);
void deleteQrtzJobLogById(String id);
}
package cn.datax.service.quartz.service;
import cn.datax.service.quartz.api.entity.QrtzJobEntity;
import cn.datax.service.quartz.api.dto.QrtzJobDto;
import cn.datax.common.base.BaseService;
import cn.datax.service.quartz.api.vo.QrtzJobVo;
/**
* <p>
* 定时任务信息表 服务类
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
public interface QrtzJobService extends BaseService<QrtzJobEntity> {
void saveQrtzJob(QrtzJobDto qrtzJob);
void updateQrtzJob(QrtzJobDto qrtzJob);
QrtzJobVo getQrtzJobById(String id);
void deleteQrtzJobById(String id);
void pauseById(String id);
void resumeById(String id);
void runById(String id);
}
package cn.datax.service.quartz.service.impl;
import cn.datax.service.quartz.api.entity.QrtzJobLogEntity;
import cn.datax.service.quartz.api.dto.QrtzJobLogDto;
import cn.datax.service.quartz.api.vo.QrtzJobLogVo;
import cn.datax.service.quartz.service.QrtzJobLogService;
import cn.datax.service.quartz.mapstruct.QrtzJobLogMapper;
import cn.datax.service.quartz.dao.QrtzJobLogDao;
import cn.datax.common.base.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>
* 定时任务日志信息表 服务实现类
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class QrtzJobLogServiceImpl extends BaseServiceImpl<QrtzJobLogDao, QrtzJobLogEntity> implements QrtzJobLogService {
@Autowired
private QrtzJobLogDao qrtzJobLogDao;
@Autowired
private QrtzJobLogMapper qrtzJobLogMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public void saveQrtzJobLog(QrtzJobLogDto qrtzJobLogDto) {
QrtzJobLogEntity qrtzJobLog = qrtzJobLogMapper.toEntity(qrtzJobLogDto);
qrtzJobLogDao.insert(qrtzJobLog);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateQrtzJobLog(QrtzJobLogDto qrtzJobLogDto) {
QrtzJobLogEntity qrtzJobLog = qrtzJobLogMapper.toEntity(qrtzJobLogDto);
qrtzJobLogDao.updateById(qrtzJobLog);
}
@Override
public QrtzJobLogVo getQrtzJobLogById(String id) {
QrtzJobLogEntity qrtzJobLogEntity = super.getById(id);
return qrtzJobLogMapper.toVO(qrtzJobLogEntity);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteQrtzJobLogById(String id) {
qrtzJobLogDao.deleteById(id);
}
}
package cn.datax.service.quartz.service.impl;
import cn.datax.common.core.DataConstant;
import cn.datax.service.quartz.api.entity.QrtzJobEntity;
import cn.datax.service.quartz.api.dto.QrtzJobDto;
import cn.datax.service.quartz.api.vo.QrtzJobVo;
import cn.datax.service.quartz.quartz.utils.ScheduleUtil;
import cn.datax.service.quartz.service.QrtzJobService;
import cn.datax.service.quartz.mapstruct.QrtzJobMapper;
import cn.datax.service.quartz.dao.QrtzJobDao;
import cn.datax.common.base.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>
* 定时任务信息表 服务实现类
* </p>
*
* @author yuwei
* @since 2020-05-14
*/
@CacheConfig(cacheNames = "data:quartz:jobs")
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class QrtzJobServiceImpl extends BaseServiceImpl<QrtzJobDao, QrtzJobEntity> implements QrtzJobService {
@Autowired
private QrtzJobDao qrtzJobDao;
@Autowired
private QrtzJobMapper qrtzJobMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public void saveQrtzJob(QrtzJobDto qrtzJobDto) {
QrtzJobEntity qrtzJob = qrtzJobMapper.toEntity(qrtzJobDto);
qrtzJobDao.insert(qrtzJob);
ScheduleUtil.createScheduleJob(qrtzJob);
}
@CachePut(key = "#p0.id")
@Override
@Transactional(rollbackFor = Exception.class)
public void updateQrtzJob(QrtzJobDto qrtzJobDto) {
QrtzJobEntity qrtzJob = qrtzJobMapper.toEntity(qrtzJobDto);
qrtzJobDao.updateById(qrtzJob);
ScheduleUtil.updateScheduleJob(qrtzJob);
}
@Cacheable(key = "#id")
@Override
public QrtzJobVo getQrtzJobById(String id) {
QrtzJobEntity qrtzJobEntity = super.getById(id);
return qrtzJobMapper.toVO(qrtzJobEntity);
}
@CacheEvict(key = "#id")
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteQrtzJobById(String id) {
ScheduleUtil.deleteJob(id);
qrtzJobDao.deleteById(id);
}
@Override
public void pauseById(String id) {
QrtzJobEntity job = super.getById(id);
job.setStatus(DataConstant.EnableState.DISABLE.getKey());
super.updateById(job);
ScheduleUtil.pauseJob(id);
}
@Override
public void resumeById(String id) {
QrtzJobEntity job = super.getById(id);
job.setStatus(DataConstant.EnableState.ENABLE.getKey());
super.updateById(job);
ScheduleUtil.resumeJob(id);
}
@Override
public void runById(String id) {
QrtzJobEntity job = super.getById(id);
ScheduleUtil.runJob(job);
}
}
<?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">
<mapper namespace="cn.datax.service.quartz.dao.QrtzJobLogDao">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.datax.service.quartz.api.entity.QrtzJobLogEntity">
<result column="id" property="id" />
<result column="status" property="status" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="create_dept" property="createDept" />
<result column="update_by" property="updateBy" />
<result column="update_time" property="updateTime" />
<result column="job_id" property="jobId" />
<result column="msg" property="msg" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
status,
create_by,
create_time,
create_dept,
update_by,
update_time,
job_id, msg
</sql>
</mapper>
<?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">
<mapper namespace="cn.datax.service.quartz.dao.QrtzJobDao">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.datax.service.quartz.api.entity.QrtzJobEntity">
<result column="id" property="id" />
<result column="status" property="status" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="create_dept" property="createDept" />
<result column="update_by" property="updateBy" />
<result column="update_time" property="updateTime" />
<result column="job_name" property="jobName" />
<result column="bean_name" property="beanName" />
<result column="method_name" property="methodName" />
<result column="method_params" property="methodParams" />
<result column="cron_expression" property="cronExpression" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
status,
create_by,
create_time,
create_dept,
update_by,
update_time,
job_name, bean_name, method_name, method_params, cron_expression
</sql>
</mapper>
package ${package.Service};
import ${cfg.PackageParent}#if(${package.ModuleName}).${package.ModuleName}#end.api.entity.${entity};
import ${cfg.PackageParent}#if(${package.ModuleName}).${package.ModuleName}#end.api.vo.${className}Vo;
import ${cfg.PackageParent}#if(${package.ModuleName}).${package.ModuleName}#end.api.dto.${className}Dto;
import ${superServiceClassPackage};
......
package ${package.ServiceImpl};
import ${cfg.PackageParent}#if(${package.ModuleName}).${package.ModuleName}#end.api.entity.${entity};
import ${cfg.PackageParent}#if(${package.ModuleName}).${package.ModuleName}#end.api.vo.${className}Vo;
import ${cfg.PackageParent}#if(${package.ModuleName}).${package.ModuleName}#end.api.dto.${className}Dto;
import ${package.Service}.${table.serviceName};
import ${cfg.PackageParent}#if(${package.ModuleName}).${package.ModuleName}#end.mapstruct.${className}Mapper;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment