|
@@ -30,7 +30,6 @@ import javax.servlet.http.HttpServletRequest;
|
30
|
30
|
import javax.servlet.http.HttpServletResponse;
|
31
|
31
|
import java.io.IOException;
|
32
|
32
|
import java.util.Date;
|
33
|
|
-import java.util.HashSet;
|
34
|
33
|
import java.util.concurrent.ConcurrentHashMap;
|
35
|
34
|
|
36
|
35
|
/**
|
|
@@ -93,6 +92,7 @@ public final class XxlJobDynamicScheduler {
|
93
|
92
|
}
|
94
|
93
|
}
|
95
|
94
|
|
|
95
|
+
|
96
|
96
|
// ---------------------- admin rpc provider (no server version) ----------------------
|
97
|
97
|
private static JettyServerHandler jettyServerHandler;
|
98
|
98
|
private void initRpcProvider(){
|
|
@@ -137,6 +137,7 @@ public final class XxlJobDynamicScheduler {
|
137
|
137
|
return executorBiz;
|
138
|
138
|
}
|
139
|
139
|
|
|
140
|
+
|
140
|
141
|
// ---------------------- schedule util ----------------------
|
141
|
142
|
|
142
|
143
|
/**
|
|
@@ -145,50 +146,39 @@ public final class XxlJobDynamicScheduler {
|
145
|
146
|
* @param jobInfo
|
146
|
147
|
*/
|
147
|
148
|
public static void fillJobInfo(XxlJobInfo jobInfo) {
|
148
|
|
- // TriggerKey : name + group
|
|
149
|
+
|
149
|
150
|
String group = String.valueOf(jobInfo.getJobGroup());
|
150
|
151
|
String name = String.valueOf(jobInfo.getId());
|
151
|
|
- TriggerKey triggerKey = TriggerKey.triggerKey(name, group);
|
152
|
152
|
|
|
153
|
+ // trigger key
|
|
154
|
+ TriggerKey triggerKey = TriggerKey.triggerKey(name, group);
|
153
|
155
|
try {
|
154
|
|
- Trigger trigger = scheduler.getTrigger(triggerKey);
|
155
|
156
|
|
156
|
|
- TriggerState triggerState = scheduler.getTriggerState(triggerKey);
|
157
|
|
-
|
158
|
|
- // parse params
|
|
157
|
+ // trigger cron
|
|
158
|
+ Trigger trigger = scheduler.getTrigger(triggerKey);
|
159
|
159
|
if (trigger!=null && trigger instanceof CronTriggerImpl) {
|
160
|
160
|
String cronExpression = ((CronTriggerImpl) trigger).getCronExpression();
|
161
|
161
|
jobInfo.setJobCron(cronExpression);
|
162
|
162
|
}
|
163
|
163
|
|
164
|
|
- //JobKey jobKey = new JobKey(jobInfo.getJobName(), String.valueOf(jobInfo.getJobGroup()));
|
165
|
|
- //JobDetail jobDetail = scheduler.getJobDetail(jobKey);
|
166
|
|
- //String jobClass = jobDetail.getJobClass().getName();
|
167
|
|
-
|
|
164
|
+ // trigger state
|
|
165
|
+ TriggerState triggerState = scheduler.getTriggerState(triggerKey);
|
168
|
166
|
if (triggerState!=null) {
|
169
|
167
|
jobInfo.setJobStatus(triggerState.name());
|
170
|
168
|
}
|
|
169
|
+
|
|
170
|
+ //JobKey jobKey = new JobKey(jobInfo.getJobName(), String.valueOf(jobInfo.getJobGroup()));
|
|
171
|
+ //JobDetail jobDetail = scheduler.getJobDetail(jobKey);
|
|
172
|
+ //String jobClass = jobDetail.getJobClass().getName();
|
171
|
173
|
|
172
|
174
|
} catch (SchedulerException e) {
|
173
|
175
|
logger.error(e.getMessage(), e);
|
174
|
176
|
}
|
175
|
177
|
}
|
176
|
|
-
|
177
|
|
- /**
|
178
|
|
- * check if exists
|
179
|
|
- *
|
180
|
|
- * @param jobName
|
181
|
|
- * @param jobGroup
|
182
|
|
- * @return
|
183
|
|
- * @throws SchedulerException
|
184
|
|
- */
|
185
|
|
- public static boolean checkExists(String jobName, String jobGroup) throws SchedulerException{
|
186
|
|
- TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
187
|
|
- return scheduler.checkExists(triggerKey);
|
188
|
|
- }
|
|
178
|
+
|
189
|
179
|
|
190
|
180
|
/**
|
191
|
|
- * addJob
|
|
181
|
+ * add trigger + job
|
192
|
182
|
*
|
193
|
183
|
* @param jobName
|
194
|
184
|
* @param jobGroup
|
|
@@ -197,113 +187,109 @@ public final class XxlJobDynamicScheduler {
|
197
|
187
|
* @throws SchedulerException
|
198
|
188
|
*/
|
199
|
189
|
public static boolean addJob(String jobName, String jobGroup, String cronExpression) throws SchedulerException {
|
200
|
|
- // TriggerKey : name + group
|
|
190
|
+ // 1、job key
|
201
|
191
|
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
202
|
192
|
JobKey jobKey = new JobKey(jobName, jobGroup);
|
203
|
|
-
|
204
|
|
- // TriggerKey valid if_exists
|
205
|
|
- if (checkExists(jobName, jobGroup)) {
|
206
|
|
- logger.info(">>>>>>>>> addJob fail, job already exist, jobGroup:{}, jobName:{}", jobGroup, jobName);
|
207
|
|
- return false;
|
|
193
|
+
|
|
194
|
+ // 2、valid
|
|
195
|
+ if (scheduler.checkExists(triggerKey)) {
|
|
196
|
+ return true; // PASS
|
208
|
197
|
}
|
209
|
|
-
|
210
|
|
- // CronTrigger : TriggerKey + cronExpression // withMisfireHandlingInstructionDoNothing 忽略掉调度终止过程中忽略的调度
|
211
|
|
- CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
|
|
198
|
+
|
|
199
|
+ // 3、corn trigger
|
|
200
|
+ CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing(); // withMisfireHandlingInstructionDoNothing 忽略掉调度终止过程中忽略的调度
|
212
|
201
|
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
|
213
|
202
|
|
214
|
|
- // JobDetail : jobClass
|
|
203
|
+ // 4、job detail
|
215
|
204
|
Class<? extends Job> jobClass_ = RemoteHttpJobBean.class; // Class.forName(jobInfo.getJobClass());
|
216
|
|
-
|
217
|
205
|
JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build();
|
|
206
|
+
|
218
|
207
|
/*if (jobInfo.getJobData()!=null) {
|
219
|
208
|
JobDataMap jobDataMap = jobDetail.getJobDataMap();
|
220
|
209
|
jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));
|
221
|
210
|
// JobExecutionContext context.getMergedJobDataMap().get("mailGuid");
|
222
|
211
|
}*/
|
223
|
212
|
|
224
|
|
- // schedule : jobDetail + cronTrigger
|
|
213
|
+ // 5、schedule job
|
225
|
214
|
Date date = scheduler.scheduleJob(jobDetail, cronTrigger);
|
226
|
215
|
|
227
|
216
|
logger.info(">>>>>>>>>>> addJob success, jobDetail:{}, cronTrigger:{}, date:{}", jobDetail, cronTrigger, date);
|
228
|
217
|
return true;
|
229
|
218
|
}
|
230
|
|
-
|
|
219
|
+
|
|
220
|
+
|
231
|
221
|
/**
|
232
|
|
- * rescheduleJob
|
|
222
|
+ * remove trigger + job
|
233
|
223
|
*
|
234
|
|
- * @param jobGroup
|
235
|
224
|
* @param jobName
|
236
|
|
- * @param cronExpression
|
|
225
|
+ * @param jobGroup
|
237
|
226
|
* @return
|
238
|
227
|
* @throws SchedulerException
|
239
|
228
|
*/
|
240
|
|
- public static boolean rescheduleJob(String jobGroup, String jobName, String cronExpression) throws SchedulerException {
|
241
|
|
-
|
242
|
|
- // TriggerKey valid if_exists
|
243
|
|
- if (!checkExists(jobName, jobGroup)) {
|
244
|
|
- logger.info(">>>>>>>>>>> rescheduleJob fail, job not exists, JobGroup:{}, JobName:{}", jobGroup, jobName);
|
245
|
|
- return false;
|
246
|
|
- }
|
247
|
|
-
|
248
|
|
- // TriggerKey : name + group
|
249
|
|
- TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
250
|
|
- CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
251
|
|
-
|
252
|
|
- if (oldTrigger != null) {
|
253
|
|
- // avoid repeat
|
254
|
|
- String oldCron = oldTrigger.getCronExpression();
|
255
|
|
- if (oldCron.equals(cronExpression)){
|
256
|
|
- return true;
|
257
|
|
- }
|
|
229
|
+ public static boolean removeJob(String jobName, String jobGroup) throws SchedulerException {
|
258
|
230
|
|
259
|
|
- // CronTrigger : TriggerKey + cronExpression
|
260
|
|
- CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
|
261
|
|
- oldTrigger = oldTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
|
|
231
|
+ TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
262
|
232
|
|
263
|
|
- // rescheduleJob
|
264
|
|
- scheduler.rescheduleJob(triggerKey, oldTrigger);
|
265
|
|
- } else {
|
266
|
|
- // CronTrigger : TriggerKey + cronExpression
|
267
|
|
- CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
|
268
|
|
- CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
|
269
|
|
-
|
270
|
|
- // JobDetail-JobDataMap fresh
|
271
|
|
- JobKey jobKey = new JobKey(jobName, jobGroup);
|
272
|
|
- JobDetail jobDetail = scheduler.getJobDetail(jobKey);
|
273
|
|
- /*JobDataMap jobDataMap = jobDetail.getJobDataMap();
|
274
|
|
- jobDataMap.clear();
|
275
|
|
- jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));*/
|
276
|
|
-
|
277
|
|
- // Trigger fresh
|
278
|
|
- HashSet<Trigger> triggerSet = new HashSet<Trigger>();
|
279
|
|
- triggerSet.add(cronTrigger);
|
280
|
|
-
|
281
|
|
- scheduler.scheduleJob(jobDetail, triggerSet, true);
|
|
233
|
+ if (scheduler.checkExists(triggerKey)) {
|
|
234
|
+ scheduler.unscheduleJob(triggerKey); // trigger + job
|
282
|
235
|
}
|
283
|
236
|
|
284
|
|
- logger.info(">>>>>>>>>>> resumeJob success, JobGroup:{}, JobName:{}", jobGroup, jobName);
|
|
237
|
+ logger.info(">>>>>>>>>>> removeJob success, triggerKey:{}", triggerKey);
|
285
|
238
|
return true;
|
286
|
239
|
}
|
287
|
|
-
|
|
240
|
+
|
|
241
|
+
|
288
|
242
|
/**
|
289
|
|
- * unscheduleJob
|
|
243
|
+ * updateJobCron
|
290
|
244
|
*
|
291
|
|
- * @param jobName
|
292
|
245
|
* @param jobGroup
|
|
246
|
+ * @param jobName
|
|
247
|
+ * @param cronExpression
|
293
|
248
|
* @return
|
294
|
249
|
* @throws SchedulerException
|
295
|
250
|
*/
|
296
|
|
- public static boolean removeJob(String jobName, String jobGroup) throws SchedulerException {
|
297
|
|
- // TriggerKey : name + group
|
|
251
|
+ public static boolean updateJobCron(String jobGroup, String jobName, String cronExpression) throws SchedulerException {
|
|
252
|
+
|
|
253
|
+ // 1、job key
|
298
|
254
|
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
299
|
|
- boolean result = false;
|
300
|
|
- if (checkExists(jobName, jobGroup)) {
|
301
|
|
- result = scheduler.unscheduleJob(triggerKey);
|
302
|
|
- logger.info(">>>>>>>>>>> removeJob, triggerKey:{}, result [{}]", triggerKey, result);
|
|
255
|
+
|
|
256
|
+ // 2、valid
|
|
257
|
+ if (!scheduler.checkExists(triggerKey)) {
|
|
258
|
+ return true; // PASS
|
|
259
|
+ }
|
|
260
|
+
|
|
261
|
+ CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
|
262
|
+
|
|
263
|
+ // 3、avoid repeat cron
|
|
264
|
+ String oldCron = oldTrigger.getCronExpression();
|
|
265
|
+ if (oldCron.equals(cronExpression)){
|
|
266
|
+ return true; // PASS
|
303
|
267
|
}
|
|
268
|
+
|
|
269
|
+ // 4、new cron trigger
|
|
270
|
+ CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
|
|
271
|
+ oldTrigger = oldTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
|
|
272
|
+
|
|
273
|
+ // 5、rescheduleJob
|
|
274
|
+ scheduler.rescheduleJob(triggerKey, oldTrigger);
|
|
275
|
+
|
|
276
|
+ /*
|
|
277
|
+ JobKey jobKey = new JobKey(jobName, jobGroup);
|
|
278
|
+
|
|
279
|
+ // old job detail
|
|
280
|
+ JobDetail jobDetail = scheduler.getJobDetail(jobKey);
|
|
281
|
+
|
|
282
|
+ // new trigger
|
|
283
|
+ HashSet<Trigger> triggerSet = new HashSet<Trigger>();
|
|
284
|
+ triggerSet.add(cronTrigger);
|
|
285
|
+ // cover trigger of job detail
|
|
286
|
+ scheduler.scheduleJob(jobDetail, triggerSet, true);*/
|
|
287
|
+
|
|
288
|
+ logger.info(">>>>>>>>>>> resumeJob success, JobGroup:{}, JobName:{}", jobGroup, jobName);
|
304
|
289
|
return true;
|
305
|
290
|
}
|
306
|
291
|
|
|
292
|
+
|
307
|
293
|
/**
|
308
|
294
|
* pause
|
309
|
295
|
*
|
|
@@ -312,21 +298,21 @@ public final class XxlJobDynamicScheduler {
|
312
|
298
|
* @return
|
313
|
299
|
* @throws SchedulerException
|
314
|
300
|
*/
|
315
|
|
- public static boolean pauseJob(String jobName, String jobGroup) throws SchedulerException {
|
316
|
|
- // TriggerKey : name + group
|
|
301
|
+ /*public static boolean pauseJob(String jobName, String jobGroup) throws SchedulerException {
|
|
302
|
+
|
317
|
303
|
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
318
|
|
-
|
|
304
|
+
|
319
|
305
|
boolean result = false;
|
320
|
|
- if (checkExists(jobName, jobGroup)) {
|
|
306
|
+ if (scheduler.checkExists(triggerKey)) {
|
321
|
307
|
scheduler.pauseTrigger(triggerKey);
|
322
|
|
- result = true;
|
323
|
|
- logger.info(">>>>>>>>>>> pauseJob success, triggerKey:{}", triggerKey);
|
324
|
|
- } else {
|
325
|
|
- logger.info(">>>>>>>>>>> pauseJob fail, triggerKey:{}", triggerKey);
|
|
308
|
+ result = true;
|
326
|
309
|
}
|
|
310
|
+
|
|
311
|
+ logger.info(">>>>>>>>>>> pauseJob {}, triggerKey:{}", (result?"success":"fail"),triggerKey);
|
327
|
312
|
return result;
|
328
|
|
- }
|
329
|
|
-
|
|
313
|
+ }*/
|
|
314
|
+
|
|
315
|
+
|
330
|
316
|
/**
|
331
|
317
|
* resume
|
332
|
318
|
*
|
|
@@ -335,21 +321,21 @@ public final class XxlJobDynamicScheduler {
|
335
|
321
|
* @return
|
336
|
322
|
* @throws SchedulerException
|
337
|
323
|
*/
|
338
|
|
- public static boolean resumeJob(String jobName, String jobGroup) throws SchedulerException {
|
339
|
|
- // TriggerKey : name + group
|
340
|
|
- TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
|
324
|
+ /*public static boolean resumeJob(String jobName, String jobGroup) throws SchedulerException {
|
|
325
|
+
|
|
326
|
+ TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
341
|
327
|
|
342
|
328
|
boolean result = false;
|
343
|
|
- if (checkExists(jobName, jobGroup)) {
|
|
329
|
+ if (scheduler.checkExists(triggerKey)) {
|
344
|
330
|
scheduler.resumeTrigger(triggerKey);
|
345
|
331
|
result = true;
|
346
|
|
- logger.info(">>>>>>>>>>> resumeJob success, triggerKey:{}", triggerKey);
|
347
|
|
- } else {
|
348
|
|
- logger.info(">>>>>>>>>>> resumeJob fail, triggerKey:{}", triggerKey);
|
349
|
332
|
}
|
|
333
|
+
|
|
334
|
+ logger.info(">>>>>>>>>>> resumeJob {}, triggerKey:{}", (result?"success":"fail"), triggerKey);
|
350
|
335
|
return result;
|
351
|
|
- }
|
352
|
|
-
|
|
336
|
+ }*/
|
|
337
|
+
|
|
338
|
+
|
353
|
339
|
/**
|
354
|
340
|
* run
|
355
|
341
|
*
|
|
@@ -358,12 +344,13 @@ public final class XxlJobDynamicScheduler {
|
358
|
344
|
* @return
|
359
|
345
|
* @throws SchedulerException
|
360
|
346
|
*/
|
361
|
|
- public static boolean triggerJob(String jobName, String jobGroup) throws SchedulerException {
|
|
347
|
+ /*public static boolean triggerJob(String jobName, String jobGroup) throws SchedulerException {
|
362
|
348
|
// TriggerKey : name + group
|
363
|
349
|
JobKey jobKey = new JobKey(jobName, jobGroup);
|
364
|
|
-
|
|
350
|
+ TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
|
351
|
+
|
365
|
352
|
boolean result = false;
|
366
|
|
- if (checkExists(jobName, jobGroup)) {
|
|
353
|
+ if (scheduler.checkExists(triggerKey)) {
|
367
|
354
|
scheduler.triggerJob(jobKey);
|
368
|
355
|
result = true;
|
369
|
356
|
logger.info(">>>>>>>>>>> runJob success, jobKey:{}", jobKey);
|
|
@@ -371,7 +358,7 @@ public final class XxlJobDynamicScheduler {
|
371
|
358
|
logger.info(">>>>>>>>>>> runJob fail, jobKey:{}", jobKey);
|
372
|
359
|
}
|
373
|
360
|
return result;
|
374
|
|
- }
|
|
361
|
+ }*/
|
375
|
362
|
|
376
|
363
|
|
377
|
364
|
/**
|