1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.openr66.context.task;
21
22 import org.waarp.common.logging.WaarpLogger;
23 import org.waarp.common.logging.WaarpLoggerFactory;
24 import org.waarp.openr66.context.ErrorCode;
25 import org.waarp.openr66.context.R66Result;
26 import org.waarp.openr66.context.R66Session;
27 import org.waarp.openr66.context.task.exception.OpenR66RunnerErrorException;
28 import org.waarp.openr66.database.data.DbTaskRunner;
29
30 import java.sql.Timestamp;
31 import java.util.Calendar;
32 import java.util.Date;
33 import java.util.Map;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119 public class RescheduleTransferTask extends AbstractTask {
120
121
122
123 private static final WaarpLogger logger =
124 WaarpLoggerFactory.getLogger(RescheduleTransferTask.class);
125
126
127
128
129
130
131
132 public static final String CPTLIMIT = "CPTLIMIT";
133 public static final String CPTTOTAL = "CPTTOTAL";
134
135 protected long newdate;
136
137 protected Calendar newDate;
138
139 protected boolean countUsed;
140
141 protected int limitCount = -1;
142
143 protected int totalCount;
144
145 protected int resetCount = -1;
146
147 protected DbTaskRunner runner;
148
149
150
151
152
153
154
155 public RescheduleTransferTask(final String argRule, final int delay,
156 final String argTransfer,
157 final R66Session session) {
158 super(TaskType.RESCHEDULE, delay, argRule, argTransfer, session);
159 }
160
161 @Override
162 public final void run() {
163 logger.info("Reschedule with {}:{} and {}", argRule, argTransfer, session);
164 runner = session.getRunner();
165 if (runner == null) {
166 futureCompletion.setFailure(
167 new OpenR66RunnerErrorException("No valid runner in Reschedule"));
168 return;
169 }
170 if (runner.isRescheduledTransfer()) {
171
172 final R66Result result =
173 new R66Result(session, false, ErrorCode.Warning, runner);
174 futureCompletion.setResult(result);
175 logger.warn("Transfer already Rescheduled: " + runner.toShortString());
176 futureCompletion.setSuccess();
177 return;
178 }
179 if (runner.isRequestOnRequested()) {
180
181 final R66Result result =
182 new R66Result(session, false, ErrorCode.LoopSelfRequestedHost,
183 runner);
184 futureCompletion.setResult(result);
185 futureCompletion.setFailure(new OpenR66RunnerErrorException(
186 "No valid runner in Reschedule since Self Requested"));
187 return;
188 }
189 String finalname = argRule;
190 finalname = getReplacedValue(finalname, BLANK.split(argTransfer));
191 final String[] args = BLANK.split(finalname);
192 if (args.length < 4) {
193 final R66Result result =
194 new R66Result(session, false, ErrorCode.Warning, runner);
195 futureCompletion.setResult(result);
196 logger.warn(
197 "Not enough argument in Reschedule: " + runner.toShortString());
198 futureCompletion.setSuccess();
199 return;
200 }
201 if (!validateArgs(args)) {
202 final R66Result result =
203 new R66Result(session, false, ErrorCode.Warning, runner);
204 futureCompletion.setResult(result);
205 logger.warn(
206 "Reschedule unallowed due to argument: " + runner.toShortString());
207 futureCompletion.setSuccess();
208 return;
209 }
210 if (countUsed) {
211 limitCount--;
212 if (limitCount >= 0) {
213
214 resetCount = limitCount;
215 }
216 resetInformation(resetCount);
217 if (limitCount < 0) {
218
219 try {
220 runner.saveStatus();
221 } catch (final OpenR66RunnerErrorException ignored) {
222
223 }
224 final R66Result result =
225 new R66Result(session, false, ErrorCode.Warning, runner);
226 futureCompletion.setResult(result);
227 logger.warn("Reschedule unallowed due to limit reached: " +
228 runner.toShortString());
229 futureCompletion.setSuccess();
230 return;
231 }
232 }
233 final Timestamp start = new Timestamp(newdate);
234 try {
235 runner.setStart(start);
236 if (runner.restart(true)) {
237 runner.saveStatus();
238 }
239 } catch (final OpenR66RunnerErrorException e) {
240 logger.error(
241 "Prepare transfer in FAILURE " + runner.toShortString() +
242 " <AT>" + new Date(newdate) + "</AT>", e);
243 futureCompletion.setFailure(new OpenR66RunnerErrorException(
244 "Reschedule failed: " + e.getMessage(), e));
245 return;
246 }
247 runner.setRescheduledTransfer();
248 final R66Result result =
249 new R66Result(session, false, ErrorCode.Warning, runner);
250 futureCompletion.setResult(result);
251 logger.warn(
252 "Reschedule transfer in SUCCESS " + runner.toShortString() +
253 " <AT>" + new Date(newdate) + "</AT>");
254 futureCompletion.setSuccess();
255 }
256
257 protected final void resetInformation(final int value) {
258 final Map<String, Object> root = runner.getTransferMap();
259 root.put(CPTLIMIT, value);
260 try {
261 totalCount = (Integer) root.get(CPTTOTAL);
262 totalCount++;
263 root.put(CPTTOTAL, totalCount);
264 } catch (final Exception e) {
265 totalCount = 1;
266 root.put(CPTTOTAL, totalCount);
267 }
268 runner.setTransferMap(root);
269 }
270
271 protected final boolean validateArgs(final String[] args) {
272 boolean validCode = false;
273 for (int i = 0; i < args.length; i++) {
274 if ("-delay".equalsIgnoreCase(args[i])) {
275 i++;
276 try {
277 newdate = Long.parseLong(args[i]);
278 } catch (final NumberFormatException e) {
279 logger.warn("Bad Long format: args[i]");
280 return false;
281 }
282 } else if ("-case".equalsIgnoreCase(args[i])) {
283 i++;
284 if (!validCode) {
285 final String[] codes = args[i].split(",");
286 for (final String code2 : codes) {
287 final ErrorCode code = ErrorCode.getFromCode(code2);
288 if (session.getLocalChannelReference().getCurrentCode() == code) {
289 logger.debug("Code valid: {}", code);
290 validCode = true;
291 }
292 }
293 }
294 } else if ("-count".equalsIgnoreCase(args[i])) {
295 i++;
296 try {
297 resetCount = Integer.parseInt(args[i]);
298 } catch (final NumberFormatException e) {
299 logger.warn("ResetLimit is not an integer: " + args[i]);
300 countUsed = false;
301 return false;
302 }
303 final Map<String, Object> root = runner.getTransferMap();
304 final Integer limit;
305 try {
306 limit = (Integer) root.get(CPTLIMIT);
307 } catch (final Exception e) {
308 logger.warn("Bad Long format: CPTLIMIT" + " : {}", e.getMessage());
309 return false;
310 }
311 if (limit != null) {
312 limitCount = limit;
313 } else {
314 limitCount = resetCount;
315 root.put(CPTLIMIT, limitCount);
316 }
317 countUsed = true;
318 }
319 }
320
321 if (!validCode) {
322 logger.warn("No valid Code found");
323 return false;
324 }
325 if (newdate <= 0) {
326 logger.warn("Delay is negative: " + newdate);
327 return false;
328 }
329 newdate += System.currentTimeMillis();
330 newDate = Calendar.getInstance();
331 newDate.setTimeInMillis(newdate);
332 boolean betweenTest = false;
333 boolean betweenResult = false;
334 for (int i = 0; i < args.length; i++) {
335 if ("-notbetween".equalsIgnoreCase(args[i])) {
336 i++;
337 final String[] elmts = args[i].split(";");
338 boolean startModified = false;
339 String[] values = elmts[0].split(":");
340 Calendar start = getCalendar(values);
341 if (start != null) {
342 startModified = true;
343 } else {
344 start = Calendar.getInstance();
345 }
346 boolean stopModified = false;
347 values = elmts[1].split(":");
348 Calendar stop = getCalendar(values);
349 if (stop != null) {
350 stopModified = true;
351 } else {
352 stop = Calendar.getInstance();
353 }
354 logger.debug("Dates before check: Not between {} and {}",
355 start.getTime(), stop.getTime());
356
357 if (start.compareTo(stop) > 0) {
358
359 stop.add(Calendar.DAY_OF_MONTH, 1);
360 }
361
362 if (start.compareTo(newDate) < 0) {
363 start.add(Calendar.DAY_OF_MONTH, 1);
364 stop.add(Calendar.DAY_OF_MONTH, 1);
365 }
366 logger.debug("Dates after check: Not between {} and {}",
367 start.getTime(), stop.getTime());
368 if (!startModified) {
369 if (newDate.compareTo(stop) < 0) {
370 logger.debug("newDate: {} Should not be between {} and {}",
371 newDate.getTime(), start.getTime(), stop.getTime());
372 return false;
373 }
374 } else if (start.compareTo(newDate) < 0) {
375 if (!stopModified || newDate.compareTo(stop) < 0) {
376 logger.debug("newDate: {} Should not be between {} and {}",
377 newDate.getTime(), start.getTime(), stop.getTime());
378 return false;
379 }
380 }
381 } else if ("-between".equalsIgnoreCase(args[i])) {
382 i++;
383 betweenTest = true;
384 final String[] elmts = args[i].split(";");
385 boolean startModified = false;
386 String[] values = elmts[0].split(":");
387 Calendar start = getCalendar(values);
388 if (start != null) {
389 startModified = true;
390 } else {
391 start = Calendar.getInstance();
392 }
393 boolean stopModified = false;
394 values = elmts[1].split(":");
395 Calendar stop = getCalendar(values);
396 if (stop != null) {
397 stopModified = true;
398 } else {
399 stop = Calendar.getInstance();
400 }
401 logger.debug("Dates before check: Between {} and {}", start.getTime(),
402 stop.getTime());
403
404 if (start.compareTo(stop) > 0) {
405
406 stop.add(Calendar.DAY_OF_MONTH, 1);
407 }
408
409 if (start.compareTo(newDate) < 0) {
410 start.add(Calendar.DAY_OF_MONTH, 1);
411 stop.add(Calendar.DAY_OF_MONTH, 1);
412 }
413 logger.debug("Dates before check: Between {} and {}", start.getTime(),
414 stop.getTime());
415 if (!startModified) {
416 if (newDate.compareTo(stop) < 0) {
417 logger.debug("newDate: {} is between {} and {}", newDate.getTime(),
418 start.getTime(), stop.getTime());
419 betweenResult = true;
420 }
421 } else if (start.compareTo(newDate) < 0) {
422 if (!stopModified || newDate.compareTo(stop) < 0) {
423 logger.debug("newDate: {} is between {} and {}", newDate.getTime(),
424 start.getTime(), stop.getTime());
425 betweenResult = true;
426 }
427 }
428 }
429 }
430 if (betweenTest) {
431 logger.debug(
432 "Since between is specified, do we found newDate: {} Result: {}",
433 newDate.getTime(), betweenResult);
434 return betweenResult;
435 }
436 logger.debug("newDate: {} rescheduled", newDate.getTime());
437 return true;
438 }
439
440
441
442
443
444
445
446
447
448
449 private Calendar getCalendar(final String[] values) {
450 final Calendar newcal = Calendar.getInstance();
451 boolean isModified = false;
452 for (final String value2 : values) {
453 if (value2.length() > 1) {
454 int addvalue = 0;
455 int value = -1;
456 switch (value2.charAt(0)) {
457 case '+':
458 try {
459 addvalue = Integer.parseInt(value2.substring(2));
460 } catch (final NumberFormatException e) {
461 continue;
462 }
463 break;
464 case '-':
465 try {
466 addvalue = Integer.parseInt(value2.substring(1));
467 } catch (final NumberFormatException e) {
468 continue;
469 }
470 break;
471 case '=':
472 try {
473 value = Integer.parseInt(value2.substring(2));
474 } catch (final NumberFormatException e) {
475 continue;
476 }
477 break;
478 default:
479 try {
480 value = Integer.parseInt(value2.substring(1));
481 } catch (final NumberFormatException e) {
482 continue;
483 }
484 }
485 switch (value2.charAt(0)) {
486 case 'Y':
487 if (value >= 0) {
488 newcal.set(Calendar.YEAR, value);
489 } else {
490 newcal.add(Calendar.YEAR, addvalue);
491 }
492 isModified = true;
493 break;
494 case 'M':
495 if (value >= 0) {
496 newcal.set(Calendar.MONTH, value);
497 } else {
498 newcal.add(Calendar.MONTH, addvalue);
499 }
500 isModified = true;
501 break;
502 case 'D':
503 if (value >= 0) {
504 newcal.set(Calendar.DAY_OF_MONTH, value);
505 } else {
506 newcal.add(Calendar.DAY_OF_MONTH, addvalue);
507 }
508 isModified = true;
509 break;
510 case 'H':
511 if (value >= 0) {
512 newcal.set(Calendar.HOUR_OF_DAY, value);
513 } else {
514 newcal.add(Calendar.HOUR_OF_DAY, addvalue);
515 }
516 isModified = true;
517 break;
518 case 'm':
519 if (value >= 0) {
520 newcal.set(Calendar.MINUTE, value);
521 } else {
522 newcal.add(Calendar.MINUTE, addvalue);
523 }
524 isModified = true;
525 break;
526 case 'S':
527 if (value >= 0) {
528 newcal.set(Calendar.SECOND, value);
529 } else {
530 newcal.add(Calendar.SECOND, addvalue);
531 }
532 isModified = true;
533 break;
534 default:
535
536 }
537 }
538 }
539 if (isModified) {
540 return newcal;
541 }
542 return null;
543 }
544 }