|
|
@@ -0,0 +1,186 @@
|
|
|
+package com.uas.report.controller.schedule.service.impl;
|
|
|
+
|
|
|
+import java.io.FileWriter;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Calendar;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
+import java.util.concurrent.ScheduledExecutorService;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+import org.apache.log4j.Logger;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.uas.report.controller.schedule.model.DailyTaskInformation;
|
|
|
+import com.uas.report.controller.schedule.model.DailyTaskLog;
|
|
|
+import com.uas.report.controller.schedule.service.DailyTaskService;
|
|
|
+import com.uas.report.core.exception.ReportException;
|
|
|
+import com.uas.report.util.PathUtils;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 管理定时任务
|
|
|
+ *
|
|
|
+ * @author sunyj
|
|
|
+ * @since 2016年12月12日 上午11:40:00
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class DailyTaskServiceImpl implements DailyTaskService {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 随容器启动时,普通成员变量的值会丢失,需要使用类域
|
|
|
+ */
|
|
|
+ private static List<DailyTaskInformation> dailyTaskInformations = new ArrayList<>();
|
|
|
+
|
|
|
+ private static ScheduledExecutorService scheduledExecutorService;
|
|
|
+
|
|
|
+ private Logger logger = Logger.getLogger(DailyTaskServiceImpl.class);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 一天的毫秒数
|
|
|
+ */
|
|
|
+ private static final long MILLISECONDS_OF_ONE_DAY = 24 * 60 * 60 * 1000;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void newDailyTask(DailyTaskInformation dailyTaskInformation) {
|
|
|
+ if (dailyTaskInformation == null || StringUtils.isEmpty(dailyTaskInformation.getTitle())
|
|
|
+ || dailyTaskInformation.getCommand() == null) {
|
|
|
+ throw new NullPointerException();
|
|
|
+ }
|
|
|
+ if (containsDailyTask(dailyTaskInformation)) {
|
|
|
+ throw new ReportException("任务已存在:" + dailyTaskInformation);
|
|
|
+ }
|
|
|
+ dailyTaskInformations.add(dailyTaskInformation);
|
|
|
+ stop();
|
|
|
+ start();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断定时任务是否已经存在
|
|
|
+ *
|
|
|
+ * @param dailyTaskInformation
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean containsDailyTask(DailyTaskInformation dailyTaskInformation) {
|
|
|
+ if (CollectionUtils.isEmpty(dailyTaskInformations)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ for (DailyTaskInformation d : dailyTaskInformations) {
|
|
|
+ if (dailyTaskInformation.equals(d)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 建立每天定时任务
|
|
|
+ *
|
|
|
+ * @param command
|
|
|
+ * 所执行的任务
|
|
|
+ * @param hour
|
|
|
+ * 执行时间中的小时
|
|
|
+ * @param minute
|
|
|
+ * 执行时间中的分钟
|
|
|
+ * @param second
|
|
|
+ * 执行时间中的秒
|
|
|
+ */
|
|
|
+ private void newDailyTask(Runnable command, int hour, int minute, int second) {
|
|
|
+ Calendar now = Calendar.getInstance();
|
|
|
+ now.setTime(new Date());
|
|
|
+ Calendar initialDelayCalendar = (Calendar) now.clone();
|
|
|
+ initialDelayCalendar.set(Calendar.HOUR_OF_DAY, hour);
|
|
|
+ initialDelayCalendar.set(Calendar.MINUTE, minute);
|
|
|
+ initialDelayCalendar.set(Calendar.SECOND, second);
|
|
|
+ if (initialDelayCalendar.before(now)) {
|
|
|
+ initialDelayCalendar.add(Calendar.DAY_OF_MONTH, 1);
|
|
|
+ }
|
|
|
+ scheduledExecutorService.scheduleAtFixedRate(command,
|
|
|
+ initialDelayCalendar.getTimeInMillis() - now.getTimeInMillis(), MILLISECONDS_OF_ONE_DAY,
|
|
|
+ TimeUnit.MILLISECONDS);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void saveLog(DailyTaskLog log) {
|
|
|
+ if (log == null) {
|
|
|
+ throw new NullPointerException();
|
|
|
+ }
|
|
|
+ FileWriter fileWriter = null;
|
|
|
+ try {
|
|
|
+ fileWriter = new FileWriter(PathUtils.getAppPath() + "daily-task-log.log", true);
|
|
|
+ fileWriter.write(JSONObject.toJSONString(log) + "\n");
|
|
|
+ fileWriter.flush();
|
|
|
+ logger.info("Saved task log:" + JSONObject.toJSONString(log) + "\n");
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ if (fileWriter != null) {
|
|
|
+ try {
|
|
|
+ fileWriter.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<DailyTaskInformation> allDailyTaskInformations() {
|
|
|
+ return dailyTaskInformations;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String start() {
|
|
|
+ String message = "";
|
|
|
+ if (!isStopped()) {
|
|
|
+ message = "已存在运行的定时任务";
|
|
|
+ logger.error(message);
|
|
|
+ return message;
|
|
|
+ }
|
|
|
+ if (!CollectionUtils.isEmpty(dailyTaskInformations)) {
|
|
|
+ // 线程数与任务数保持一致,这样保证任务间不会互相影响
|
|
|
+ scheduledExecutorService = Executors.newScheduledThreadPool(dailyTaskInformations.size());
|
|
|
+ for (DailyTaskInformation dailyTaskInformation : dailyTaskInformations) {
|
|
|
+ logger.info("New daily task: " + dailyTaskInformation);
|
|
|
+ newDailyTask(dailyTaskInformation.getCommand(), dailyTaskInformation.getHour(),
|
|
|
+ dailyTaskInformation.getMinute(), dailyTaskInformation.getSecond());
|
|
|
+ }
|
|
|
+ message = "已开启定时任务:" + dailyTaskInformations;
|
|
|
+ logger.info(message + "\n");
|
|
|
+ return message;
|
|
|
+ } else {
|
|
|
+ message = "定时任务为空";
|
|
|
+ logger.error(message + "\n");
|
|
|
+ return message;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String stop() {
|
|
|
+ String message = "";
|
|
|
+ if (isStopped()) {
|
|
|
+ message = "定时任务已经停止或者未开启过";
|
|
|
+ logger.error(message);
|
|
|
+ return message;
|
|
|
+ }
|
|
|
+ logger.info("Remove old daily tasks...");
|
|
|
+ scheduledExecutorService.shutdownNow();
|
|
|
+ message = "已关闭定时任务";
|
|
|
+ logger.info(message + "\n");
|
|
|
+ return message;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean isStopped() {
|
|
|
+ if (scheduledExecutorService == null) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return scheduledExecutorService.isShutdown() || scheduledExecutorService.isTerminated();
|
|
|
+ }
|
|
|
+
|
|
|
+}
|