1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.helper;
17
18 import java.util.HashMap;
19 import java.util.Map;
20
21 import org.apache.logging.log4j.LogManager;
22 import org.apache.logging.log4j.Logger;
23 import org.codelibs.core.lang.StringUtil;
24 import org.codelibs.core.timer.TimeoutManager;
25 import org.codelibs.core.timer.TimeoutTarget;
26 import org.codelibs.core.timer.TimeoutTask;
27 import org.codelibs.fess.Constants;
28 import org.codelibs.fess.es.config.exbhv.JobLogBhv;
29 import org.codelibs.fess.es.config.exbhv.ScheduledJobBhv;
30 import org.codelibs.fess.es.config.exentity.JobLog;
31 import org.codelibs.fess.es.config.exentity.ScheduledJob;
32 import org.codelibs.fess.exception.ScheduledJobException;
33 import org.codelibs.fess.mylasta.direction.FessConfig;
34 import org.codelibs.fess.util.ComponentUtil;
35 import org.dbflute.optional.OptionalThing;
36 import org.lastaflute.job.JobManager;
37 import org.lastaflute.job.LaCron;
38 import org.lastaflute.job.LaJobRuntime;
39 import org.lastaflute.job.LaScheduledJob;
40 import org.lastaflute.job.key.LaJobUnique;
41 import org.lastaflute.job.subsidiary.CronParamsSupplier;
42
43 public class JobHelper {
44 private static final Logger logger = LogManager.getLogger(JobHelper.class);
45
46 protected int monitorInterval = 60 * 60;
47
48 protected ThreadLocal<LaJobRuntime> jobRuntimeLocal = new ThreadLocal<>();
49
50 public void register(final ScheduledJob scheduledJob) {
51 final JobManager jobManager = ComponentUtil.getJobManager();
52 jobManager.schedule(cron -> register(cron, scheduledJob));
53 }
54
55 public void register(final LaCron cron, final ScheduledJob scheduledJob) {
56 if (scheduledJob == null) {
57 throw new ScheduledJobException("No job.");
58 }
59
60 final String id = scheduledJob.getId();
61 if (!Constants.T.equals(scheduledJob.getAvailable())) {
62 logger.info("Inactive Job {}:{}", id, scheduledJob.getName());
63 try {
64 unregister(scheduledJob);
65 } catch (final Exception e) {
66 if (logger.isDebugEnabled()) {
67 logger.debug("Failed to delete Job {}", scheduledJob, e);
68 }
69 }
70 return;
71 }
72
73 final FessConfig fessConfig = ComponentUtil.getFessConfig();
74 final CronParamsSupplier paramsOp = () -> {
75 final Map<String, Object> params = new HashMap<>();
76 ComponentUtil.getComponent(ScheduledJobBhv.class).selectByPK(scheduledJob.getId())
77 .ifPresent(e -> params.put(Constants.SCHEDULED_JOB, e)).orElse(() -> {
78 logger.warn("Job {} is not found.", scheduledJob.getId());
79 });
80 return params;
81 };
82 findJobByUniqueOf(LaJobUnique.of(id)).ifPresent(job -> {
83 if (!job.isUnscheduled()) {
84 if (StringUtil.isNotBlank(scheduledJob.getCronExpression())) {
85 logger.info("Starting Job {}:{}", id, scheduledJob.getName());
86 final String cronExpression = scheduledJob.getCronExpression();
87 job.reschedule(cronExpression, op -> op.changeNoticeLogToDebug().params(paramsOp));
88 } else {
89 logger.info("Inactive Job {}:{}", id, scheduledJob.getName());
90 job.becomeNonCron();
91 }
92 } else if (StringUtil.isNotBlank(scheduledJob.getCronExpression())) {
93 logger.info("Starting Job {}:{}", id, scheduledJob.getName());
94 final String cronExpression = scheduledJob.getCronExpression();
95 job.reschedule(cronExpression, op -> op.changeNoticeLogToDebug().params(paramsOp));
96 }
97 }).orElse(() -> {
98 if (StringUtil.isNotBlank(scheduledJob.getCronExpression())) {
99 logger.info("Starting Job {}:{}", id, scheduledJob.getName());
100 final String cronExpression = scheduledJob.getCronExpression();
101 cron.register(cronExpression, fessConfig.getSchedulerJobClassAsClass(), fessConfig.getSchedulerConcurrentExecModeAsEnum(),
102 op -> op.uniqueBy(id).changeNoticeLogToDebug().params(paramsOp));
103 } else {
104 logger.info("Inactive Job {}:{}", id, scheduledJob.getName());
105 cron.registerNonCron(fessConfig.getSchedulerJobClassAsClass(), fessConfig.getSchedulerConcurrentExecModeAsEnum(),
106 op -> op.uniqueBy(id).changeNoticeLogToDebug().params(paramsOp));
107 }
108 });
109 }
110
111 private OptionalThing<LaScheduledJob> findJobByUniqueOf(final LaJobUnique jobUnique) {
112 final JobManager jobManager = ComponentUtil.getJobManager();
113 try {
114 return jobManager.findJobByUniqueOf(jobUnique);
115 } catch (final Exception e) {
116 return OptionalThing.empty();
117 }
118 }
119
120 public void unregister(final ScheduledJob scheduledJob) {
121 try {
122 final JobManager jobManager = ComponentUtil.getJobManager();
123 if (jobManager.isSchedulingDone()) {
124 jobManager.findJobByUniqueOf(LaJobUnique.of(scheduledJob.getId())).ifPresent(job -> {
125 job.unschedule();
126 }).orElse(() -> logger.debug("Job {} is not scheduled.", scheduledJob.getId()));
127 }
128 } catch (final Exception e) {
129 throw new ScheduledJobException("Failed to delete Job: " + scheduledJob, e);
130 }
131 }
132
133 public void remove(final ScheduledJob scheduledJob) {
134 try {
135 final JobManager jobManager = ComponentUtil.getJobManager();
136 if (jobManager.isSchedulingDone()) {
137 jobManager.findJobByUniqueOf(LaJobUnique.of(scheduledJob.getId())).ifPresent(job -> {
138 job.disappear();
139 }).orElse(() -> logger.debug("Job {} is not scheduled.", scheduledJob.getId()));
140 }
141 } catch (final Exception e) {
142 throw new ScheduledJobException("Failed to delete Job: " + scheduledJob, e);
143 }
144 }
145
146 public boolean isAvailable(final String id) {
147 return ComponentUtil.getComponent(ScheduledJobBhv.class).selectByPK(id).filter(e -> Boolean.TRUE.equals(e.getAvailable()))
148 .isPresent();
149 }
150
151 public void store(final JobLog jobLog) {
152 ComponentUtil.getComponent(JobLogBhv.class).insertOrUpdate(jobLog, op -> {
153 op.setRefreshPolicy(Constants.TRUE);
154 });
155 }
156
157 public TimeoutTask startMonitorTask(final JobLog jobLog) {
158 final TimeoutTarget target = new MonitorTarget(jobLog);
159 return TimeoutManager.getInstance().addTimeoutTarget(target, monitorInterval, true);
160 }
161
162 public void setMonitorInterval(final int monitorInterval) {
163 this.monitorInterval = monitorInterval;
164 }
165
166 static class MonitorTarget implements TimeoutTarget {
167
168 private final JobLog jobLog;
169
170 public MonitorTarget(final JobLog jobLog) {
171 this.jobLog = jobLog;
172 }
173
174 @Override
175 public void expired() {
176 if (jobLog.getEndTime() == null) {
177 jobLog.setLastUpdated(ComponentUtil.getSystemHelper().getCurrentTimeAsLong());
178 if (logger.isDebugEnabled()) {
179 logger.debug("Update {}", jobLog);
180 }
181 ComponentUtil.getComponent(JobLogBhv.class).insertOrUpdate(jobLog, op -> {
182 op.setRefreshPolicy(Constants.TRUE);
183 });
184 }
185 }
186
187 }
188
189 public void setJobRuntime(final LaJobRuntime runtime) {
190 jobRuntimeLocal.set(runtime);
191 }
192
193 public LaJobRuntime getJobRuntime() {
194 return jobRuntimeLocal.get();
195 }
196 }