1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.waarp.openr66.client;
22
23 import org.apache.commons.cli.CommandLine;
24 import org.apache.commons.cli.CommandLineParser;
25 import org.apache.commons.cli.DefaultParser;
26 import org.apache.commons.cli.HelpFormatter;
27 import org.apache.commons.cli.Option;
28 import org.apache.commons.cli.OptionGroup;
29 import org.apache.commons.cli.Options;
30 import org.apache.commons.cli.ParseException;
31 import org.waarp.common.database.exception.WaarpDatabaseException;
32 import org.waarp.common.database.exception.WaarpDatabaseNoDataException;
33 import org.waarp.common.guid.LongUuid;
34 import org.waarp.common.json.JsonHandler;
35 import org.waarp.common.logging.SysErrLogger;
36 import org.waarp.common.logging.WaarpLogger;
37 import org.waarp.common.logging.WaarpLoggerFactory;
38 import org.waarp.openr66.client.utils.OutputFormat;
39 import org.waarp.openr66.client.utils.OutputFormat.OUTPUTFORMAT;
40 import org.waarp.openr66.database.data.DbTaskRunner;
41 import org.waarp.openr66.protocol.configuration.Configuration;
42 import org.waarp.openr66.protocol.configuration.Messages;
43
44 import java.sql.Timestamp;
45 import java.text.SimpleDateFormat;
46 import java.util.Arrays;
47 import java.util.Date;
48 import java.util.HashMap;
49 import java.util.Map;
50
51 import static org.waarp.common.database.DbConstant.*;
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 public class TransferArgs {
73 private static final WaarpLogger logger =
74 WaarpLoggerFactory.getLogger(TransferArgs.class);
75
76 private static final String FILE = "file";
77 public static final String FILE_ARG = "-" + FILE;
78 private static final Option FILE_OPTION =
79 Option.builder(FILE).required(false).hasArg(true)
80 .desc("Specify the file path to operate on").build();
81 private static final String TO = "to";
82 public static final String TO_ARG = "-" + TO;
83 private static final Option TO_OPTION =
84 Option.builder(TO).required(true).hasArg(true)
85 .desc("Specify the requested Host").build();
86 private static final String RULE = "rule";
87 public static final String RULE_ARG = "-" + RULE;
88 private static final Option RULE_OPTION =
89 Option.builder(RULE).required(false).hasArg(true).desc("Specify the Rule")
90 .build();
91 private static final String ID_FIELD = "id";
92 public static final String ID_ARG = "-" + ID_FIELD;
93 private static final Option ID_OPTION =
94 Option.builder(ID_FIELD).required(false).hasArg(true)
95 .desc("Specify the id of transfer").build();
96 private static final String NO_FOLLOW = "nofollow";
97 public static final String NO_FOLLOW_ARG = "-" + NO_FOLLOW;
98 private static final Option NO_FOLLOW_OPTION =
99 Option.builder(NO_FOLLOW).required(false).hasArg(false)
100 .desc("Specify if the transfer should not integrate a FOLLOW id")
101 .build();
102 public static final String FOLLOW_JSON_KEY = "follow";
103 private static final String INFO = "info";
104 public static final String INFO_ARG = "-" + INFO;
105 private static final Option INFO_OPTION =
106 Option.builder(INFO).required(false).hasArg(true)
107 .desc("Specify the transfer information").build();
108 private static final String HASH = "md5";
109 public static final String HASH_ARG = "-" + HASH;
110 private static final Option HASH_OPTION =
111 Option.builder(HASH).required(false).hasArg(false)
112 .desc("Specify the option to have a hash computed for the transfer")
113 .build();
114 private static final String BLOCK = "block";
115 public static final String BLOCK_ARG = "-" + BLOCK;
116 private static final Option BLOCK_OPTION =
117 Option.builder(BLOCK).required(false).hasArg(true)
118 .desc("Specify the block size").build();
119 private static final String START = "start";
120 public static final String START_ARG = "-" + START;
121 private static final Option START_OPTION =
122 Option.builder(START).required(false).hasArg(true)
123 .desc("Specify the start time as yyyyMMddHHmmss").build();
124 private static final String DELAY = "delay";
125 public static final String DELAY_ARG = "-" + DELAY;
126 private static final Option DELAY_OPTION =
127 Option.builder(DELAY).required(false).hasArg(true).desc(
128 "Specify the delay time as an epoch time or '+' a delay in ms")
129 .build();
130
131 private static final String LOGWARN = "logWarn";
132 public static final String LOGWARN_ARG = "-" + LOGWARN;
133 private static final Option LOGWARN_OPTION =
134 Option.builder(LOGWARN).required(false).hasArg(false)
135 .desc("Specify to log final result as Warn if OK").build();
136 private static final String NOTLOGWARN = "notlogWarn";
137 public static final String NOTLOGWARN_ARG = "-" + NOTLOGWARN;
138 private static final Option NOTLOGWARN_OPTION =
139 Option.builder(NOTLOGWARN).required(false).hasArg(false)
140 .desc("Specify to log final result as Info if OK").build();
141
142 private static final String NOTLOG = "nolog";
143 public static final String NOTLOG_ARG = "-" + NOTLOG;
144 private static final Option NOTLOG_OPTION =
145 Option.builder(NOTLOG).required(false).hasArg(false).desc(
146 "Specify to not log anything included database once the " +
147 "transfer is done").build();
148
149 private static final OptionGroup LOGWARN_OPTIONS =
150 new OptionGroup().addOption(LOGWARN_OPTION).addOption(NOTLOGWARN_OPTION);
151 private static final OptionGroup DELAY_OPTIONS =
152 new OptionGroup().addOption(DELAY_OPTION).addOption(START_OPTION);
153
154 private static final String QUIET = "quiet";
155 private static final String CSV = "csv";
156 private static final String XML = "xml";
157 private static final String JSON = "json";
158 private static final String PROPERTY = "property";
159 public static final String QUIET_ARG = "-" + QUIET;
160 public static final String CSV_ARG = "-" + CSV;
161 public static final String XML_ARG = "-" + XML;
162 public static final String JSON_ARG = "-" + JSON;
163 public static final String PROPERTY_ARG = "-" + PROPERTY;
164 private static final Option QUIET_OPTION =
165 Option.builder(QUIET).required(false).hasArg(false).desc(
166 "meaning no output at all (logs are not changed, exit value still " +
167 "uses 0 as Success, 1 as Warning and others as Failure)").build();
168 private static final Option CSV_OPTION =
169 Option.builder(CSV).required(false).hasArg(false).desc(
170 "meaning output will be in CSV format (2 lines, 1 with title, 1 " +
171 "with content, separator is ';')").build();
172 private static final Option XML_OPTION =
173 Option.builder(XML).required(false).hasArg(false)
174 .desc("meaning output will be in XML").build();
175 private static final Option JSON_OPTION =
176 Option.builder(JSON).required(false).hasArg(false)
177 .desc("meaning output will be in JSON").build();
178 private static final Option PROPERTY_OPTION =
179 Option.builder(PROPERTY).required(false).hasArg(false)
180 .desc("meaning output will be in Property format (name=value)")
181 .build();
182 private static final OptionGroup OUTPUT_OPTIONS =
183 new OptionGroup().addOption(QUIET_OPTION).addOption(CSV_OPTION)
184 .addOption(XML_OPTION).addOption(JSON_OPTION)
185 .addOption(PROPERTY_OPTION);
186
187 private static final Options TRANSFER_OPTIONS =
188 new Options().addOption(FILE_OPTION).addOption(TO_OPTION)
189 .addOption(NO_FOLLOW_OPTION).addOption(RULE_OPTION)
190 .addOption(ID_OPTION).addOption(INFO_OPTION)
191 .addOption(HASH_OPTION).addOption(BLOCK_OPTION)
192 .addOptionGroup(DELAY_OPTIONS).addOption(NOTLOG_OPTION)
193 .addOptionGroup(LOGWARN_OPTIONS)
194 .addOptionGroup(OUTPUT_OPTIONS);
195
196 public static final String SEPARATOR_SEND = "--";
197
198
199
200
201
202 public static void printHelp() {
203 final HelpFormatter formatter = new HelpFormatter();
204 formatter.printHelp("Transfer", TRANSFER_OPTIONS);
205 }
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234 public static TransferArgs getParamsInternal(final int rank,
235 final String[] args,
236 final boolean analyseFollow) {
237 if (args == null || args.length == 0) {
238 logger.error("Arguments cannot be empty or null");
239 return null;
240 }
241 final String[] realArgs = getRealArgs(rank, args);
242
243
244 final TransferArgs transferArgs1 = new TransferArgs();
245 transferArgs1.setBlockSize(Configuration.configuration.getBlockSize());
246
247 final CommandLineParser parser = new DefaultParser();
248 try {
249 final CommandLine cmd = parser.parse(TRANSFER_OPTIONS, realArgs, true);
250 if (getTransferMinimalArgs(transferArgs1, cmd)) {
251 return null;
252 }
253 if (checkDelayStart(transferArgs1, cmd)) {
254 return null;
255 }
256 if (checkExtraTransferArgs(transferArgs1, cmd)) {
257 return null;
258 }
259 checkLog(transferArgs1, cmd);
260 checkOutput(cmd);
261 } catch (final ParseException e) {
262 printHelp();
263 logger.error("Arguments are incorrect {}", e.getMessage());
264 return null;
265 }
266 return finalizeTransferArgs(analyseFollow, transferArgs1);
267 }
268
269
270
271
272
273
274
275
276
277 private static boolean checkExtraTransferArgs(
278 final TransferArgs transferArgs1, final CommandLine cmd) {
279 if (!cmd.hasOption(NO_FOLLOW)) {
280 transferArgs1.setFollowId("");
281 }
282 if (cmd.hasOption(INFO)) {
283 transferArgs1.setTransferInfo(cmd.getOptionValue(INFO));
284 }
285 if (cmd.hasOption(HASH)) {
286 transferArgs1.setMD5(true);
287 }
288 if (cmd.hasOption(BLOCK)) {
289 try {
290 transferArgs1.setBlockSize(Integer.parseInt(cmd.getOptionValue(BLOCK)));
291 } catch (final NumberFormatException ignored) {
292 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
293 logger.error(Messages.getString("AbstractTransfer.20") + " block");
294
295 return true;
296 }
297 if (transferArgs1.getBlockSize() < 100) {
298 logger.error(Messages.getString("AbstractTransfer.1") +
299 transferArgs1.getBlockSize());
300
301 return true;
302 }
303 }
304 return false;
305 }
306
307
308
309
310
311
312
313
314
315 private static boolean getTransferMinimalArgs(
316 final TransferArgs transferArgs1, final CommandLine cmd) {
317 if (cmd.hasOption(TO)) {
318 transferArgs1.setRemoteHost(cmd.getOptionValue(TO));
319 if (Configuration.configuration.getAliases().containsKey(
320 transferArgs1.getRemoteHost())) {
321 transferArgs1.setRemoteHost(Configuration.configuration.getAliases()
322 .get(
323 transferArgs1.getRemoteHost()));
324 }
325 }
326 if (cmd.hasOption(FILE)) {
327 transferArgs1.setFilename(cmd.getOptionValue(FILE));
328 transferArgs1.setFilename(transferArgs1.getFilename().replace('ยง', '*'));
329 }
330 if (cmd.hasOption(RULE)) {
331 transferArgs1.setRulename(cmd.getOptionValue(RULE));
332 }
333 if (cmd.hasOption(ID_FIELD)) {
334 try {
335 transferArgs1.setId(Long.parseLong(cmd.getOptionValue(ID_FIELD)));
336 } catch (final NumberFormatException ignored) {
337 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
338 logger.error(Messages.getString("AbstractTransfer.20") + " id");
339
340 return true;
341 }
342 }
343 return false;
344 }
345
346
347
348
349
350
351
352
353
354
355 private static String[] getRealArgs(final int rank, final String[] args) {
356 String[] realArgs =
357 rank == 0? args : Arrays.copyOfRange(args, rank, args.length);
358 for (int i = rank; i < args.length; i++) {
359 if (SEPARATOR_SEND.equals(args[i])) {
360 realArgs = Arrays.copyOfRange(args, rank, i);
361 break;
362 }
363 }
364 return realArgs;
365 }
366
367
368
369
370
371
372
373
374
375 private static TransferArgs finalizeTransferArgs(final boolean analyseFollow,
376 final TransferArgs transferArgs1) {
377 if (transferArgs1.getTransferInfo() == null) {
378 transferArgs1.setTransferInfo(AbstractTransfer.NO_INFO_ARGS);
379 }
380 if (analyseFollow) {
381 analyzeFollow(transferArgs1);
382 }
383 if (transferArgs1.getRemoteHost() != null &&
384 transferArgs1.getRulename() != null &&
385 transferArgs1.getFilename() != null) {
386 return transferArgs1;
387 } else if (transferArgs1.getId() != ILLEGALVALUE &&
388 transferArgs1.getRemoteHost() != null) {
389 try {
390 final DbTaskRunner runner = new DbTaskRunner(transferArgs1.getId(),
391 transferArgs1.getRemoteHost());
392 transferArgs1.setRulename(runner.getRuleId());
393 transferArgs1.setFilename(runner.getOriginalFilename());
394 return transferArgs1;
395 } catch (final WaarpDatabaseNoDataException e) {
396 logger.error("No transfer found with this id and partner");
397 logger.error(Messages.getString("AbstractBusinessRequest.NeedMoreArgs",
398 "(-to -rule -file | -to -id with " +
399 "existing id transfer): {}")
400
401 , e.getMessage());
402 return null;
403 } catch (final WaarpDatabaseException e) {
404 logger.error(Messages.getString("AbstractBusinessRequest.NeedMoreArgs",
405 "(-to -rule -file | -to -id) with a " +
406 "correct database connexion: {}",
407 e.getMessage()));
408 return null;
409 }
410 }
411 logger.error(Messages.getString("AbstractBusinessRequest.NeedMoreArgs",
412 "(-to -rule -file | -to -id)") +
413
414 AbstractTransfer.INFO_ARGS);
415 return null;
416 }
417
418
419
420
421
422
423
424 private static void checkLog(final TransferArgs transferArgs1,
425 final CommandLine cmd) {
426 if (cmd.hasOption(LOGWARN)) {
427 transferArgs1.setNormalInfoAsWarn(true);
428 }
429 if (cmd.hasOption(NOTLOGWARN)) {
430 transferArgs1.setNormalInfoAsWarn(false);
431 }
432 if (cmd.hasOption(NOTLOG)) {
433 transferArgs1.setNolog(true);
434 }
435 }
436
437
438
439
440
441
442 private static void checkOutput(final CommandLine cmd) {
443 if (cmd.hasOption(QUIET)) {
444 OutputFormat.setDefaultOutput(OUTPUTFORMAT.QUIET);
445 } else if (cmd.hasOption(CSV)) {
446 OutputFormat.setDefaultOutput(OUTPUTFORMAT.CSV);
447 } else if (cmd.hasOption(XML)) {
448 OutputFormat.setDefaultOutput(OUTPUTFORMAT.XML);
449 } else if (cmd.hasOption(JSON)) {
450 OutputFormat.setDefaultOutput(OUTPUTFORMAT.JSON);
451 } else if (cmd.hasOption(PROPERTY)) {
452 OutputFormat.setDefaultOutput(OUTPUTFORMAT.PROPERTY);
453 }
454 }
455
456
457
458
459
460
461
462
463
464 private static boolean checkDelayStart(final TransferArgs transferArgs1,
465 final CommandLine cmd) {
466 if (cmd.hasOption(START)) {
467 final Date date;
468 final SimpleDateFormat dateFormat =
469 new SimpleDateFormat(AbstractTransfer.TIMESTAMP_FORMAT);
470 try {
471 date = dateFormat.parse(cmd.getOptionValue(START));
472 transferArgs1.setStartTime(new Timestamp(date.getTime()));
473 } catch (final java.text.ParseException ignored) {
474 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
475 logger.error(Messages.getString("AbstractTransfer.20") + " StartTime");
476
477 return true;
478 }
479 }
480 if (cmd.hasOption(DELAY)) {
481 final String delay = cmd.getOptionValue(DELAY);
482 try {
483 if (delay.charAt(0) == '+') {
484 transferArgs1.setStartTime(new Timestamp(
485 System.currentTimeMillis() + Long.parseLong(delay.substring(1))));
486 } else {
487 transferArgs1.setStartTime(new Timestamp(Long.parseLong(delay)));
488 }
489 } catch (final NumberFormatException ignored) {
490 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
491 logger.error(Messages.getString("AbstractTransfer.20") + " Delay");
492
493 return true;
494 }
495 }
496 return false;
497 }
498
499
500
501
502
503
504
505
506
507 public static void getAllInfo(final TransferArgs transferArgs, final int rank,
508 final String[] args, final String copiedInfo) {
509 if (transferArgs != null) {
510 final StringBuilder builder = new StringBuilder();
511 if (copiedInfo != null) {
512 builder.append(copiedInfo);
513 }
514 for (int i = rank; i < args.length; i++) {
515 if (INFO_ARG.equalsIgnoreCase(args[i])) {
516 i++;
517 if (builder.length() == 0) {
518 builder.append(args[i].trim());
519 } else {
520 builder.append(' ').append(args[i].trim());
521 }
522 i++;
523 while (i < args.length) {
524 builder.append(' ').append(args[i].trim());
525 i++;
526 }
527 }
528 }
529 transferArgs.setTransferInfo(builder.toString());
530 TransferArgs.analyzeFollow(transferArgs);
531 }
532 }
533
534
535
536
537
538
539
540 public static void forceAnalyzeFollow(
541 final AbstractTransfer abstractTransfer) {
542 if (abstractTransfer.transferArgs.getFollowId() == null) {
543 abstractTransfer.transferArgs.setFollowId("");
544 analyzeFollow(abstractTransfer.transferArgs);
545 } else if (!abstractTransfer.transferArgs.getFollowId().isEmpty() &&
546 abstractTransfer.transferArgs.getTransferInfo() != null) {
547 if (!abstractTransfer.transferArgs.getTransferInfo()
548 .contains(FOLLOW_JSON_KEY)) {
549
550 final Map<String, Object> map = new HashMap<String, Object>();
551 map.put(FOLLOW_JSON_KEY,
552 Long.parseLong(abstractTransfer.transferArgs.getFollowId()));
553 abstractTransfer.transferArgs.setTransferInfo(
554 abstractTransfer.transferArgs.getTransferInfo() + " " +
555 JsonHandler.writeAsStringEscaped(map));
556 }
557 }
558 }
559
560
561
562
563
564
565
566 public static void analyzeFollow(final TransferArgs transferArgs1) {
567 if (transferArgs1.getFollowId() != null &&
568 transferArgs1.getTransferInfo() != null) {
569 final Map<String, Object> map =
570 DbTaskRunner.getMapFromString(transferArgs1.getTransferInfo());
571 if (map.containsKey(FOLLOW_JSON_KEY)) {
572 transferArgs1.setFollowId(map.get(FOLLOW_JSON_KEY).toString());
573 }
574 if (transferArgs1.getFollowId().isEmpty()) {
575 final long longUuid = LongUuid.getLongUuid();
576 map.put(FOLLOW_JSON_KEY, longUuid);
577 transferArgs1.setTransferInfo(transferArgs1.getTransferInfo() + " " +
578 JsonHandler.writeAsStringEscaped(map));
579 transferArgs1.setFollowId(Long.toString(longUuid));
580 } else {
581 if (map.size() > 1) {
582 transferArgs1.setTransferInfo(transferArgs1.getTransferInfo() + " " +
583 JsonHandler.writeAsStringEscaped(map));
584 }
585 }
586 }
587 }
588
589 private String filename;
590 private String rulename;
591 private String transferInfo;
592 private boolean isMD5;
593 private String remoteHost;
594 private int blocksize = 0x10000;
595 private long id = ILLEGALVALUE;
596 private Timestamp startTime;
597 private String followId;
598 private boolean normalInfoAsWarn = true;
599 private boolean nolog = false;
600
601
602
603
604 public TransferArgs() {
605
606 }
607
608 public final String getFilename() {
609 return filename;
610 }
611
612 public final TransferArgs setFilename(final String filename) {
613 this.filename = filename;
614 return this;
615 }
616
617 public final String getRulename() {
618 return rulename;
619 }
620
621 public final TransferArgs setRulename(final String rulename) {
622 this.rulename = rulename;
623 return this;
624 }
625
626 public final String getTransferInfo() {
627 return transferInfo;
628 }
629
630 public final TransferArgs setTransferInfo(final String transferInfo) {
631 this.transferInfo = transferInfo;
632 return this;
633 }
634
635 public final boolean isMD5() {
636 return isMD5;
637 }
638
639 public final TransferArgs setMD5(final boolean md5) {
640 isMD5 = md5;
641 return this;
642 }
643
644 public final String getRemoteHost() {
645 return remoteHost;
646 }
647
648 public final TransferArgs setRemoteHost(final String remoteHost) {
649 this.remoteHost = remoteHost;
650 return this;
651 }
652
653 public final int getBlockSize() {
654 return blocksize;
655 }
656
657 public final TransferArgs setBlockSize(final int blocksize) {
658 this.blocksize = blocksize;
659 return this;
660 }
661
662 public final long getId() {
663 return id;
664 }
665
666 public final TransferArgs setId(final long id) {
667 this.id = id;
668 return this;
669 }
670
671 public final Timestamp getStartTime() {
672 return startTime;
673 }
674
675 public final TransferArgs setStartTime(final Timestamp startTime) {
676 this.startTime = startTime;
677 return this;
678 }
679
680 public final String getFollowId() {
681 return followId;
682 }
683
684 public final TransferArgs setFollowId(final String followId) {
685 this.followId = followId;
686 return this;
687 }
688
689 public final boolean isNormalInfoAsWarn() {
690 return normalInfoAsWarn;
691 }
692
693 public final TransferArgs setNormalInfoAsWarn(
694 final boolean normalInfoAsWarn) {
695 this.normalInfoAsWarn = normalInfoAsWarn;
696 return this;
697 }
698
699 public final boolean isNolog() {
700 return nolog;
701 }
702
703 public final TransferArgs setNolog(final boolean nolog) {
704 this.nolog = nolog;
705 return this;
706 }
707 }