wangwei 7 vuotta sitten
vanhempi
commit
8da98f9e03
37 muutettua tiedostoa jossa 1447 lisäystä ja 1403 poistoa
  1. 12 12
      .gitignore
  2. 85 0
      examcloud-task-api-provider/src/main/java/cn/com/qmth/examcloud/task/api/controller/JobController.java
  3. 0 77
      examcloud-task-api-provider/src/main/java/cn/com/qmth/task/api/provider/TaskScheduleApi.java
  4. 43 50
      examcloud-task-base/src/main/java/cn/com/qmth/examcloud/task/base/AbstractTask.java
  5. 53 53
      examcloud-task-base/src/main/java/cn/com/qmth/examcloud/task/base/DistributionJob.java
  6. 307 307
      examcloud-task-base/src/main/java/cn/com/qmth/examcloud/task/base/QuartzManager.java
  7. 105 133
      examcloud-task-base/src/main/java/cn/com/qmth/examcloud/task/base/ScheduleJob.java
  8. 18 18
      examcloud-task-base/src/main/java/cn/com/qmth/examcloud/task/base/StatefulDistributionJob.java
  9. 18 18
      examcloud-task-base/src/main/java/cn/com/qmth/examcloud/task/base/Task.java
  10. 0 34
      examcloud-task-base/src/main/java/cn/com/qmth/task/base/enums/JobStatus.java
  11. 17 16
      examcloud-task-dao/src/main/java/cn/com/qmth/examcloud/task/dao/ScheduleJobRepo.java
  12. 15 0
      examcloud-task-dao/src/main/java/cn/com/qmth/examcloud/task/dao/TaskExecutionRepo.java
  13. 129 0
      examcloud-task-dao/src/main/java/cn/com/qmth/examcloud/task/dao/entity/ScheduleJobEntity.java
  14. 92 0
      examcloud-task-dao/src/main/java/cn/com/qmth/examcloud/task/dao/entity/TaskExecutionEntity.java
  15. 0 192
      examcloud-task-dao/src/main/java/cn/com/qmth/task/entity/ScheduleJobEntity.java
  16. 29 0
      examcloud-task-service/src/main/java/cn/com/qmth/examcloud/task/service/job/OeCleanExamRecordTask.java
  17. 0 24
      examcloud-task-service/src/main/java/cn/com/qmth/task/service/ScheduleJobEntityService.java
  18. 0 55
      examcloud-task-service/src/main/java/cn/com/qmth/task/service/impl/ScheduleJobEntityServiceImpl.java
  19. 0 33
      examcloud-task-service/src/main/java/cn/com/qmth/task/service/job/JobsInitialization.java
  20. 0 54
      examcloud-task-service/src/main/java/cn/com/qmth/task/service/job/OeCleanExamRecordTask.java
  21. 0 0
      examcloud-task-starter/.logs/interface/task.interface.log
  22. 0 0
      examcloud-task-starter/.logs/task/task.log
  23. 16 0
      examcloud-task-starter/.springBeans
  24. 97 96
      examcloud-task-starter/pom.xml
  25. 91 0
      examcloud-task-starter/src/main/java/cn/com/qmth/examcloud/task/starter/TaskApp.java
  26. 83 0
      examcloud-task-starter/src/main/java/cn/com/qmth/examcloud/task/starter/config/DefaultWebMvcConfigurerAdapter.java
  27. 40 0
      examcloud-task-starter/src/main/java/cn/com/qmth/examcloud/task/starter/config/JobsInitialization.java
  28. 23 0
      examcloud-task-starter/src/main/java/cn/com/qmth/examcloud/task/starter/config/JobsInitializationListener.java
  29. 0 16
      examcloud-task-starter/src/main/java/cn/com/qmth/task/starter/JobsInitializationListener.java
  30. 0 40
      examcloud-task-starter/src/main/java/cn/com/qmth/task/starter/TaskApplication.java
  31. 8 8
      examcloud-task-starter/src/main/resources/application-dev.properties
  32. 27 30
      examcloud-task-starter/src/main/resources/application.properties
  33. 77 76
      examcloud-task-starter/src/main/resources/logback-spring.xml
  34. 3 0
      examcloud-task-starter/src/main/resources/security-exclusions.conf
  35. 1 0
      examcloud-task-starter/src/main/resources/security-mapping.properties
  36. 31 31
      examcloud-task-starter/src/test/java/cn/com/qmth/task/TestTaskSchedule.java
  37. 27 30
      examcloud-task-starter/target/classes/application.properties

+ 12 - 12
.gitignore

@@ -1,12 +1,12 @@
-/*.project
-/.settings
-/examcloud-task-api-provider/*.classpath
-*.project
-/examcloud-task-api-provider/.settings
-*.classpath
-org.eclipse.core.resources.prefs
-org.eclipse.jdt.core.prefs
-org.eclipse.m2e.core.prefs
-*.class
-target
-log
+.project
+.classpath
+.settings
+target/
+.idea/
+*.iml
+*test/
+# Package Files #
+*.jar
+logs/
+
+

+ 85 - 0
examcloud-task-api-provider/src/main/java/cn/com/qmth/examcloud/task/api/controller/JobController.java

@@ -0,0 +1,85 @@
+package cn.com.qmth.examcloud.task.api.controller;
+
+import javax.transaction.Transactional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import cn.com.qmth.examcloud.commons.base.exception.StatusException;
+import cn.com.qmth.examcloud.commons.web.support.ControllerSupport;
+import cn.com.qmth.examcloud.task.base.QuartzManager;
+import cn.com.qmth.examcloud.task.base.ScheduleJob;
+import cn.com.qmth.examcloud.task.dao.ScheduleJobRepo;
+import cn.com.qmth.examcloud.task.dao.entity.ScheduleJobEntity;
+import io.swagger.annotations.ApiOperation;
+
+@Transactional
+@RestController
+@RequestMapping("${$rmp.ctr.task}" + "job")
+public class JobController extends ControllerSupport {
+
+	@Autowired
+	private ScheduleJobRepo scheduleJobEntityRepo;
+
+	@Autowired
+	private QuartzManager quartzManager;
+
+	@ApiOperation(value = "启动job")
+	@PostMapping("/executeJob/{jobName}")
+	public void executeJob(@PathVariable String jobName) {
+		ScheduleJob scheduleJob = getEnableScheduleJob(jobName);
+		quartzManager.addJob(scheduleJob);
+	}
+
+	@ApiOperation(value = "暂停job")
+	@PostMapping("/pauseJob/{jobName}")
+	public void pauseJob(@PathVariable String jobName) {
+		ScheduleJob scheduleJob = getEnableScheduleJob(jobName);
+		quartzManager.pauseJob(scheduleJob);
+	}
+
+	@ApiOperation(value = "从暂停中恢复job")
+	@PostMapping("/resumeJob/{jobName}")
+	public void resumeJob(@PathVariable String jobName) {
+		ScheduleJob scheduleJob = getEnableScheduleJob(jobName);
+		quartzManager.resumeJob(scheduleJob);
+	}
+
+	@ApiOperation(value = "删除job")
+	@PostMapping("/deleteJob/{jobName}")
+	public void deleteJob(@PathVariable String jobName) {
+		ScheduleJob scheduleJob = getEnableScheduleJob(jobName);
+		quartzManager.deleteJob(scheduleJob);
+	}
+
+	/**
+	 * 获取可用job
+	 *
+	 * @author WANGWEI
+	 * @param jobName
+	 * @return
+	 */
+	private ScheduleJob getEnableScheduleJob(String jobName) {
+		ScheduleJobEntity jobEntity = scheduleJobEntityRepo.findByJobName(jobName);
+		if (null == jobEntity) {
+			throw new StatusException("T-100001", "任务不存在");
+		}
+
+		if (!jobEntity.getEnable()) {
+			throw new StatusException("T-100001", "任务被禁用");
+		}
+
+		ScheduleJob scheduleJob = new ScheduleJob();
+		scheduleJob.setJobName(jobEntity.getJobName());
+		scheduleJob.setJobGroup(jobEntity.getJobGroup());
+		scheduleJob.setSpringBean(jobEntity.getSpringBean());
+		scheduleJob.setCronExpression(jobEntity.getCronExpression());
+		scheduleJob.setStateful(jobEntity.getStateful());
+
+		return scheduleJob;
+	}
+
+}

+ 0 - 77
examcloud-task-api-provider/src/main/java/cn/com/qmth/task/api/provider/TaskScheduleApi.java

@@ -1,77 +0,0 @@
-package cn.com.qmth.task.api.provider;
-
-import io.swagger.annotations.ApiOperation;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import cn.com.qmth.task.base.QuartzManager;
-import cn.com.qmth.task.base.ScheduleJob;
-import cn.com.qmth.task.base.enums.JobStatus;
-import cn.com.qmth.task.entity.ScheduleJobEntity;
-import cn.com.qmth.task.service.ScheduleJobEntityService;
-
-@RestController
-@RequestMapping("${app.api.task}/taskScheduleApi")
-public class TaskScheduleApi {
-	
-	@Autowired
-	private ScheduleJobEntityService scheduleJobEntityService;
-	
-	@Autowired
-	private QuartzManager quartzManager;
-	
-	@ApiOperation(value="启动job")
-	@PostMapping("/executeJob/{jobName}")
-	public void executeJob(@PathVariable String jobName){
-		ScheduleJobEntity scheduleJobEntity = scheduleJobEntityService.findByJobName(jobName);
-		ScheduleJob scheduleJob = scheduleJobEntityService.transformationToScheduleJob(scheduleJobEntity);
-		quartzManager.addJob(scheduleJob);
-	}
-	
-	@ApiOperation(value="暂停job")
-	@PostMapping("/pauseJob/{jobName}")
-	public void pauseJob(@PathVariable String jobName){
-		ScheduleJobEntity scheduleJobEntity = scheduleJobEntityService.findByJobName(jobName);
-		ScheduleJob scheduleJob = scheduleJobEntityService.transformationToScheduleJob(scheduleJobEntity);
-		try{
-			quartzManager.pauseJob(scheduleJob);
-			scheduleJobEntity.setJobStatus(JobStatus.PAUSE.name());
-			scheduleJobEntity.setOperateResult(JobStatus.PAUSE.name()+" SUCCESS");
-			scheduleJobEntityService.saveScheduleJobEntity(scheduleJobEntity);
-		}catch(Exception e){
-			scheduleJobEntity.setOperateResult(JobStatus.PAUSE.name()+" FAILED");
-			scheduleJobEntityService.saveScheduleJobEntity(scheduleJobEntity);
-			e.printStackTrace();
-		}
-	}
-	
-	@ApiOperation(value="从暂停中恢复job")
-	@PostMapping("/resumeJob/{jobName}")
-	public void resumeJob(@PathVariable String jobName){
-		ScheduleJobEntity scheduleJobEntity = scheduleJobEntityService.findByJobName(jobName);
-		ScheduleJob scheduleJob = scheduleJobEntityService.transformationToScheduleJob(scheduleJobEntity);
-		quartzManager.resumeJob(scheduleJob);
-	}
-	
-	@ApiOperation(value="删除job")
-	@PostMapping("/deleteJob/{jobName}")
-	public void deleteJob(@PathVariable String jobName){
-		ScheduleJobEntity scheduleJobEntity = scheduleJobEntityService.findByJobName(jobName);
-		ScheduleJob scheduleJob = scheduleJobEntityService.transformationToScheduleJob(scheduleJobEntity);
-		try{
-			quartzManager.deleteJob(scheduleJob);
-			scheduleJobEntity.setJobStatus(JobStatus.DELETE.name());
-			scheduleJobEntity.setOperateResult(JobStatus.DELETE.name()+" SUCCESS");
-			scheduleJobEntityService.saveScheduleJobEntity(scheduleJobEntity);
-		}catch(Exception e){
-			scheduleJobEntity.setOperateResult(JobStatus.DELETE.name()+" FAILED");
-			scheduleJobEntityService.saveScheduleJobEntity(scheduleJobEntity);
-			e.printStackTrace();
-		}
-	}
-	
-}

