[ server ] - add quartz and knife4j framework

This commit is contained in:
zeaslity
2023-01-10 14:42:25 +08:00
parent 9d04af3dd1
commit 0c4531dccf
9 changed files with 555 additions and 2 deletions

View File

@@ -31,6 +31,19 @@
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
<!-- 2023-1-10 introduce the quartz framework -->
<!--http://www.quartz-scheduler.org/documentation/quartz-2.3.0/-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!--<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-influx</artifactId>

View File

@@ -1,4 +1,4 @@
package io.wdd.rpc.execute.web;
package io.wdd.rpc.controller;
import io.wdd.common.beans.response.R;
import io.wdd.rpc.execute.result.CreateStreamReader;
@@ -51,7 +51,6 @@ public class ExecutionController {
) {
createStreamReader.registerStreamReader(COMMAND_RESULT_REDIS_STREAM_LISTENER_CONTAINER ,streamKey);
}
@@ -65,4 +64,14 @@ public class ExecutionController {
}
@PostMapping("/agentUpdate")
public void AgentUpdate(
@RequestParam(value = "agentTopicName") String agentTopicName
) {
}
}

View File

@@ -0,0 +1,75 @@
package io.wdd.rpc.controller;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.*;
import io.wdd.rpc.scheduler.config.UpdateJobBean;
import io.wdd.rpc.scheduler.service.OctopusQuartzService;
import org.quartz.JobDataMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
@Api(value = "quartz增删改查相关API")
@RequestMapping(value = "/quartz")
public class QuartzCRUDController {
@Autowired
OctopusQuartzService octopusQuartzService;
// @ApiOperation(value = "使用quartz添加job")
// @RequestMapping(value = "/addJob/{jobUUID}", method = RequestMethod.POST)
// public void addQuartzJob(@ApiParam(name = "jobUUID") @PathVariable("jobUUID") String jobUUID, @ApiParam(name = "JobXXXBean") @RequestBody JobXXXBean jobXXXBean) {
//
// if (jobXXXBean.getOpenBean() != null) {
// JobDataMap jobDataMap = new JobDataMap();
// jobDataMap.put("key01", jobXXXBean.getKey01());
// jobDataMap.put("key02", jobXXXBean.getKey02());
// jobDataMap.put("key03", jobXXXBean.getKey03());
// jobDataMap.put("jobTimeCron", jobXXXBean.getJobTimeCron());
// jobDataMap.put("key04", jobXXXBean.getKey04());
// octopusQuartzService.addJob(Job1.class, jobUUID, jobUUID, jobXXXBean.getJobTimeCron(), jobDataMap);
// } else {
// throw new BadRequestException("参数错误");
// }
// }
@ApiOperation(value = "使用quartz查询所有job")
@RequestMapping(value = "/queryAllJob", method = RequestMethod.GET)
public List<Map<String, Object>> queryAllQuartzJob() {
List<Map<String, Object>> list = octopusQuartzService.queryAllJob();
return list;
}
@ApiOperation(value = "使用quartz查询所有运行job")
@RequestMapping(value = "/queryRunJob", method = RequestMethod.GET)
public List<Map<String, Object>> queryRunQuartzJob() {
List<Map<String, Object>> list = octopusQuartzService.queryRunJob();
return list;
}
@ApiOperation(value = "使用quartz删除job")
@RequestMapping(value = "/deleteJob/{jobUUID}", method = RequestMethod.DELETE)
public void deleteJob(@ApiParam(name = "jobUUID") @PathVariable("jobUUID") String jobUUID) {
octopusQuartzService.deleteJob(jobUUID, jobUUID);
}
@ApiOperation(value = "使用quartz修改job的cron时间")
@RequestMapping(value = "/updateJob/{jobUUID}", method = RequestMethod.PUT)
public void deleteJob(@ApiParam(name = "jobUUID") @PathVariable("jobUUID") String jobUUID, @ApiParam(name = "jobCronTime") @RequestBody UpdateJobBean updateJobBean) {
octopusQuartzService.updateJob(jobUUID, jobUUID, updateJobBean.getJobCronTime());
}
}

View File

@@ -0,0 +1,24 @@
package io.wdd.rpc.scheduler.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* @author Andya
* @create 2021/04/01
*/
@ApiModel(value = "更新job cron时间参数")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UpdateJobBean {
@ApiModelProperty(value = "jobTime的cron表达式", example = "0 0 1 * * ?")
String jobCronTime;
public String getJobCronTime() {
return jobCronTime;
}
public void setJobCronTime(String jobCronTime) {
this.jobCronTime = jobCronTime;
}
}

View File

