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.exception.ScheduledJobException;
29 import org.codelibs.fess.mylasta.direction.FessConfig;
30 import org.codelibs.fess.opensearch.config.exbhv.JobLogBhv;
31 import org.codelibs.fess.opensearch.config.exbhv.ScheduledJobBhv;
32 import org.codelibs.fess.opensearch.config.exentity.JobLog;
33 import org.codelibs.fess.opensearch.config.exentity.ScheduledJob;
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
44
45
46
47 public class JobHelper {
48
49 private static final Logger logger = LogManager.getLogger(JobHelper.class);
50
51
52
53
54 public JobHelper() {
55
56 }
57
58
59 protected int monitorInterval = 60 * 60;
60
61
62 protected ThreadLocal<LaJobRuntime> jobRuntimeLocal = new ThreadLocal<>();
63
64
65
66
67
68
69 public void register(final ScheduledJob scheduledJob) {
70 final JobManager jobManager = ComponentUtil.getJobManager();
71 jobManager.schedule(cron -> register(cron, scheduledJob));
72 }
73
74
75
76
77
78
79
80 public void register(final LaCron cron, final ScheduledJob scheduledJob) {
81 if (scheduledJob == null) {
82 throw new ScheduledJobException("scheduledJob parameter is null. Cannot register a null job.");
83 }
84
85 final String id = scheduledJob.getId();
86 if (!Constants.T.equals(scheduledJob.getAvailable())) {
87 logger.info("Inactive Job: id={}, name={}", id, scheduledJob.getName());
88 try {
89 unregister(scheduledJob);
90 } catch (final Exception e) {
91 if (logger.isDebugEnabled()) {
92 logger.debug("Failed to delete Job: job={}", scheduledJob, e);
93 }
94 }
95 return;
96 }
97
98 final FessConfig fessConfig = ComponentUtil.getFessConfig();
99 final CronParamsSupplier paramsOp = () -> {
100 final Map<String, Object> params = new HashMap<>();
101 ComponentUtil.getComponent(ScheduledJobBhv.class)
102 .selectByPK(scheduledJob.getId())
103 .ifPresent(e -> params.put(Constants.SCHEDULED_JOB, e))
104 .orElse(() -> {
105 logger.warn("Job {} is not found.", scheduledJob.getId());
106 });
107 return params;
108 };
109 findJobByUniqueOf(LaJobUnique.of(id)).ifPresent(job -> {
110 if (!job.isUnscheduled()) {
111 if (StringUtil.isNotBlank(scheduledJob.getCronExpression())) {
112 logger.info("Starting Job {}:{}", id, scheduledJob.getName());
113 final String cronExpression = scheduledJob.getCronExpression();
114 job.reschedule(cronExpression, op -> op.changeNoticeLogToDebug().params(paramsOp));
115 } else {
116 logger.info("Inactive Job: id={}, name={}", id, scheduledJob.getName());
117 job.becomeNonCron();
118 }
119 } else if (StringUtil.isNotBlank(scheduledJob.getCronExpression())) {
120 logger.info("Starting Job {}:{}", id, scheduledJob.getName());
121 final String cronExpression = scheduledJob.getCronExpression();
122 job.reschedule(cronExpression, op -> op.changeNoticeLogToDebug().params(paramsOp));
123 }
124 }).orElse(() -> {
125 if (StringUtil.isNotBlank(scheduledJob.getCronExpression())) {
126 logger.info("Starting Job {}:{}", id, scheduledJob.getName());
127 final String cronExpression = scheduledJob.getCronExpression();
128 cron.register(cronExpression, fessConfig.getSchedulerJobClassAsClass(), fessConfig.getSchedulerConcurrentExecModeAsEnum(),
129 op -> op.uniqueBy(id).changeNoticeLogToDebug().params(paramsOp));
130 } else {
131 logger.info("Inactive Job: id={}, name={}", id, scheduledJob.getName());
132 cron.registerNonCron(fessConfig.getSchedulerJobClassAsClass(), fessConfig.getSchedulerConcurrentExecModeAsEnum(),
133 op -> op.uniqueBy(id).changeNoticeLogToDebug().params(paramsOp));
134 }
135 });
136 }
137
138
139
140
141
142
143
144 private OptionalThing<LaScheduledJob> findJobByUniqueOf(final LaJobUnique jobUnique) {
145 final JobManager jobManager = ComponentUtil.getJobManager();
146 try {
147 return jobManager.findJobByUniqueOf(jobUnique);
148 } catch (final Exception e) {
149 return OptionalThing.empty();
150 }
151 }
152
153
154
155
156
157
158
159 public void unregister(final ScheduledJob scheduledJob) {
160 try {
161 final JobManager jobManager = ComponentUtil.getJobManager();
162 if (jobManager.isSchedulingDone()) {
163 jobManager.findJobByUniqueOf(LaJobUnique.of(scheduledJob.getId())).ifPresent(job -> {
164 job.unschedule();
165 }).orElse(() -> logger.debug("Job {} is not scheduled.", scheduledJob.getId()));
166 }
167 } catch (final Exception e) {
168 throw new ScheduledJobException("Failed to delete Job: " + scheduledJob, e);
169 }
170 }
171
172
173
174
175
176
177
178 public void remove(final ScheduledJob scheduledJob) {
179 try {
180 final JobManager jobManager = ComponentUtil.getJobManager();
181 if (jobManager.isSchedulingDone()) {
182 jobManager.findJobByUniqueOf(LaJobUnique.of(scheduledJob.getId())).ifPresent(job -> {
183 job.disappear();
184 }).orElse(() -> logger.debug("Job {} is not scheduled.", scheduledJob.getId()));
185 }
186 } catch (final Exception e) {
187 throw new ScheduledJobException("Failed to delete Job: " + scheduledJob, e);
188 }
189 }
190
191
192
193
194
195
196
197 public boolean isAvailable(final String id) {
198 return ComponentUtil.getComponent(ScheduledJobBhv.class)
199 .selectByPK(id)
200 .filter(e -> Boolean.TRUE.equals(e.getAvailable()))
201 .isPresent();
202 }
203
204
205
206
207
208
209 public void store(final JobLog jobLog) {
210 ComponentUtil.getComponent(JobLogBhv.class).insertOrUpdate(jobLog, op -> {
211 op.setRefreshPolicy(Constants.TRUE);
212 });
213 }
214
215
216
217
218
219
220
221 public TimeoutTask startMonitorTask(final JobLog jobLog) {
222 final TimeoutTarget target = new MonitorTarget(jobLog);
223 return TimeoutManager.getInstance().addTimeoutTarget(target, monitorInterval, true);
224 }
225
226
227
228
229
230
231 public void setMonitorInterval(final int monitorInterval) {
232 this.monitorInterval = monitorInterval;
233 }
234
235
236
237
238 static class MonitorTarget implements TimeoutTarget {
239
240
241 private final JobLog jobLog;
242
243
244
245
246
247
248 public MonitorTarget(final JobLog jobLog) {
249 this.jobLog = jobLog;
250 }
251
252
253
254
255 @Override
256 public void expired() {
257 if (jobLog.getEndTime() == null) {
258 jobLog.setLastUpdated(ComponentUtil.getSystemHelper().getCurrentTimeAsLong());
259 if (logger.isDebugEnabled()) {
260 logger.debug("Update {}", jobLog);
261 }
262 ComponentUtil.getComponent(JobLogBhv.class).insertOrUpdate(jobLog, op -> {
263 op.setRefreshPolicy(Constants.TRUE);
264 });
265 }
266 }
267
268 }
269
270
271
272
273
274
275 public void setJobRuntime(final LaJobRuntime runtime) {
276 jobRuntimeLocal.set(runtime);
277 }
278
279
280
281
282
283
284 public LaJobRuntime getJobRuntime() {
285 return jobRuntimeLocal.get();
286 }
287 }