+ 43 - 50
examcloud-task-base/src/main/java/cn/com/qmth/task/base/AbstractTask.java → examcloud-task-base/src/main/java/cn/com/qmth/examcloud/task/base/AbstractTask.java

@@ -1,50 +1,43 @@
-package cn.com.qmth.task.base;
-
-import cn.com.qmth.examcloud.commons.base.exception.ExamCloudRuntimeException;
-import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
-import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
-import cn.com.qmth.examcloud.commons.base.util.JsonUtil;
-
-
-/**
- * 任务调度抽象类
- *
- * @author WANGWEI
- * @date 2018年3月7日
- * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
- */
-public abstract class AbstractTask implements Task
-{
-	
-	private static final ExamCloudLog taskLog = ExamCloudLogFactory.getLog("TASK_LOGGER");
-
-	@Override
-	public void execute(ScheduleJob scheduleJob)
-	{
-		if (taskLog.isDebugEnabled())
-		{
-			taskLog.debug("[TASK IN]. detail: " + JsonUtil.toJson(scheduleJob));
-		}
-		try
-		{
-			run(scheduleJob);
-		}
-		catch (Exception e)
-		{
-			if (taskLog.isErrorEnabled())
-			{
-				taskLog.error("[TASK EXCEPTION]. detail: " + JsonUtil.toJson(scheduleJob), e);
-			}
-			throw new ExamCloudRuntimeException(e);
-		}
-
-		if (taskLog.isDebugEnabled())
-		{
-			taskLog.debug("[TASK OUT]. detail: " + JsonUtil.toJson(scheduleJob));
-		}
-
-	}
-
-	public abstract void run(ScheduleJob scheduleJob) throws Exception;
-
-}
+package cn.com.qmth.examcloud.task.base;
+
+import cn.com.qmth.examcloud.commons.base.exception.ExamCloudRuntimeException;
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
+import cn.com.qmth.examcloud.commons.base.util.JsonUtil;
+
+/**
+ * 任务调度抽象类
+ *
+ * @author WANGWEI
+ * @date 2018年3月7日
+ * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
+ */
+public abstract class AbstractTask implements Task {
+
+	protected ExamCloudLog taskLog = ExamCloudLogFactory.getLog("TASK_LOGGER");
+
+	protected ExamCloudLog debugLog = ExamCloudLogFactory.getLog(this.getClass());
+
+	@Override
+	public void execute(ScheduleJob scheduleJob) {
+		if (taskLog.isDebugEnabled()) {
+			taskLog.debug("[TASK IN]. detail: " + JsonUtil.toJson(scheduleJob));
+		}
+		try {
+			run(scheduleJob);
+		} catch (Exception e) {
+			if (taskLog.isErrorEnabled()) {
+				taskLog.error("[TASK EXCEPTION]. detail: " + JsonUtil.toJson(scheduleJob), e);
+			}
+			throw new ExamCloudRuntimeException(e);
+		}
+
+		if (taskLog.isDebugEnabled()) {
+			taskLog.debug("[TASK OUT]. detail: " + JsonUtil.toJson(scheduleJob));
+		}
+
+	}
+
+	public abstract void run(ScheduleJob scheduleJob) throws Exception;
+
+}

+ 53 - 53
examcloud-task-base/src/main/java/cn/com/qmth/task/base/DistributionJob.java → examcloud-task-base/src/main/java/cn/com/qmth/examcloud/task/base/DistributionJob.java

@@ -1,53 +1,53 @@
-package cn.com.qmth.task.base;
-
-import org.quartz.Job;
-import org.quartz.JobExecutionContext;
-import org.quartz.JobExecutionException;
-
-import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
-import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
-import cn.com.qmth.examcloud.commons.base.util.JsonUtil;
-import cn.com.qmth.examcloud.commons.web.support.SpringContextHolder;
-
-
-/**
- * 并行任务分发器
- *
- * @author WANGWEI
- * @date 2018年3月7日
- * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
- */
-public class DistributionJob implements Job
-{
-	private static final ExamCloudLog TASK_LOG = ExamCloudLogFactory.getLog("TASK_LOGGER");
-
-	@Override
-	public void execute(JobExecutionContext context) throws JobExecutionException
-	{
-		ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
-
-		if (TASK_LOG.isDebugEnabled())
-		{
-			TASK_LOG.debug("distribute job. job detail :" + JsonUtil.toJson(scheduleJob));
-		}
-
-		try
-		{
-			Object bean = SpringContextHolder.getBean(scheduleJob.getSpringBean());
-
-			Task task = (Task) bean;
-			task.execute(scheduleJob);
-		}
-		catch (Exception e)
-		{
-			if (TASK_LOG.isErrorEnabled())
-			{
-				TASK_LOG.error(
-						"fail to distribute job. job detail :" + JsonUtil.toJson(scheduleJob), e);
-			}
-			throw new JobExecutionException(e);
-		}
-
-	}
-
-}
+package cn.com.qmth.examcloud.task.base;
+
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
+import cn.com.qmth.examcloud.commons.base.util.JsonUtil;
+import cn.com.qmth.examcloud.commons.web.support.SpringContextHolder;
+
+
+/**
+ * 并行任务分发器
+ *
+ * @author WANGWEI
+ * @date 2018年3月7日
+ * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
+ */
+public class DistributionJob implements Job
+{
+	private static final ExamCloudLog TASK_LOG = ExamCloudLogFactory.getLog("TASK_LOGGER");
+
+	@Override
+	public void execute(JobExecutionContext context) throws JobExecutionException
+	{
+		ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
+
+		if (TASK_LOG.isDebugEnabled())
+		{
+			TASK_LOG.debug("distribute job. job detail :" + JsonUtil.toJson(scheduleJob));
+		}
+
+		try
+		{
+			Object bean = SpringContextHolder.getBean(scheduleJob.getSpringBean());
+
+			Task task = (Task) bean;
+			task.execute(scheduleJob);
+		}
+		catch (Exception e)
+		{
+			if (TASK_LOG.isErrorEnabled())
+			{
+				TASK_LOG.error(
+						"fail to distribute job. job detail :" + JsonUtil.toJson(scheduleJob), e);
+			}
+			throw new JobExecutionException(e);
+		}
+
+	}
+
+}

+ 307 - 307
examcloud-task-base/src/main/java/cn/com/qmth/task/base/QuartzManager.java → examcloud-task-base/src/main/java/cn/com/qmth/examcloud/task/base/QuartzManager.java