@@ -0,0 +1,81 @@
package io.wdd.rpc.scheduler.service;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.util.List;
import java.util.Map;
public interface OctopusQuartzService {
/**
* 增加一个任务job
* @param jobClass 任务job实现类
* @param jobName 任务job名称保证唯一性
* @param jobGroupName 任务job组名
* @param jobTime 任务时间间隔(秒)
* @param jobTimes 任务运行次数(若<0则不限次数
* @param jobData 任务参数
*/
void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobTime,
int jobTimes, Map jobData);
/**
* 增加一个任务job
* @param jobClass 任务job实现类
* @param jobName 任务job名称保证唯一性
* @param jobGroupName 任务job组名
* @param jobTime 任务时间表达式
* @param jobData 任务参数
*/
void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobTime, Map jobData);
/**
* 修改一个任务job
* @param jobName 任务名称
* @param jobGroupName 任务组名
* @param jobTime cron时间表达式
*/
void updateJob(String jobName, String jobGroupName, String jobTime);
/**
* 删除一个任务job
* @param jobName
* @param jobGroupName
*/
void deleteJob(String jobName, String jobGroupName);
/**
* 暂停一个任务job
* @param jobName
* @param jobGroupName
*/
void pauseJob(String jobName, String jobGroupName);
/**
* 恢复一个任务job
* @param jobName
* @param jobGroupName
*/
void resumeJob(String jobName, String jobGroupName);
/**
* 立即执行一个任务job
* @param jobName
* @param jobGroupName
*/
void runAJobNow(String jobName, String jobGroupName);
/**
* 获取所有任务job
* @return
*/
List<Map<String, Object>> queryAllJob();
/**
* 获取正在运行的任务job
* @return
*/
List<Map<String, Object>> queryRunJob();
}

View File