@@ -1,308 +1,308 @@
-package cn.com.qmth.task.base;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-import org.quartz.CronScheduleBuilder;
-import org.quartz.CronTrigger;
-import org.quartz.Job;
-import org.quartz.JobBuilder;
-import org.quartz.JobDetail;
-import org.quartz.JobExecutionContext;
-import org.quartz.JobKey;
-import org.quartz.Scheduler;
-import org.quartz.SchedulerException;
-import org.quartz.Trigger;
-import org.quartz.TriggerBuilder;
-import org.quartz.TriggerKey;
-import org.quartz.impl.matchers.GroupMatcher;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.quartz.SchedulerFactoryBean;
-import org.springframework.stereotype.Component;
-
-import cn.com.qmth.examcloud.commons.base.exception.ExamCloudRuntimeException;
-import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
-import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
-import cn.com.qmth.examcloud.commons.base.util.JsonUtil;
-
-
-/**
- * Quartz 管理器
- *
- * @author WANGWEI
- * @date 2018年3月7日
- * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
- */
-@Component
-public class QuartzManager
-{
-	private static final ExamCloudLog TASK_LOG = ExamCloudLogFactory.getLog("TASK_LOGGER");
-
-	@Autowired
-	private SchedulerFactoryBean schedulerFactoryBean;
-
-	/**
-	 * 添加任务
-	 *
-	 * @author WANGWEI
-	 * @param job
-	 */
-	public void addJob(ScheduleJob job)
-	{
-		if (TASK_LOG.isDebugEnabled())
-		{
-			TASK_LOG.debug("add a job. job detail: " + JsonUtil.toJson(job));
-		}
-
-		try
-		{
-			Scheduler scheduler = schedulerFactoryBean.getScheduler();
-			TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
-
-			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
-
-			if (null == trigger)
-			{
-				Class<? extends Job> jobClass = job.isStateful()
-						? StatefulDistributionJob.class
-						: DistributionJob.class;
-				JobDetail jobDetail = JobBuilder.newJob(jobClass)
-						.withIdentity(job.getJobName(), job.getJobGroup()).build();
-
-				jobDetail.getJobDataMap().put("scheduleJob", job);
-
-				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
-						.cronSchedule(job.getCronExpression());
-
-				trigger = TriggerBuilder.newTrigger()
-						.withIdentity(job.getJobName(), job.getJobGroup())
-						.withSchedule(scheduleBuilder).build();
-
-				scheduler.scheduleJob(jobDetail, trigger);
-			}
-			else
-			{
-				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
-						.cronSchedule(job.getCronExpression());
-
-				trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
-						.withSchedule(scheduleBuilder).build();
-
-				scheduler.rescheduleJob(triggerKey, trigger);
-			}
-		}
-		catch (SchedulerException e)
-		{
-			TASK_LOG.error("Fail to add a job. job detail: " + JsonUtil.toJson(job), e);
-			throw new ExamCloudRuntimeException(e);
-		}
-
-		if (TASK_LOG.isDebugEnabled())
-		{
-			TASK_LOG.debug("add a job successfully. job detail: " + JsonUtil.toJson(job));
-		}
-	}
-
-	/**
-	 * 获取所有计划中的任务列表
-	 *
-	 * @author WANGWEI
-	 * @return
-	 */
-	public List<ScheduleJob> getAllJobs()
-	{
-		try
-		{
-			Scheduler scheduler = schedulerFactoryBean.getScheduler();
-			GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
-			Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
-			List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
-			for (JobKey jobKey : jobKeys)
-			{
-				List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
-				for (Trigger trigger : triggers)
-				{
-					ScheduleJob job = new ScheduleJob();
-					job.setJobName(jobKey.getName());
-					job.setJobGroup(jobKey.getGroup());
-					job.setDescription("触发器:" + trigger.getKey());
-					Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
-					job.setJobStatus(triggerState.name());
-					if (trigger instanceof CronTrigger)
-					{
-						CronTrigger cronTrigger = (CronTrigger) trigger;
-						String cronExpression = cronTrigger.getCronExpression();
-						job.setCronExpression(cronExpression);
-					}
-					jobList.add(job);
-				}
-			}
-			return jobList;
-		}
-		catch (SchedulerException e)
-		{
-			TASK_LOG.error("Fail to get all jobs.", e);
-			throw new ExamCloudRuntimeException(e);
-		}
-	}
-
-	/**
-	 * 所有正在运行的job
-	 *
-	 * @author WANGWEI
-	 * @return
-	 */
-	public List<ScheduleJob> getRunningJobs()
-	{
-		try
-		{
-			Scheduler scheduler = schedulerFactoryBean.getScheduler();
-			List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
-			List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(executingJobs.size());
-			for (JobExecutionContext executingJob : executingJobs)
-			{
-				ScheduleJob job = new ScheduleJob();
-				JobDetail jobDetail = executingJob.getJobDetail();
-				JobKey jobKey = jobDetail.getKey();
-				Trigger trigger = executingJob.getTrigger();
-				job.setJobName(jobKey.getName());
-				job.setJobGroup(jobKey.getGroup());
-				job.setDescription("触发器:" + trigger.getKey());
-				Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
-				job.setJobStatus(triggerState.name());
-				if (trigger instanceof CronTrigger)
-				{
-					CronTrigger cronTrigger = (CronTrigger) trigger;
-					String cronExpression = cronTrigger.getCronExpression();
-					job.setCronExpression(cronExpression);
-				}
-				jobList.add(job);
-			}
-			return jobList;
-		}
-		catch (Exception e)
-		{
-			TASK_LOG.error("Fail to get running jobs.", e);
-			throw new ExamCloudRuntimeException(e);
-		}
-	}
-
-	/**
-	 * 暂停一个job
-	 *
-	 * @author WANGWEI
-	 * @param scheduleJob
-	 */
-	public void pauseJob(ScheduleJob scheduleJob)
-	{
-		try
-		{
-			Scheduler scheduler = schedulerFactoryBean.getScheduler();
-			JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
-			scheduler.pauseJob(jobKey);
-		}
-		catch (SchedulerException e)
-		{
-			TASK_LOG.error("Fail to pause Job. job detail: " + JsonUtil.toJson(scheduleJob), e);
-			throw new ExamCloudRuntimeException(e);
-		}
-	}
-
-	/**
-	 * 恢复一个job
-	 *
-	 * @author WANGWEI
-	 * @param scheduleJob
-	 */
-	public void resumeJob(ScheduleJob scheduleJob)
-	{
-		try
-		{
-			Scheduler scheduler = schedulerFactoryBean.getScheduler();
-			JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
-			scheduler.resumeJob(jobKey);
-		}
-		catch (SchedulerException e)
-		{
-			TASK_LOG.error("Fail to resume job. job detail: " + JsonUtil.toJson(scheduleJob), e);
-			throw new ExamCloudRuntimeException(e);
-		}
-	}
-
-	/**
-	 * 删除一个job
-	 *
-	 * @author WANGWEI
-	 * @param scheduleJob
-	 */
-	public void deleteJob(ScheduleJob scheduleJob)
-	{
-		try
-		{
-			Scheduler scheduler = schedulerFactoryBean.getScheduler();
-			JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
-			scheduler.deleteJob(jobKey);
-		}
-		catch (SchedulerException e)
-		{
-			TASK_LOG.error("Fail to delete job. job detail: " + JsonUtil.toJson(scheduleJob), e);
-			throw new ExamCloudRuntimeException(e);
-		}
-
-	}
-
-	/**
-	 * 执行job
-	 *
-	 * @author WANGWEI
-	 * @param scheduleJob
-	 */
-	public void runJob(ScheduleJob scheduleJob)
-	{
-		try
-		{
-			Scheduler scheduler = schedulerFactoryBean.getScheduler();
-			JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
-			scheduler.triggerJob(jobKey);
-		}
-		catch (SchedulerException e)
-		{
-			TASK_LOG.error("Fail to run job. job detail: " + JsonUtil.toJson(scheduleJob), e);
-			throw new ExamCloudRuntimeException(e);
-		}
-	}
-
-	/**
-	 * 更新job时间表达式
-	 *
-	 * @author WANGWEI
-	 * @param scheduleJob
-	 */
-	public void updateJobCronExpression(ScheduleJob scheduleJob)
-	{
-		try
-		{
-			Scheduler scheduler = schedulerFactoryBean.getScheduler();
-
-			TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(),
-					scheduleJob.getJobGroup());
-
-			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
-
-			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
-					.cronSchedule(scheduleJob.getCronExpression());
-
-			trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
-					.withSchedule(scheduleBuilder).build();
-
-			scheduler.rescheduleJob(triggerKey, trigger);
-		}
-		catch (SchedulerException e)
-		{
-			TASK_LOG.error("Fail to update job cron expression. job detail :"
-					+ JsonUtil.toJson(scheduleJob), e);
-			throw new ExamCloudRuntimeException(e);
-		}
-	}
+package cn.com.qmth.examcloud.task.base;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.quartz.CronScheduleBuilder;
+import org.quartz.CronTrigger;
+import org.quartz.Job;
+import org.quartz.JobBuilder;
+import org.quartz.JobDetail;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobKey;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.Trigger;
+import org.quartz.TriggerBuilder;
+import org.quartz.TriggerKey;
+import org.quartz.impl.matchers.GroupMatcher;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+import org.springframework.stereotype.Component;
+
+import cn.com.qmth.examcloud.commons.base.exception.ExamCloudRuntimeException;
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
+import cn.com.qmth.examcloud.commons.base.util.JsonUtil;
+
+
+/**
+ * Quartz 管理器
+ *
+ * @author WANGWEI
+ * @date 2018年3月7日
+ * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
+ */
+@Component
+public class QuartzManager
+{
+	private static final ExamCloudLog TASK_LOG = ExamCloudLogFactory.getLog("TASK_LOGGER");
+
+	@Autowired
+	private SchedulerFactoryBean schedulerFactoryBean;
+
+	/**
+	 * 添加任务
+	 *
+	 * @author WANGWEI
+	 * @param job
+	 */
+	public void addJob(ScheduleJob job)
+	{
+		if (TASK_LOG.isDebugEnabled())
+		{
+			TASK_LOG.debug("add a job. job detail: " + JsonUtil.toJson(job));
+		}
+
+		try
+		{
+			Scheduler scheduler = schedulerFactoryBean.getScheduler();
+			TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
+
+			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
+
+			if (null == trigger)
+			{
+				Class<? extends Job> jobClass = job.isStateful()
+						? StatefulDistributionJob.class
+						: DistributionJob.class;
+				JobDetail jobDetail = JobBuilder.newJob(jobClass)
+						.withIdentity(job.getJobName(), job.getJobGroup()).build();
+
+				jobDetail.getJobDataMap().put("scheduleJob", job);
+
+				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
+						.cronSchedule(job.getCronExpression());
+
+				trigger = TriggerBuilder.newTrigger()
+						.withIdentity(job.getJobName(), job.getJobGroup())
+						.withSchedule(scheduleBuilder).build();
+
+				scheduler.scheduleJob(jobDetail, trigger);
+			}
+			else
+			{
+				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
+						.cronSchedule(job.getCronExpression());
+
+				trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
+						.withSchedule(scheduleBuilder).build();
+
+				scheduler.rescheduleJob(triggerKey, trigger);
+			}
+		}
+		catch (SchedulerException e)
+		{
+			TASK_LOG.error("Fail to add a job. job detail: " + JsonUtil.toJson(job), e);
+			throw new ExamCloudRuntimeException(e);
+		}
+
+		if (TASK_LOG.isDebugEnabled())
+		{
+			TASK_LOG.debug("add a job successfully. job detail: " + JsonUtil.toJson(job));
+		}
+	}
+
+	/**
+	 * 获取所有计划中的任务列表
+	 *
+	 * @author WANGWEI
+	 * @return
+	 */
+	public List<ScheduleJob> getAllJobs()
+	{
+		try
+		{
+			Scheduler scheduler = schedulerFactoryBean.getScheduler();
+			GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
+			Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
+			List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
+			for (JobKey jobKey : jobKeys)
+			{
+				List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
+				for (Trigger trigger : triggers)
+				{
+					ScheduleJob job = new ScheduleJob();
+					job.setJobName(jobKey.getName());
+					job.setJobGroup(jobKey.getGroup());
+					job.setDescription("触发器:" + trigger.getKey());
+					Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
+					job.setJobStatus(triggerState.name());
+					if (trigger instanceof CronTrigger)
+					{
+						CronTrigger cronTrigger = (CronTrigger) trigger;
+						String cronExpression = cronTrigger.getCronExpression();
+						job.setCronExpression(cronExpression);
+					}
+					jobList.add(job);
+				}
+			}
+			return jobList;
+		}
+		catch (SchedulerException e)
+		{
+			TASK_LOG.error("Fail to get all jobs.", e);
+			throw new ExamCloudRuntimeException(e);
+		}
+	}
+
+	/**
+	 * 所有正在运行的job
+	 *
+	 * @author WANGWEI
+	 * @return
+	 */
+	public List<ScheduleJob> getRunningJobs()
+	{
+		try
+		{
+			Scheduler scheduler = schedulerFactoryBean.getScheduler();
+			List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
+			List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(executingJobs.size());
+			for (JobExecutionContext executingJob : executingJobs)
+			{
+				ScheduleJob job = new ScheduleJob();
+				JobDetail jobDetail = executingJob.getJobDetail();
+				JobKey jobKey = jobDetail.getKey();
+				Trigger trigger = executingJob.getTrigger();
+				job.setJobName(jobKey.getName());
+				job.setJobGroup(jobKey.getGroup());
+				job.setDescription("触发器:" + trigger.getKey());
+				Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
+				job.setJobStatus(triggerState.name());
+				if (trigger instanceof CronTrigger)
+				{
+					CronTrigger cronTrigger = (CronTrigger) trigger;
+					String cronExpression = cronTrigger.getCronExpression();
+					job.setCronExpression(cronExpression);
+				}
+				jobList.add(job);
+			}
+			return jobList;
+		}
+		catch (Exception e)
+		{
+			TASK_LOG.error("Fail to get running jobs.", e);
+			throw new ExamCloudRuntimeException(e);
+		}
+	}
+
+	/**
+	 * 暂停一个job
+	 *
+	 * @author WANGWEI
+	 * @param scheduleJob
+	 */
+	public void pauseJob(ScheduleJob scheduleJob)
+	{
+		try
+		{
+			Scheduler scheduler = schedulerFactoryBean.getScheduler();
+			JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
+			scheduler.pauseJob(jobKey);
+		}
+		catch (SchedulerException e)
+		{
+			TASK_LOG.error("Fail to pause Job. job detail: " + JsonUtil.toJson(scheduleJob), e);
+			throw new ExamCloudRuntimeException(e);
+		}
+	}
+
+	/**
+	 * 恢复一个job
+	 *
+	 * @author WANGWEI
+	 * @param scheduleJob
+	 */
+	public void resumeJob(ScheduleJob scheduleJob)
+	{
+		try
+		{
+			Scheduler scheduler = schedulerFactoryBean.getScheduler();
+			JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
+			scheduler.resumeJob(jobKey);
+		}
+		catch (SchedulerException e)
+		{
+			TASK_LOG.error("Fail to resume job. job detail: " + JsonUtil.toJson(scheduleJob), e);
+			throw new ExamCloudRuntimeException(e);
+		}
+	}
+
+	/**
+	 * 删除一个job
+	 *
+	 * @author WANGWEI
+	 * @param scheduleJob
+	 */
+	public void deleteJob(ScheduleJob scheduleJob)
+	{
+		try
+		{
+			Scheduler scheduler = schedulerFactoryBean.getScheduler();
+			JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
+			scheduler.deleteJob(jobKey);
+		}
+		catch (SchedulerException e)
+		{
+			TASK_LOG.error("Fail to delete job. job detail: " + JsonUtil.toJson(scheduleJob), e);
+			throw new ExamCloudRuntimeException(e);
+		}
+
+	}
+
+	/**
+	 * 执行job
+	 *
+	 * @author WANGWEI
+	 * @param scheduleJob
+	 */
+	public void runJob(ScheduleJob scheduleJob)
+	{
+		try
+		{
+			Scheduler scheduler = schedulerFactoryBean.getScheduler();
+			JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
+			scheduler.triggerJob(jobKey);
+		}
+		catch (SchedulerException e)
+		{
+			TASK_LOG.error("Fail to run job. job detail: " + JsonUtil.toJson(scheduleJob), e);
+			throw new ExamCloudRuntimeException(e);
+		}
+	}
+
+	/**
+	 * 更新job时间表达式
+	 *
+	 * @author WANGWEI
+	 * @param scheduleJob
+	 */
+	public void updateJobCronExpression(ScheduleJob scheduleJob)
+	{
+		try
+		{
+			Scheduler scheduler = schedulerFactoryBean.getScheduler();
+
+			TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(),
+					scheduleJob.getJobGroup());
+
+			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
+
+			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
+					.cronSchedule(scheduleJob.getCronExpression());
+
+			trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
+					.withSchedule(scheduleBuilder).build();
+
+			scheduler.rescheduleJob(triggerKey, trigger);
+		}
+		catch (SchedulerException e)
+		{
+			TASK_LOG.error("Fail to update job cron expression. job detail :"
+					+ JsonUtil.toJson(scheduleJob), e);
+			throw new ExamCloudRuntimeException(e);
+		}
+	}
 }