@@ -0,0 +1,287 @@
package io.wdd.rpc.scheduler.service;
import io.wdd.common.handler.MyRuntimeException;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.DateBuilder.IntervalUnit;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.*;
/**
* @author Andya
* @date 2021/4/01
*/
@Slf4j
@Service
public class OctopusQuartzServiceImpl implements OctopusQuartzService {
@Autowired
private Scheduler scheduler;
@PostConstruct
public void startScheduler() {
try {
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 增加一个job
*
* @param jobClass
* 任务实现类
* @param jobName
* 任务名称
* @param jobGroupName
* 任务组名
* @param jobTime
* 时间表达式 (这是每隔多少秒为一次任务)
* @param jobTimes
* 运行的次数 <0:表示不限次数)
* @param jobData
* 参数
*/
@Override
public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobTime,
int jobTimes, Map jobData) {
try {
// 任务名称和组构成任务key
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
.build();
// 设置job参数
if(jobData!= null && jobData.size()>0){
jobDetail.getJobDataMap().putAll(jobData);
}
// 使用simpleTrigger规则
Trigger trigger = null;
if (jobTimes < 0) {
trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withIntervalInSeconds(jobTime))
.startNow().build();
} else {
trigger = TriggerBuilder
.newTrigger().withIdentity(jobName, jobGroupName).withSchedule(SimpleScheduleBuilder
.repeatSecondlyForever(1).withIntervalInSeconds(jobTime).withRepeatCount(jobTimes))
.startNow().build();
}
log.info("jobDataMap: {}", jobDetail.getJobDataMap().getWrappedMap());
scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
throw new MyRuntimeException("add job error!");
}
}
/**
* 增加一个job
*
* @param jobClass
* 任务实现类
* @param jobName
* 任务名称(建议唯一)
* @param jobGroupName
* 任务组名
* @param jobTime
* 时间表达式 0/5 * * * * ?
* @param jobData
* 参数
*/
@Override
public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobTime, Map jobData) {
try {
// 创建jobDetail实例绑定Job实现类
// 指明job的名称所在组的名称以及绑定job类
// 任务名称和组构成任务key
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
.build();
// 设置job参数
if(jobData!= null && jobData.size()>0){
jobDetail.getJobDataMap().putAll(jobData);
}
// 定义调度触发规则
// 使用cornTrigger规则
// 触发器key
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
.startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))
.withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).startNow().build();
// 把作业和触发器注册到任务调度中
scheduler.scheduleJob(jobDetail, trigger);
log.info("jobDataMap: {}", jobDetail.getJobDataMap());
} catch (Exception e) {
e.printStackTrace();
throw new MyRuntimeException("add job error!");
}
}
/**
* 修改 一个job的 时间表达式
*
* @param jobName
* @param jobGroupName
* @param jobTime
*/
@Override
public void updateJob(String jobName, String jobGroupName, String jobTime) {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
log.info("new jobTime: {}", jobTime);
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).build();
// 重启触发器
scheduler.rescheduleJob(triggerKey, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
throw new MyRuntimeException("update job error!");
}
}
/**
* 删除任务一个job
*
* @param jobName
* 任务名称
* @param jobGroupName
* 任务组名
*/
@Override
public void deleteJob(String jobName, String jobGroupName) {
try {
scheduler.deleteJob(new JobKey(jobName, jobGroupName));
} catch (Exception e) {
e.printStackTrace();
throw new MyRuntimeException("delete job error!");
}
}
/**
* 暂停一个job
*
* @param jobName
* @param jobGroupName
*/
@Override
public void pauseJob(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
scheduler.pauseJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
throw new MyRuntimeException("pause job error!");
}
}
/**
* 恢复一个job
*
* @param jobName
* @param jobGroupName
*/
@Override
public void resumeJob(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
scheduler.resumeJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
throw new MyRuntimeException("resume job error!");
}
}
/**
* 立即执行一个job
*
* @param jobName
* @param jobGroupName
*/
@Override
public void runAJobNow(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
scheduler.triggerJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
throw new MyRuntimeException("run a job error!");
}
}
/**
* 获取所有计划中的任务列表
*
* @return
*/
@Override
public List<Map<String, Object>> queryAllJob() {
List<Map<String, Object>> jobList = null;
try {
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
jobList = new ArrayList<Map<String, Object>>();
for (JobKey jobKey : jobKeys) {
log.info("maps: {}", scheduler.getJobDetail(jobKey).getJobDataMap().getWrappedMap());
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
for (Trigger trigger : triggers) {
Map<String, Object> map = new HashMap<>();
map.put("jobName", jobKey.getName());
map.put("jobGroupName", jobKey.getGroup());
map.put("description", "触发器:" + trigger.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
map.put("jobStatus", triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
map.put("jobTime", cronExpression);
}
jobList.add(map);
}
}
} catch (SchedulerException e) {
e.printStackTrace();
throw new MyRuntimeException("query all jobs error!");
}
return jobList;
}
/**
* 获取所有正在运行的job
*
* @return
*/
@Override
public List<Map<String, Object>> queryRunJob() {
List<Map<String, Object>> jobList = null;
try {
List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
jobList = new ArrayList<Map<String, Object>>(executingJobs.size());
for (JobExecutionContext executingJob : executingJobs) {
Map<String, Object> map = new HashMap<String, Object>();
JobDetail jobDetail = executingJob.getJobDetail();
JobKey jobKey = jobDetail.getKey();
Trigger trigger = executingJob.getTrigger();
map.put("jobName", jobKey.getName());
map.put("jobGroupName", jobKey.getGroup());
map.put("description", "触发器:" + trigger.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
map.put("jobStatus", triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
map.put("jobTime", cronExpression);
}
jobList.add(map);
}
} catch (SchedulerException e) {
e.printStackTrace();
throw new MyRuntimeException("query run jobs error!");
}
return jobList;
}
}

View File

@@ -0,0 +1,59 @@
package io.wdd.server.config;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableKnife4j
@EnableSwagger2
public class Knife4jConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.useDefaultResponseMessages(false)
.apiInfo(apiInfo())
.groupName("Server核心业务")
.select()
// controller包路径配置不对的话找不到
.apis(
RequestHandlerSelectors.basePackage("io.wdd.server.controller")
)
.paths(PathSelectors.any())
.build();
}
@Bean
public Docket createRestApiRPC() {
return new Docket(DocumentationType.SWAGGER_2)
.useDefaultResponseMessages(false)
.apiInfo(apiInfo())
.groupName("Server调用Agent业务")
.select()
// controller包路径配置不对的话找不到
.apis(
RequestHandlerSelectors.basePackage("io.wdd.rpc.controller")
)
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Octopus Server")
.description("Octopus Server Knife4j Documents")
.version("1.0")
.build();
}
}

View File

@@ -1,6 +1,8 @@
package io.wdd.server.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.wdd.server.beans.po.DomainInfoPO;
import io.wdd.server.beans.po.ServerInfoPO;
import io.wdd.server.beans.vo.AppInfoVO;
@@ -16,6 +18,7 @@ import org.springframework.web.bind.annotation.*;
import java.util.List;
@Api("Octopus Server - Agent服务器")
@RestController
@RequestMapping("/server")
public class ServerController {
@@ -24,6 +27,7 @@ public class ServerController {
CoreServerService coreServerService;
@GetMapping("/all")
@ApiOperation("获取所有的服务器信息")
public R<List> serverGetAll() {
return R.ok(coreServerService.serverGetAll());