+ 105 - 133
examcloud-task-base/src/main/java/cn/com/qmth/task/base/ScheduleJob.java → examcloud-task-base/src/main/java/cn/com/qmth/examcloud/task/base/ScheduleJob.java

@@ -1,134 +1,106 @@
-package cn.com.qmth.task.base;
-
-import java.io.Serializable;
-
-/**
- * 任务配置
- *
- * @author WANGWEI
- * @date 2018年3月7日
- * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
- */
-public class ScheduleJob implements Serializable
-{
-	private static final long serialVersionUID = -1638993747996917970L;
-
-	/**
-	 * 任务名称
-	 */
-	private String jobName;
-
-	/**
-	 * 任务分组
-	 */
-	private String jobGroup;
-
-	/**
-	 * 任务状态
-	 */
-	private String jobStatus;
-
-	/**
-	 * cron表达式
-	 */
-	private String cronExpression;
-
-	/**
-	 * 描述
-	 */
-	private String description;
-
-	/**
-	 * Spring bean
-	 */
-	private String springBean;
-
-	/**
-	 * 是否顺序执行
-	 */
-	private boolean stateful = true;
-	
-	/**
-	 * 随着容器启动而启动
-	 */
-	private boolean startWithContainer = false;
-
-	public String getJobName()
-	{
-		return jobName;
-	}
-
-	public void setJobName(String jobName)
-	{
-		this.jobName = jobName;
-	}
-
-	public String getJobGroup()
-	{
-		return jobGroup;
-	}
-
-	public void setJobGroup(String jobGroup)
-	{
-		this.jobGroup = jobGroup;
-	}
-
-	public String getJobStatus()
-	{
-		return jobStatus;
-	}
-
-	public void setJobStatus(String jobStatus)
-	{
-		this.jobStatus = jobStatus;
-	}
-
-	public String getCronExpression()
-	{
-		return cronExpression;
-	}
-
-	public void setCronExpression(String cronExpression)
-	{
-		this.cronExpression = cronExpression;
-	}
-
-	public String getDescription()
-	{
-		return description;
-	}
-
-	public void setDescription(String description)
-	{
-		this.description = description;
-	}
-
-	public String getSpringBean()
-	{
-		return springBean;
-	}
-
-	public void setSpringBean(String springBean)
-	{
-		this.springBean = springBean;
-	}
-
-	public boolean isStateful()
-	{
-		return stateful;
-	}
-
-	public void setStateful(boolean stateful)
-	{
-		this.stateful = stateful;
-	}
-
-	public boolean isStartWithContainer() {
-		return startWithContainer;
-	}
-
-	public void setStartWithContainer(boolean startWithContainer) {
-		this.startWithContainer = startWithContainer;
-	}
-	
+package cn.com.qmth.examcloud.task.base;
+
+import java.io.Serializable;
+
+/**
+ * 任务配置
+ *
+ * @author WANGWEI
+ * @date 2018年3月7日
+ * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
+ */
+public class ScheduleJob implements Serializable {
+	private static final long serialVersionUID = -1638993747996917970L;
+
+	/**
+	 * 任务名称
+	 */
+	private String jobName;
+
+	/**
+	 * 任务分组
+	 */
+	private String jobGroup;
+
+	/**
+	 * 任务状态
+	 */
+	private String jobStatus;
+
+	/**
+	 * cron表达式
+	 */
+	private String cronExpression;
+
+	/**
+	 * 描述
+	 */
+	private String description;
+
+	/**
+	 * Spring bean
+	 */
+	private String springBean;
+
+	/**
+	 * 是否顺序执行
+	 */
+	private boolean stateful = true;
+
+	public String getJobName() {
+		return jobName;
+	}
+
+	public void setJobName(String jobName) {
+		this.jobName = jobName;
+	}
+
+	public String getJobGroup() {
+		return jobGroup;
+	}
+
+	public void setJobGroup(String jobGroup) {
+		this.jobGroup = jobGroup;
+	}
+
+	public String getJobStatus() {
+		return jobStatus;
+	}
+
+	public void setJobStatus(String jobStatus) {
+		this.jobStatus = jobStatus;
+	}
+
+	public String getCronExpression() {
+		return cronExpression;
+	}
+
+	public void setCronExpression(String cronExpression) {
+		this.cronExpression = cronExpression;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getSpringBean() {
+		return springBean;
+	}
+
+	public void setSpringBean(String springBean) {
+		this.springBean = springBean;
+	}
+
+	public boolean isStateful() {
+		return stateful;
+	}
+
+	public void setStateful(boolean stateful) {
+		this.stateful = stateful;
+	}
+
 }

+ 18 - 18
examcloud-task-base/src/main/java/cn/com/qmth/task/base/StatefulDistributionJob.java → examcloud-task-base/src/main/java/cn/com/qmth/examcloud/task/base/StatefulDistributionJob.java

@@ -1,18 +1,18 @@
-package cn.com.qmth.task.base;
-
-import org.quartz.DisallowConcurrentExecution;
-import org.quartz.PersistJobDataAfterExecution;
-
-/**
- * 顺序执行任务分发器
- *
- * @author WANGWEI
- * @date 2018年3月7日
- * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
- */
-@DisallowConcurrentExecution
-@PersistJobDataAfterExecution
-public class StatefulDistributionJob extends DistributionJob
-{
-
-}
+package cn.com.qmth.examcloud.task.base;
+
+import org.quartz.DisallowConcurrentExecution;
+import org.quartz.PersistJobDataAfterExecution;
+
+/**
+ * 顺序执行任务分发器
+ *
+ * @author WANGWEI
+ * @date 2018年3月7日
+ * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
+ */
+@DisallowConcurrentExecution
+@PersistJobDataAfterExecution
+public class StatefulDistributionJob extends DistributionJob
+{
+
+}

+ 18 - 18
examcloud-task-base/src/main/java/cn/com/qmth/task/base/Task.java → examcloud-task-base/src/main/java/cn/com/qmth/examcloud/task/base/Task.java

@@ -1,18 +1,18 @@
-package cn.com.qmth.task.base;
-
-/**
- * 任务接口
- *
- * @author WANGWEI
- * @date 2018年3月7日
- * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
- */
-public interface Task
-{
-	/**
-	 * 执行任务
-	 *
-	 * @author WANGWEI
-	 */
-	void execute(ScheduleJob scheduleJob);
-}
+package cn.com.qmth.examcloud.task.base;
+
+/**
+ * 任务接口
+ *
+ * @author WANGWEI
+ * @date 2018年3月7日
+ * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
+ */
+public interface Task
+{
+	/**
+	 * 执行任务
+	 *
+	 * @author WANGWEI
+	 */
+	void execute(ScheduleJob scheduleJob);
+}

+ 0 - 34
examcloud-task-base/src/main/java/cn/com/qmth/task/base/enums/JobStatus.java

@@ -1,34 +0,0 @@
-package cn.com.qmth.task.base.enums;
-
-/**
- * @author  	chenken
- * @date    	2018年7月11日 上午11:28:26
- * @company 	QMTH
- * @description JobStatus.java
- */
-public enum JobStatus {
-
-	RUNNING("运行中"),
-	
-	PAUSE("暂停"),
-	
-	RESUME("从暂停中恢复"),
-	
-	DELETE("已删除");
-	
-	private String name;
-	
-
-	private JobStatus(String name) {
-		this.name = name;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-	
-}

+ 17 - 16
examcloud-task-dao/src/main/java/cn/com/qmth/task/repository/ScheduleJobEntityRepo.java → examcloud-task-dao/src/main/java/cn/com/qmth/examcloud/task/dao/ScheduleJobRepo.java

@@ -1,16 +1,17 @@
-package cn.com.qmth.task.repository;
-
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-import org.springframework.stereotype.Repository;
-
-import cn.com.qmth.task.entity.ScheduleJobEntity;
-
-@Repository
-public interface ScheduleJobEntityRepo  extends JpaRepository<ScheduleJobEntity,Long>,
-												JpaSpecificationExecutor<ScheduleJobEntity>{
-
-	public ScheduleJobEntity findByJobName(String jobName);
-	
-}
-
+package cn.com.qmth.examcloud.task.dao;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+import cn.com.qmth.examcloud.task.dao.entity.ScheduleJobEntity;
+
+@Repository
+public interface ScheduleJobRepo
+		extends
+			JpaRepository<ScheduleJobEntity, Long>,
+			JpaSpecificationExecutor<ScheduleJobEntity> {
+
+	public ScheduleJobEntity findByJobName(String jobName);
+
+}

+ 15 - 0
examcloud-task-dao/src/main/java/cn/com/qmth/examcloud/task/dao/TaskExecutionRepo.java

@@ -0,0 +1,15 @@
+package cn.com.qmth.examcloud.task.dao;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+import cn.com.qmth.examcloud.task.dao.entity.ScheduleJobEntity;
+
+@Repository
+public interface TaskExecutionRepo
+		extends
+			JpaRepository<ScheduleJobEntity, Long>,
+			JpaSpecificationExecutor<ScheduleJobEntity> {
+
+}

+ 129 - 0
examcloud-task-dao/src/main/java/cn/com/qmth/examcloud/task/dao/entity/ScheduleJobEntity.java

@@ -0,0 +1,129 @@
+package cn.com.qmth.examcloud.task.dao.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
+
+import cn.com.qmth.examcloud.commons.web.jpa.JpaEntity;
+
+/**
+ * 任务配置
+ *
+ * @author WANGWEI
+ * @date 2018年3月7日
+ * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
+ */
+@Entity
+@Table(name = "EC_T_SCHEDULE_JOB")
+public class ScheduleJobEntity extends JpaEntity {
+	private static final long serialVersionUID = -1638993747996917970L;
+
+	@Id
+	@GeneratedValue
+	private Long id;
+
+	/**
+	 * 任务名称
+	 */
+	@Column(unique = true, nullable = false)
+	private String jobName;
+
+	/**
+	 * 任务分组
+	 */
+	@Column(unique = false, nullable = false)
+	private String jobGroup;
+
+	/**
+	 * cron表达式
+	 */
+	@NotNull
+	private String cronExpression;
+
+	/**
+	 * 描述
+	 */
+	private String description;
+
+	/**
+	 * Spring bean
+	 */
+	@NotNull
+	private String springBean;
+
+	/**
+	 * 是否顺序执行
+	 */
+	private Boolean stateful;
+
+	@NotNull
+	private Boolean enable;
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getJobName() {
+		return jobName;
+	}
+
+	public void setJobName(String jobName) {
+		this.jobName = jobName;
+	}
+
+	public String getJobGroup() {
+		return jobGroup;
+	}
+
+	public void setJobGroup(String jobGroup) {
+		this.jobGroup = jobGroup;
+	}
+
+	public String getCronExpression() {
+		return cronExpression;
+	}
+
+	public void setCronExpression(String cronExpression) {
+		this.cronExpression = cronExpression;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getSpringBean() {
+		return springBean;
+	}
+
+	public void setSpringBean(String springBean) {
+		this.springBean = springBean;
+	}
+
+	public Boolean getStateful() {
+		return stateful;
+	}
+
+	public void setStateful(Boolean stateful) {
+		this.stateful = stateful;
+	}
+
+	public Boolean getEnable() {
+		return enable;
+	}
+
+	public void setEnable(Boolean enable) {
+		this.enable = enable;
+	}
+
+}

+ 92 - 0
examcloud-task-dao/src/main/java/cn/com/qmth/examcloud/task/dao/entity/TaskExecutionEntity.java

@@ -0,0 +1,92 @@
+package cn.com.qmth.examcloud.task.dao.entity;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import cn.com.qmth.examcloud.commons.web.jpa.JpaEntity;
+
+/**
+ * 任务执行记录
+ *
+ * @author WANGWEI
+ * @date 2018年3月7日
+ * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
+ */
+@Entity
+@Table(name = "EC_T_TASK_EXECUTION")
+public class TaskExecutionEntity extends JpaEntity {
+
+	private static final long serialVersionUID = -1638993747996917970L;
+
+	@Id
+	@GeneratedValue
+	private Long id;
+
+	@Column(unique = false, nullable = false)
+	private Long jobId;
+
+	/**
+	 * 任务当前状态
+	 */
+	private String jobStatus;
+
+	private Date startTime;
+
+	private Date endTime;
+
+	private String exception;
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public Long getJobId() {
+		return jobId;
+	}
+
+	public void setJobId(Long jobId) {
+		this.jobId = jobId;
+	}
+
+	public String getJobStatus() {
+		return jobStatus;
+	}
+
+	public void setJobStatus(String jobStatus) {
+		this.jobStatus = jobStatus;
+	}
+
+	public Date getStartTime() {
+		return startTime;
+	}
+
+	public void setStartTime(Date startTime) {
+		this.startTime = startTime;
+	}
+
+	public Date getEndTime() {
+		return endTime;
+	}
+
+	public void setEndTime(Date endTime) {
+		this.endTime = endTime;
+	}
+
+	public String getException() {
+		return exception;
+	}
+
+	public void setException(String exception) {
+		this.exception = exception;
+	}
+
+}

+ 0 - 192
examcloud-task-dao/src/main/java/cn/com/qmth/task/entity/ScheduleJobEntity.java

@@ -1,192 +0,0 @@
-package cn.com.qmth.task.entity;
-
-import java.io.Serializable;
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
-import javax.validation.constraints.NotNull;
-
-/**
- * 任务配置
- *
- * @author WANGWEI
- * @date 2018年3月7日
- * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
- */
-@Table(name="ec_b_schedule_job",uniqueConstraints = {@UniqueConstraint(columnNames={"jobName"})})
-@Entity
-public class ScheduleJobEntity implements Serializable
-{
-	private static final long serialVersionUID = -1638993747996917970L;
-	
-	@Id
-	@GeneratedValue
-	private Long id;
-
-	/**
-	 * 任务名称
-	 */
-	@NotNull
-	private String jobName;
-
-	/**
-	 * 任务分组
-	 */
-	@NotNull
-	private String jobGroup;
-
-	/**
-	 * 任务当前状态
-	 */
-	private String jobStatus;
-
-	/**
-	 * cron表达式
-	 */
-	@NotNull
-	private String cronExpression;
-
-	/**
-	 * 描述
-	 */
-	private String description;
-
-	/**
-	 * Spring bean
-	 */
-	@NotNull
-	private String springBean;
-
-	/**
-	 * 是否顺序执行
-	 */
-	private Boolean stateful;
-	
-	/**
-	 * job操作时间
-	 */
-	private Date operateTime;
-
-	/**
-	 * job操作是否成功
-	 */
-	private String operateResult;
-	
-	/**
-	 * 随着容器启动而启动
-	 */
-	@Column(name="start_width_container")
-	private Boolean startWithContainer;
-	
-	public String getJobName()
-	{
-		return jobName;
-	}
-
-	public void setJobName(String jobName)
-	{
-		this.jobName = jobName;
-	}
-
-	public String getJobGroup()
-	{
-		return jobGroup;
-	}
-
-	public void setJobGroup(String jobGroup)
-	{
-		this.jobGroup = jobGroup;
-	}
-
-	public String getJobStatus()
-	{
-		return jobStatus;
-	}
-
-	public void setJobStatus(String jobStatus)
-	{
-		this.jobStatus = jobStatus;
-	}
-
-	public String getCronExpression()
-	{
-		return cronExpression;
-	}
-
-	public void setCronExpression(String cronExpression)
-	{
-		this.cronExpression = cronExpression;
-	}
-
-	public String getDescription()
-	{
-		return description;
-	}
-
-	public void setDescription(String description)
-	{
-		this.description = description;
-	}
-
-	public String getSpringBean()
-	{
-		return springBean;
-	}
-
-	public void setSpringBean(String springBean)
-	{
-		this.springBean = springBean;
-	}
-
-	public Boolean isStateful()
-	{
-		return stateful;
-	}
-
-	public void setStateful(Boolean stateful)
-	{
-		this.stateful = stateful;
-	}
-
-	public Long getId() {
-		return id;
-	}
-
-	public void setId(Long id) {
-		this.id = id;
-	}
-
-	public Date getOperateTime() {
-		return operateTime;
-	}
-
-	public void setOperateTime(Date operateTime) {
-		this.operateTime = operateTime;
-	}
-
-	public String getOperateResult() {
-		return operateResult;
-	}
-
-	public void setOperateResult(String operateResult) {
-		this.operateResult = operateResult;
-	}
-
-	public Boolean getStartWithContainer() {
-		return startWithContainer;
-	}
-
-	public void setStartWithContainer(Boolean startWithContainer) {
-		this.startWithContainer = startWithContainer;
-	}
-
-	public Boolean getStateful() {
-		return stateful;
-	}
-	
-}

+ 29 - 0
examcloud-task-service/src/main/java/cn/com/qmth/examcloud/task/service/job/OeCleanExamRecordTask.java

@@ -0,0 +1,29 @@
+package cn.com.qmth.examcloud.task.service.job;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
+import cn.com.qmth.examcloud.core.oe.api.CleanExamRecordService;
+import cn.com.qmth.examcloud.task.base.AbstractTask;
+import cn.com.qmth.examcloud.task.base.ScheduleJob;
+
+/**
+ * 
+ * @author chenken
+ * @date 2018年7月11日 上午11:02:50
+ * @company QMTH
+ * @description 网考考试记录清理job
+ */
+@Component("oeCleanExamRecordTask")
+public class OeCleanExamRecordTask extends AbstractTask {
+
+	@Autowired
+	@Qualifier("cleanExamRecordClient")
+	private CleanExamRecordService cleanExamRecordService;
+
+	@Override
+	public void run(ScheduleJob scheduleJob) {
+		cleanExamRecordService.cleanExamExpiredExamRecord();
+	}
+}

+ 0 - 24
examcloud-task-service/src/main/java/cn/com/qmth/task/service/ScheduleJobEntityService.java

@@ -1,24 +0,0 @@
-package cn.com.qmth.task.service;
-
-import java.util.List;
-
-import cn.com.qmth.task.base.ScheduleJob;
-import cn.com.qmth.task.entity.ScheduleJobEntity;
-
-
-public interface ScheduleJobEntityService {
-
-	public List<ScheduleJobEntity> findAll();
-	
-	
-	public void saveScheduleJobEntity(ScheduleJobEntity scheduleJobEntity);
-	
-	/**
-	 * 根据jobName查询
-	 * @param jobName
-	 * @return
-	 */
-	public ScheduleJobEntity findByJobName(String jobName);
-	
-	public ScheduleJob transformationToScheduleJob(ScheduleJobEntity scheduleJobEntity);
-}

+ 0 - 55
examcloud-task-service/src/main/java/cn/com/qmth/task/service/impl/ScheduleJobEntityServiceImpl.java

@@ -1,55 +0,0 @@
-package cn.com.qmth.task.service.impl;
-
-import java.util.Date;
-import java.util.List;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import cn.com.qmth.task.base.ScheduleJob;
-import cn.com.qmth.task.entity.ScheduleJobEntity;
-import cn.com.qmth.task.repository.ScheduleJobEntityRepo;
-import cn.com.qmth.task.service.ScheduleJobEntityService;
-
-@Service("scheduleJobEntityService")
-public class ScheduleJobEntityServiceImpl implements ScheduleJobEntityService{
-	
-	@Autowired
-	private ScheduleJobEntityRepo scheduleJobEntityRepo;
-
-	@Override
-	public List<ScheduleJobEntity> findAll() {
-		return scheduleJobEntityRepo.findAll();
-	}
-
-	@Override
-	public void saveScheduleJobEntity(ScheduleJobEntity scheduleJobEntity) {
-		scheduleJobEntity.setOperateTime(new Date());
-		scheduleJobEntityRepo.save(scheduleJobEntity);
-	}
-
-	@Override
-	public ScheduleJobEntity findByJobName(String jobName) {
-		if(StringUtils.isBlank(jobName)){
-			return null;
-		}
-		return scheduleJobEntityRepo.findByJobName(jobName);
-	}
-
-	@Override
-	public ScheduleJob transformationToScheduleJob(ScheduleJobEntity scheduleJobEntity) {
-		if(scheduleJobEntity==null){
-			return null;
-		}
-		ScheduleJob scheduleJob = new ScheduleJob();
-		scheduleJob.setJobName(scheduleJobEntity.getJobName());
-		scheduleJob.setJobGroup(scheduleJobEntity.getJobGroup());
-		scheduleJob.setSpringBean(scheduleJobEntity.getSpringBean());
-		scheduleJob.setCronExpression(scheduleJobEntity.getCronExpression());
-		Boolean startWithContainer = scheduleJobEntity.getStartWithContainer();
-		scheduleJob.setStartWithContainer(startWithContainer==null?false:startWithContainer);
-		return scheduleJob;
-	}
-
-}

+ 0 - 33
examcloud-task-service/src/main/java/cn/com/qmth/task/service/job/JobsInitialization.java

@@ -1,33 +0,0 @@
-package cn.com.qmth.task.service.job;
-
-import java.util.List;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import cn.com.qmth.task.base.QuartzManager;
-import cn.com.qmth.task.base.ScheduleJob;
-import cn.com.qmth.task.entity.ScheduleJobEntity;
-import cn.com.qmth.task.service.ScheduleJobEntityService;
-
-@Component
-public class JobsInitialization implements Runnable{
-
-	@Autowired
-	private ScheduleJobEntityService scheduleJobEntityService;
-	
-	@Autowired
-	private QuartzManager quartzManager;
-
-	@Override
-	public void run() {
-		List<ScheduleJobEntity> scheduleJobEntitys = scheduleJobEntityService.findAll();
-    	for(ScheduleJobEntity scheduleJobEntity:scheduleJobEntitys){
-			ScheduleJob scheduleJob = scheduleJobEntityService.transformationToScheduleJob(scheduleJobEntity);
-			if(scheduleJob.isStartWithContainer()){
-				quartzManager.addJob(scheduleJob);
-			}
-    	}
-	} 
-	
-}

+ 0 - 54
examcloud-task-service/src/main/java/cn/com/qmth/task/service/job/OeCleanExamRecordTask.java

@@ -1,54 +0,0 @@
-package cn.com.qmth.task.service.job;
-
-import java.util.Date;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Component;
-
-import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
-import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
-import cn.com.qmth.examcloud.commons.base.util.DateFormat;
-import cn.com.qmth.examcloud.core.oe.api.CleanExamRecordService;
-import cn.com.qmth.task.base.AbstractTask;
-import cn.com.qmth.task.base.ScheduleJob;
-import cn.com.qmth.task.base.enums.JobStatus;
-import cn.com.qmth.task.entity.ScheduleJobEntity;
-import cn.com.qmth.task.service.ScheduleJobEntityService;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年7月11日 上午11:02:50
- * @company 	QMTH
- * @description 网考考试记录清理job
- */
-@Component("oeCleanExamRecordTask")
-public class OeCleanExamRecordTask extends AbstractTask{
-	
-	private static final ExamCloudLog LOG = ExamCloudLogFactory.getLog("EXAMCLOUD_TASK");
-	
-	@Autowired
-	@Qualifier("cleanExamRecordClient")
-	private CleanExamRecordService cleanExamRecordService;
-	
-	@Autowired
-	private ScheduleJobEntityService scheduleJobEntityService;
-	
-	@Override
-	public void run(ScheduleJob scheduleJob){
-		LOG.info(DateFormat.dateFormat(new Date())+"oeCleanExamRecordTask Run");
-		ScheduleJobEntity scheduleJobEntity = scheduleJobEntityService.findByJobName(scheduleJob.getJobName());
-		try{
-			cleanExamRecordService.cleanExamExpiredExamRecord();
-			scheduleJobEntity.setOperateResult("EXECUTE SUCCESS");
-			scheduleJobEntity.setJobStatus(JobStatus.RUNNING.name());
-			scheduleJobEntityService.saveScheduleJobEntity(scheduleJobEntity);
-		}catch(Exception e){
-			scheduleJobEntity.setOperateResult("EXECUTE FAILED");
-			scheduleJobEntityService.saveScheduleJobEntity(scheduleJobEntity);
-			e.printStackTrace();
-		}
-		
-	}
-}

+ 0 - 0
examcloud-task-starter/.logs/interface/task.interface.log


+ 0 - 0
examcloud-task-starter/.logs/task/task.log


+ 16 - 0
examcloud-task-starter/.springBeans

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beansProjectDescription>
+	<version>1</version>
+	<pluginVersion><![CDATA[3.9.4.201804120850-RELEASE]]></pluginVersion>
+	<configSuffixes>
+		<configSuffix><![CDATA[xml]]></configSuffix>
+	</configSuffixes>
+	<enableImports><![CDATA[false]]></enableImports>
+	<configs>
+		<config>java:cn.com.qmth.examcloud.task.starter.TaskApp</config>
+	</configs>
+	<autoconfigs>
+	</autoconfigs>
+	<configSets>
+	</configSets>
+</beansProjectDescription>

+ 97 - 96
examcloud-task-starter/pom.xml

@@ -1,97 +1,98 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" 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">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>cn.com.qmth.examcloud.task</groupId>
-    <artifactId>examcloud-task</artifactId>
-    <version>2.0-SNAPSHOT</version>
-  </parent>
-  <artifactId>examcloud-task-starter</artifactId>
-  
-  <dependencies>
-		<dependency>
-			<groupId>cn.com.qmth.examcloud.task</groupId>
-			<artifactId>examcloud-task-api-provider</artifactId>
-			<version>${examcloud.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-test</artifactId>
-		</dependency>
-  </dependencies>
-   <!-- 打包成zip -->
-  	<build>
-		<plugins>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-jar-plugin</artifactId>
-				<configuration>
-					<archive>
-						<manifest>
-							<mainClass>cn.com.qmth.task.starter.TaskApplication</mainClass>
-							<addClasspath>true</addClasspath>
-							<classpathPrefix>./</classpathPrefix>
-						</manifest>
-						<manifestEntries>
-							<Class-Path>../config/</Class-Path>
-						</manifestEntries>
-					</archive>
-					<excludes>
-						<exclude>*.properties</exclude>
-						<exclude>*.xml </exclude>
-						<exclude>*.conf </exclude>
-					</excludes>
-				</configuration>
-			</plugin>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-assembly-plugin</artifactId>
-				<configuration>
-					<finalName>examcloud-task</finalName>
-					<descriptors>
-						<descriptor>assembly.xml</descriptor>
-					</descriptors>
-				</configuration>
-				<executions>
-					<execution>
-						<id>make-assembly</id>
-						<phase>install</phase>
-						<goals>
-							<goal>assembly</goal>
-						</goals>
-					</execution>
-				</executions>
-			</plugin>
-		</plugins>
-	</build>
-	<!-- 
-	打成jar包
-	<build>  
-		<finalName>examcloud-task</finalName>
-		<plugins>  
-		    <plugin>  
-		        <groupId>org.springframework.boot</groupId>  
-		        <artifactId>spring-boot-maven-plugin</artifactId>  
-		        <configuration>  
-                	<fork>true</fork>  
-                	<mainClass>cn.com.qmth.task.starter.TaskApplication</mainClass> 主类 包含main
-                	<layout>JAR</layout> -包类型(必须大写) JAR,WAR,ZIP,MODULE,NONE
-            	</configuration>
-            	<executions>
-					<execution>
-						<goals>
-							<goal>repackage</goal>
-						</goals>
-					</execution>
-				</executions>
-		    </plugin>  
-		    <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                </configuration>
-            </plugin>
-		</plugins>  
-	 </build>   -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" 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">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>cn.com.qmth.examcloud.task</groupId>
+    <artifactId>examcloud-task</artifactId>
+    <version>2.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>examcloud-task-starter</artifactId>
+  
+  <dependencies>
+		<dependency>
+			<groupId>cn.com.qmth.examcloud.task</groupId>
+			<artifactId>examcloud-task-api-provider</artifactId>
+			<version>${examcloud.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+		</dependency>
+  </dependencies>
+  
+	<!-- 打包成zip -->
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+				<configuration>
+					<archive>
+						<manifest>
+							<mainClass>cn.com.qmth.examcloud.task.starter.TaskApp</mainClass>
+							<addClasspath>true</addClasspath>
+							<classpathPrefix>./</classpathPrefix>
+						</manifest>
+						<manifestEntries>
+							<Class-Path>../config/</Class-Path>
+						</manifestEntries>
+					</archive>
+					<excludes>
+						<exclude>*.properties</exclude>
+						<exclude>*.xml </exclude>
+						<exclude>*.conf </exclude>
+					</excludes>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-assembly-plugin</artifactId>
+				<configuration>
+					<finalName>examcloud-task</finalName>
+					<descriptors>
+						<descriptor>assembly.xml</descriptor>
+					</descriptors>
+				</configuration>
+				<executions>
+					<execution>
+						<id>make-assembly</id>
+						<phase>install</phase>
+						<goals>
+							<goal>assembly</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+	<!-- 
+	打成jar包
+	<build>  
+		<finalName>examcloud-task</finalName>
+		<plugins>  
+		    <plugin>  
+		        <groupId>org.springframework.boot</groupId>  
+		        <artifactId>spring-boot-maven-plugin</artifactId>  
+		        <configuration>  
+                	<fork>true</fork>  
+                	<mainClass>cn.com.qmth.examcloud.task.starter.TaskApp</mainClass> 主类 包含main
+                	<layout>JAR</layout> -包类型(必须大写) JAR,WAR,ZIP,MODULE,NONE
+            	</configuration>
+            	<executions>
+					<execution>
+						<goals>
+							<goal>repackage</goal>
+						</goals>
+					</execution>
+				</executions>
+		    </plugin>  
+		    <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+		</plugins>  
+	 </build>   -->
 </project>

+ 91 - 0
examcloud-task-starter/src/main/java/cn/com/qmth/examcloud/task/starter/TaskApp.java

@@ -0,0 +1,91 @@
+package cn.com.qmth.examcloud.task.starter;
+
+import org.slf4j.MDC;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.cloud.client.loadbalancer.LoadBalanced;
+import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+import org.springframework.web.client.RestTemplate;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
+import cn.com.qmth.examcloud.commons.base.logging.SLF4JImpl;
+import cn.com.qmth.examcloud.commons.web.redis.RedisClient;
+import cn.com.qmth.examcloud.commons.web.redis.RedisClientImpl;
+import cn.com.qmth.examcloud.commons.web.support.CustomResponseErrorHandler;
+import cn.com.qmth.examcloud.task.starter.config.JobsInitializationListener;
+
+@SpringBootApplication(scanBasePackages = {"cn.com.qmth"})
+@EnableJpaRepositories(basePackages = {"cn.com.qmth"})
+@EntityScan(basePackages = {"cn.com.qmth"})
+@EnableJpaAuditing
+@EnableEurekaClient
+@EnableScheduling
+@EnableAutoConfiguration
+public class TaskApp {
+
+	private static final ExamCloudLog LOG = ExamCloudLogFactory.getLog(TaskApp.class);
+
+	public static void main(String[] args) throws Exception {
+		if (LOG instanceof SLF4JImpl) {
+			MDC.put("TRACE_ID", Thread.currentThread().getName());
+		}
+
+		SpringApplication application = new SpringApplication(TaskApp.class);
+		application.addListeners(new JobsInitializationListener());
+		application.run(args);
+	}
+
+	@Bean
+	@LoadBalanced
+	public RestTemplate restTemplate() {
+		RestTemplate restTemplate = new RestTemplate();
+		restTemplate.setErrorHandler(new CustomResponseErrorHandler());
+		return restTemplate;
+	}
+
+	@Bean
+	public RedisTemplate<String, Object> redisTemplate(
+			RedisConnectionFactory redisConnectionFactory) {
+		RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
+		redisTemplate.setConnectionFactory(redisConnectionFactory);
+		Jackson2JsonRedisSerializer<?> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(
+				Object.class);
+		ObjectMapper objectMapper = new ObjectMapper();
+		objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+		objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+		jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
+		redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
+		redisTemplate.setKeySerializer(new StringRedisSerializer());
+		redisTemplate.afterPropertiesSet();
+		return redisTemplate;
+	}
+
+	@Bean
+	@Autowired
+	public RedisClient redisClient(RedisTemplate<String, Object> redisTemplate) {
+		return new RedisClientImpl(redisTemplate);
+	}
+
+	@Bean(name = "schedulerFactoryBean")
+	public SchedulerFactoryBean schedulerFactory() {
+		return new SchedulerFactoryBean();
+	}
+
+}

+ 83 - 0
examcloud-task-starter/src/main/java/cn/com/qmth/examcloud/task/starter/config/DefaultWebMvcConfigurerAdapter.java

@@ -0,0 +1,83 @@
+package cn.com.qmth.examcloud.task.starter.config;
+
+import java.util.List;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+import cn.com.qmth.examcloud.commons.base.util.PathUtil;
+import cn.com.qmth.examcloud.commons.base.util.PropertiesUtil;
+import cn.com.qmth.examcloud.commons.web.interceptor.FirstInterceptor;
+import cn.com.qmth.examcloud.commons.web.redis.RedisClient;
+import cn.com.qmth.examcloud.commons.web.security.RequestPermissionInterceptor;
+import cn.com.qmth.examcloud.commons.web.security.SpringCloudInterceptor;
+import cn.com.qmth.examcloud.commons.web.security.bean.Role;
+import cn.com.qmth.examcloud.commons.web.security.bean.User;
+
+/**
+ * 默认WebMvcConfigurer
+ *
+ * @author WANGWEI
+ * @date 2018年5月22日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+@Configuration
+public class DefaultWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
+
+	@Autowired
+	RedisClient redisClient;
+
+	static {
+		PropertiesUtil.configureAndWatch(PathUtil.getResoucePath("security-mapping.properties"));
+	}
+
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+		registry.addInterceptor(new FirstInterceptor()).addPathPatterns("/**");
+
+		SpringCloudInterceptor springCloudInterceptor = new SpringCloudInterceptor();
+		springCloudInterceptor.setRedisClient(redisClient);
+		registry.addInterceptor(springCloudInterceptor).addPathPatterns("/**");
+
+		RequestPermissionInterceptor requestPermissionInterceptor = getRequestPermissionInterceptor();
+		requestPermissionInterceptor.configureAndWatch("security-exclusions.conf");
+		registry.addInterceptor(requestPermissionInterceptor).addPathPatterns("/**");
+
+		super.addInterceptors(registry);
+	}
+
+	@Bean
+	public RequestPermissionInterceptor getRequestPermissionInterceptor() {
+		return new RequestPermissionInterceptor(redisClient) {
+
+			@Override
+			public boolean hasPermission(String mappingPath, User user) {
+				List<Role> roleList = user.getRoleList();
+				if (CollectionUtils.isEmpty(roleList)) {
+					return false;
+				}
+
+				String roles = PropertiesUtil.getString(mappingPath);
+				if (StringUtils.isBlank(roles)) {
+					return true;
+				}
+
+				roles = "," + roles + ",";
+
+				for (Role role : roleList) {
+					if (roles.contains("," + role.getRoleCode() + ",")) {
+						return true;
+					}
+				}
+
+				return false;
+			}
+
+		};
+	}
+}

+ 40 - 0
examcloud-task-starter/src/main/java/cn/com/qmth/examcloud/task/starter/config/JobsInitialization.java

@@ -0,0 +1,40 @@
+package cn.com.qmth.examcloud.task.starter.config;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import cn.com.qmth.examcloud.task.base.QuartzManager;
+import cn.com.qmth.examcloud.task.base.ScheduleJob;
+import cn.com.qmth.examcloud.task.dao.ScheduleJobRepo;
+import cn.com.qmth.examcloud.task.dao.entity.ScheduleJobEntity;
+
+@Component
+public class JobsInitialization {
+
+	@Autowired
+	private ScheduleJobRepo scheduleJobEntityRepo;
+
+	@Autowired
+	private QuartzManager quartzManager;
+
+	public void init() {
+		List<ScheduleJobEntity> jobEntityList = scheduleJobEntityRepo.findAll();
+
+		for (ScheduleJobEntity jobEntity : jobEntityList) {
+			if (jobEntity.getEnable()) {
+				continue;
+			}
+			ScheduleJob scheduleJob = new ScheduleJob();
+			scheduleJob.setJobName(jobEntity.getJobName());
+			scheduleJob.setJobGroup(jobEntity.getJobGroup());
+			scheduleJob.setSpringBean(jobEntity.getSpringBean());
+			scheduleJob.setCronExpression(jobEntity.getCronExpression());
+			scheduleJob.setStateful(jobEntity.getStateful());
+			quartzManager.addJob(scheduleJob);
+		}
+
+	}
+
+}

+ 23 - 0
examcloud-task-starter/src/main/java/cn/com/qmth/examcloud/task/starter/config/JobsInitializationListener.java

@@ -0,0 +1,23 @@
+package cn.com.qmth.examcloud.task.starter.config;
+
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
+import cn.com.qmth.examcloud.task.starter.TaskApp;
+
+public class JobsInitializationListener implements ApplicationListener<ContextRefreshedEvent> {
+
+	private static final ExamCloudLog LOG = ExamCloudLogFactory.getLog(TaskApp.class);
+
+	@Override
+	public void onApplicationEvent(ContextRefreshedEvent event) {
+		LOG.info("start to init jobs...");
+		JobsInitialization jobsInitialization = event.getApplicationContext()
+				.getBean(JobsInitialization.class);
+		jobsInitialization.init();
+		LOG.info ("jobs inited.");
+	}
+
+}

+ 0 - 16
examcloud-task-starter/src/main/java/cn/com/qmth/task/starter/JobsInitializationListener.java

@@ -1,16 +0,0 @@
-package cn.com.qmth.task.starter;
-
-import org.springframework.context.ApplicationListener;
-import org.springframework.context.event.ContextRefreshedEvent;
-
-import cn.com.qmth.task.service.job.JobsInitialization;
-
-public class JobsInitializationListener implements ApplicationListener<ContextRefreshedEvent> {
-
-	@Override
-	public void onApplicationEvent(ContextRefreshedEvent event) {
-    	Thread thread = new Thread(event.getApplicationContext().getBean(JobsInitialization.class));
-    	thread.start();
-	}
-
-}

+ 0 - 40
examcloud-task-starter/src/main/java/cn/com/qmth/task/starter/TaskApplication.java

@@ -1,40 +0,0 @@
-package cn.com.qmth.task.starter;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.domain.EntityScan;
-import org.springframework.cloud.client.loadbalancer.LoadBalanced;
-import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
-import org.springframework.context.annotation.Bean;
-import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
-import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.scheduling.quartz.SchedulerFactoryBean;
-import org.springframework.web.client.RestTemplate;
-
-@SpringBootApplication(scanBasePackages = {"cn.com.qmth"})
-@EnableJpaRepositories(basePackages = {"cn.com.qmth"})
-@EntityScan(basePackages = {"cn.com.qmth"})
-@EnableEurekaClient
-@EnableScheduling
-@EnableAutoConfiguration
-public class TaskApplication {
-
-    public static void main(String[] args) throws Exception {
-    	SpringApplication application = new SpringApplication(TaskApplication.class);
-    	application.addListeners(new JobsInitializationListener());
-    	application.run(args);
-    }
-    
-    @Bean
-	@LoadBalanced
-	public RestTemplate restTemplate() {
-		return new RestTemplate();
-	}
-    
-    @Bean(name = "schedulerFactoryBean")
-    public SchedulerFactoryBean schedulerFactory() {
-        return new SchedulerFactoryBean();
-	}
-    
-}

+ 8 - 8
examcloud-task-starter/src/main/resources/application-dev.properties

@@ -1,8 +1,8 @@
-spring.datasource.url=jdbc:mysql://192.168.10.30:3306/exam_cloud_test?useUnicode=true&characterEncoding=UTF-8
-spring.datasource.username=root
-spring.datasource.password=root
-spring.datasource.validation-query=SELECT 1 FROM DUAL
-spring.datasource.test-on-borrow=true
-
-
-eureka.client.serviceUrl.defaultZone=http://192.168.10.30:1111/eureka/
+spring.datasource.url=jdbc:mysql://db-host:3306/exam_cloud_test?useUnicode=true&characterEncoding=UTF-8&useSSL=false
+spring.datasource.username=root
+spring.datasource.password=root
+
+spring.redis.host=192.168.10.30
+spring.redis.port=6379
+
+eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

+ 27 - 30
examcloud-task-starter/src/main/resources/application.properties

@@ -1,30 +1,27 @@
-spring.profiles.active=dev
-spring.datasource.url=jdbc:mysql://192.168.10.30:3306/exam_cloud_test?useUnicode=true&characterEncoding=UTF-8
-spring.datasource.username=root
-spring.datasource.password=root
-spring.datasource.validation-query=SELECT 1 FROM DUAL
-spring.datasource.test-on-borrow=true
-
-spring.http.multipart.max-file-size=50Mb
-spring.http.multipart.max-request-size=50Mb
-
-spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
-spring.jackson.time-zone=GMT+8
-
-spring.jpa.show-sql=true
-spring.jpa.hibernate.ddl-auto=update
-app.oe.examcontrol.session.expire=30
-app.oe.examcontrol.session.captureCycle=300
-
-#springcloud
-spring.application.name=EXAMCLOUD-SERVICE-TASK
-server.port=8011
-
-eureka.client.serviceUrl.defaultZone=http://192.168.10.30:1111/eureka/
-hystrix.command.default.execution.timeout.enabled=false
-hystrix.threadpool.default.coreSize = 500
-
-feign.httpclient.enabled=false
-feign.okhttp.enabled=true
-
-app.api.task=/api/task
+spring.profiles.active=dev
+spring.application.name=EXAMCLOUD-TASK
+server.port=8011
+
+$rmp.ctr.task=/api/ctr/task/
+$rmp.cloud.task=/api/cloud/task/
+
+spring.datasource.validation-query=SELECT 1 FROM DUAL
+spring.datasource.test-on-borrow=true
+
+spring.http.multipart.max-file-size=50Mb
+spring.http.multipart.max-request-size=50Mb
+
+spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
+spring.jackson.time-zone=GMT+8
+
+spring.jpa.show-sql=true
+spring.jpa.hibernate.ddl-auto=update
+app.oe.examcontrol.session.expire=30
+app.oe.examcontrol.session.captureCycle=300
+
+hystrix.command.default.execution.timeout.enabled=false
+hystrix.threadpool.default.coreSize = 500
+
+feign.httpclient.enabled=false
+feign.okhttp.enabled=true
+

+ 77 - 76
examcloud-task-starter/src/main/resources/logback-spring.xml

@@ -1,77 +1,78 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration debug="true" scan="true" scanPeriod="30 seconds">
-
-	<springProperty scope="context" name="logdir" source="logback.logdir"/>
-	
-	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-		<encoder>
-			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %level | %X{TRACE_ID} - %X{KEY} | %m | [%class:%line]%n</pattern>
-		</encoder>
-	</appender>
-
-	<!-- debug 日志 -->
-	<appender name="DEBUG_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
-		<file>log/debug.log</file><!-- 路径是在当前jar 包路径+/log/debug.log -->
-		<encoder>
-			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %level | %X{TRACE_ID} - %X{KEY} | %m | [%class:%line]%n</pattern>
-		</encoder>
-		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-			<fileNamePattern>log/debug.log.%d{yyyy-MM-dd}.%i.zip</fileNamePattern>
-			<maxHistory>100</maxHistory>
-			<maxFileSize>100MB</maxFileSize>
-		</rollingPolicy>
-	</appender>
-
-	<!-- 接口日志 -->
-	<appender name="INTERFACE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
-		<file>log/interface.log</file>
-		<encoder>
-			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %level | %X{TRACE_ID} - %X{KEY} | %m%n</pattern>
-		</encoder>
-		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-			<fileNamePattern>log/interface.log.%d{yyyy-MM-dd}.%i.zip</fileNamePattern>
-			<maxHistory>100</maxHistory>
-			<maxFileSize>100MB</maxFileSize>
-		</rollingPolicy>
-	</appender>
-	<!-- 任务日志 -->
-	<appender name="EXAMCLOUD_TASK_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
-		<file>log/task.log</file>
-		<encoder>
-			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %level | %X{TRACE_ID} - %X{KEY} | %m%n</pattern>
-		</encoder>
-		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
-			<fileNamePattern>log/task.log.%d{yyyy-MM-dd}.%i.zip</fileNamePattern>
-			<maxHistory>100</maxHistory>
-			<maxFileSize>100MB</maxFileSize>
-		</rollingPolicy>
-	</appender>
-
-	<logger name="cn.com.qmth.examcloud" level="DEBUG" additivity="false">
-		<appender-ref ref="DEBUG_APPENDER" />
-		<appender-ref ref="STDOUT" />
-	</logger>
-
-	<logger name="INTERFACE_LOGGER" level="DEBUG" additivity="false">
-		<appender-ref ref="INTERFACE_APPENDER" />
-		<appender-ref ref="STDOUT" />
-	</logger>
-	
-	<logger name="EXAMCLOUD_TASK" level="DEBUG" additivity="false">
-		<appender-ref ref="EXAMCLOUD_TASK_APPENDER" />
-		<appender-ref ref="STDOUT" />
-	</logger>
-
-	<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" />
-	<logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />
-	<logger name="org.hibernate.SQL" level="DEBUG" />
-	<logger name="org.hibernate.type" level="DEBUG" />
-	<logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
-	<logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />
-
-	<root level="INFO">
-		<appender-ref ref="DEBUG_APPENDER" />
-		<appender-ref ref="STDOUT" />
-	</root>
-
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="true" scan="true" scanPeriod="30 seconds">
+
+	<springProperty scope="context" name="logdir" source="logback.logdir" />
+
+	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %level | %X{TRACE_ID} - %X{KEY} | %m | [%class:%line]%n</pattern>
+		</encoder>
+	</appender>
+
+	<!-- debug 日志 -->
+	<appender name="DEBUG_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>./logs/debug/task.debug.log</file>
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %level | %X{TRACE_ID} - %X{KEY} | %m | [%class:%line]%n</pattern>
+		</encoder>
+		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+			<fileNamePattern>./logs/debug/task.debug.log.%d{yyyy-MM-dd}.%i.zip</fileNamePattern>
+			<maxHistory>100</maxHistory>
+			<maxFileSize>100MB</maxFileSize>
+		</rollingPolicy>
+	</appender>
+
+	<!-- 接口日志 -->
+	<appender name="INTERFACE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>.logs/interface/task.interface.log</file>
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %level | %X{TRACE_ID} - %X{KEY} | %m%n</pattern>
+		</encoder>
+		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+			<fileNamePattern>.logs/interface/task.interface.%d{yyyy-MM-dd}.%i.zip</fileNamePattern>
+			<maxHistory>100</maxHistory>
+			<maxFileSize>100MB</maxFileSize>
+		</rollingPolicy>
+	</appender>
+
+	<!-- 任务日志 -->
+	<appender name="TASK_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>.logs/task/task.log</file>
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}| %level | %X{TRACE_ID} - %X{KEY} | %m%n</pattern>
+		</encoder>
+		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+			<fileNamePattern>.logs/task/task.%d{yyyy-MM-dd}.%i.zip</fileNamePattern>
+			<maxHistory>100</maxHistory>
+			<maxFileSize>100MB</maxFileSize>
+		</rollingPolicy>
+	</appender>
+
+	<logger name="cn.com.qmth.examcloud" level="DEBUG" additivity="false">
+		<appender-ref ref="DEBUG_APPENDER" />
+		<appender-ref ref="STDOUT" />
+	</logger>
+
+	<logger name="INTERFACE_LOGGER" level="DEBUG" additivity="false">
+		<appender-ref ref="INTERFACE_APPENDER" />
+		<appender-ref ref="STDOUT" />
+	</logger>
+
+	<logger name="TASK_LOGGER" level="DEBUG" additivity="false">
+		<appender-ref ref="TASK_APPENDER" />
+		<appender-ref ref="STDOUT" />
+	</logger>
+
+	<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" />
+	<logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />
+	<logger name="org.hibernate.SQL" level="DEBUG" />
+	<logger name="org.hibernate.type" level="DEBUG" />
+	<logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
+	<logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />
+
+	<root level="INFO">
+		<appender-ref ref="DEBUG_APPENDER" />
+		<appender-ref ref="STDOUT" />
+	</root>
+
 </configuration>

+ 3 - 0
examcloud-task-starter/src/main/resources/security-exclusions.conf

@@ -0,0 +1,3 @@
+
+
+

+ 1 - 0
examcloud-task-starter/src/main/resources/security-mapping.properties

@@ -0,0 +1 @@
+

+ 31 - 31
examcloud-task-starter/src/test/java/cn/com/qmth/task/TestTaskSchedule.java

@@ -1,31 +1,31 @@
-package cn.com.qmth.task;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import cn.com.qmth.task.base.QuartzManager;
-import cn.com.qmth.task.base.ScheduleJob;
-
-
-@RunWith(SpringRunner.class)
-@SpringBootTest(classes={cn.com.qmth.task.starter.TaskApplication.class})
-public class TestTaskSchedule {
-
-	@Autowired
-	private QuartzManager quartzManager;
-	
-	@Test
-	public void executeTaskTest(){
-		ScheduleJob scheduleJob = new ScheduleJob();
-		scheduleJob.setJobName("clean exam");
-		scheduleJob.setJobGroup("OE");
-		scheduleJob.setSpringBean("oeCleanExamRecordTask");
-		scheduleJob.setCronExpression("0/10 * * * * ?");
-		scheduleJob.setStateful(true);
-		quartzManager.addJob(scheduleJob);
-	}
-	
-}
+package cn.com.qmth.task;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import cn.com.qmth.examcloud.task.base.QuartzManager;
+import cn.com.qmth.examcloud.task.base.ScheduleJob;
+
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes={cn.com.qmth.examcloud.task.starter.TaskApp.class})
+public class TestTaskSchedule {
+
+	@Autowired
+	private QuartzManager quartzManager;
+	
+	@Test
+	public void executeTaskTest(){
+		ScheduleJob scheduleJob = new ScheduleJob();
+		scheduleJob.setJobName("clean exam");
+		scheduleJob.setJobGroup("OE");
+		scheduleJob.setSpringBean("oeCleanExamRecordTask");
+		scheduleJob.setCronExpression("0/10 * * * * ?");
+		scheduleJob.setStateful(true);
+		quartzManager.addJob(scheduleJob);
+	}
+	
+}

+ 27 - 30
examcloud-task-starter/target/classes/application.properties

@@ -1,30 +1,27 @@
-spring.profiles.active=dev
-spring.datasource.url=jdbc:mysql://192.168.10.30:3306/exam_cloud_test?useUnicode=true&characterEncoding=UTF-8
-spring.datasource.username=root
-spring.datasource.password=root
-spring.datasource.validation-query=SELECT 1 FROM DUAL
-spring.datasource.test-on-borrow=true
-
-spring.http.multipart.max-file-size=50Mb
-spring.http.multipart.max-request-size=50Mb
-
-spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
-spring.jackson.time-zone=GMT+8
-
-spring.jpa.show-sql=true
-spring.jpa.hibernate.ddl-auto=update
-app.oe.examcontrol.session.expire=30
-app.oe.examcontrol.session.captureCycle=300
-
-#springcloud
-spring.application.name=EXAMCLOUD-SERVICE-TASK
-server.port=8011
-
-eureka.client.serviceUrl.defaultZone=http://192.168.10.30:1111/eureka/
-hystrix.command.default.execution.timeout.enabled=false
-hystrix.threadpool.default.coreSize = 500
-
-feign.httpclient.enabled=false
-feign.okhttp.enabled=true
-
-app.api.task=/api/task
+spring.profiles.active=dev
+spring.application.name=EXAMCLOUD-TASK
+server.port=8011
+
+$rmp.ctr.task=/api/ctr/task/
+$rmp.cloud.task=/api/cloud/task/
+
+spring.datasource.validation-query=SELECT 1 FROM DUAL
+spring.datasource.test-on-borrow=true
+
+spring.http.multipart.max-file-size=50Mb
+spring.http.multipart.max-request-size=50Mb
+
+spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
+spring.jackson.time-zone=GMT+8
+
+spring.jpa.show-sql=true
+spring.jpa.hibernate.ddl-auto=update
+app.oe.examcontrol.session.expire=30
+app.oe.examcontrol.session.captureCycle=300
+
+hystrix.command.default.execution.timeout.enabled=false
+hystrix.threadpool.default.coreSize = 500
+
+feign.httpclient.enabled=false
+feign.okhttp.enabled=true
+