1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.openr66.client;
21
22 import org.waarp.common.command.exception.CommandAbstractException;
23 import org.waarp.common.database.data.AbstractDbData.UpdatedInfo;
24 import org.waarp.common.database.exception.WaarpDatabaseException;
25 import org.waarp.common.logging.SysErrLogger;
26 import org.waarp.common.logging.WaarpLogger;
27 import org.waarp.common.logging.WaarpLoggerFactory;
28 import org.waarp.openr66.client.utils.OutputFormat;
29 import org.waarp.openr66.client.utils.OutputFormat.FIELDS;
30 import org.waarp.openr66.commander.ClientRunner;
31 import org.waarp.openr66.configuration.FileBasedConfiguration;
32 import org.waarp.openr66.context.ErrorCode;
33 import org.waarp.openr66.context.R66Result;
34 import org.waarp.openr66.context.R66Session;
35 import org.waarp.openr66.context.filesystem.R66Dir;
36 import org.waarp.openr66.context.filesystem.R66File;
37 import org.waarp.openr66.context.task.exception.OpenR66RunnerErrorException;
38 import org.waarp.openr66.database.data.DbHostAuth;
39 import org.waarp.openr66.database.data.DbRule;
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 import org.waarp.openr66.protocol.configuration.PartnerConfiguration;
44 import org.waarp.openr66.protocol.exception.OpenR66DatabaseGlobalException;
45 import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoConnectionException;
46 import org.waarp.openr66.protocol.exception.OpenR66ProtocolPacketException;
47 import org.waarp.openr66.protocol.localhandler.LocalChannelReference;
48 import org.waarp.openr66.protocol.localhandler.packet.AbstractLocalPacket;
49 import org.waarp.openr66.protocol.localhandler.packet.InformationPacket.ASKENUM;
50 import org.waarp.openr66.protocol.localhandler.packet.RequestPacket;
51 import org.waarp.openr66.protocol.localhandler.packet.ValidPacket;
52 import org.waarp.openr66.protocol.networkhandler.NetworkTransaction;
53 import org.waarp.openr66.protocol.utils.ChannelUtils;
54 import org.waarp.openr66.protocol.utils.FileUtils;
55 import org.waarp.openr66.protocol.utils.R66Future;
56
57 import java.io.File;
58 import java.net.SocketAddress;
59 import java.sql.Timestamp;
60 import java.util.ArrayList;
61 import java.util.List;
62 import java.util.regex.Pattern;
63
64 import static org.waarp.common.database.DbConstant.*;
65 import static org.waarp.common.file.filesystembased.FilesystemBasedFileImpl.*;
66
67
68
69
70 public abstract class AbstractTransfer implements Runnable {
71 private static final Pattern COMPILE_NEWLINE = Pattern.compile("\n");
72 public static final String TIMESTAMP_FORMAT = "yyyyMMddHHmmss";
73
74
75
76 protected static WaarpLogger logger;
77
78 protected static final String INFO_ARGS =
79 Messages.getString("AbstractTransfer.0")
80 + Messages.getString("Message.OutputFormat");
81
82 protected static final String NO_INFO_ARGS = "noinfo";
83
84 protected final TransferArgs transferArgs = new TransferArgs();
85 protected final R66Future future;
86 protected boolean normalInfoAsWarn = true;
87
88
89
90
91
92
93 protected AbstractTransfer(final Class<?> clasz, final R66Future future,
94 final TransferArgs transferArgs) {
95 this(clasz, future, transferArgs.getFilename(), transferArgs.getRulename(),
96 transferArgs.getTransferInfo(), transferArgs.isMD5(),
97 transferArgs.getRemoteHost(), transferArgs.getBlockSize(),
98 transferArgs.getId(), transferArgs.getStartTime());
99 }
100
101
102
103
104
105
106
107
108
109
110
111
112 protected AbstractTransfer(final Class<?> clasz, final R66Future future,
113 final String filename, final String rulename,
114 final String transferInfo, final boolean isMD5,
115 final String remoteHost, final int blocksize,
116 final long id, final Timestamp timestart) {
117 if (logger == null) {
118 logger = WaarpLoggerFactory.getLogger(clasz);
119 }
120 this.future = future;
121 this.transferArgs.setFilename(filename);
122 this.transferArgs.setRulename(rulename);
123 this.transferArgs.setTransferInfo(transferInfo);
124 this.transferArgs.setMD5(isMD5);
125 if (Configuration.configuration.getAliases().containsKey(remoteHost)) {
126 this.transferArgs.setRemoteHost(
127 Configuration.configuration.getAliases().get(remoteHost));
128 } else {
129 this.transferArgs.setRemoteHost(remoteHost);
130 }
131 this.transferArgs.setBlockSize(blocksize);
132 this.transferArgs.setId(id);
133 transferArgs.setStartTime(timestart);
134 }
135
136
137
138
139
140
141
142
143
144 public static boolean sendValidPacket(final DbHostAuth host,
145 final LocalChannelReference localChannelReference,
146 final AbstractLocalPacket packet,
147 final R66Future future) {
148 if (logger == null) {
149 logger = WaarpLoggerFactory.getLogger(AbstractTransfer.class);
150 }
151 try {
152 ChannelUtils.writeAbstractLocalPacket(localChannelReference, packet,
153 true);
154 } catch (final OpenR66ProtocolPacketException e) {
155 RequestTransfer.logger.error(
156 Messages.getString("RequestTransfer.63") + host);
157 localChannelReference.close();
158 RequestTransfer.logger.debug("Bad Protocol", e);
159 future.setResult(
160 new R66Result(e, null, true, ErrorCode.TransferError, null));
161 future.setFailure(e);
162 return false;
163 }
164 future.awaitOrInterruptible();
165
166 localChannelReference.close();
167 return true;
168 }
169
170
171
172
173
174
175 protected final DbTaskRunner initRequest() {
176 final DbRule dbRule;
177 try {
178 dbRule = new DbRule(transferArgs.getRulename());
179 } catch (final WaarpDatabaseException e) {
180 logger.error("Cannot get Rule: " + transferArgs.getRulename() + ": {}",
181 e.getMessage(), e);
182 future.setResult(
183 new R66Result(new OpenR66DatabaseGlobalException(e), null, true,
184 ErrorCode.Internal, null));
185 future.setFailure(e);
186 return null;
187 }
188 int mode = dbRule.getMode();
189 if (transferArgs.isMD5()) {
190 mode = RequestPacket.getModeMD5(mode);
191 }
192 final DbTaskRunner taskRunner;
193 if (transferArgs.getId() != ILLEGALVALUE) {
194 try {
195 taskRunner = new DbTaskRunner(transferArgs.getId(),
196 transferArgs.getRemoteHost());
197 } catch (final WaarpDatabaseException e) {
198 logger.error("Cannot get task: {}", e.getMessage());
199 future.setResult(
200 new R66Result(new OpenR66DatabaseGlobalException(e), null, true,
201 ErrorCode.QueryRemotelyUnknown, null));
202 future.setFailure(e);
203 return null;
204 }
205
206 taskRunner.setSenderByRequestToValidate(true);
207 if (transferArgs.getTransferInfo() != null &&
208 !transferArgs.getTransferInfo().equals(NO_INFO_ARGS)) {
209 taskRunner.setFileInformation(transferArgs.getTransferInfo());
210 }
211 if (transferArgs.getStartTime() != null) {
212 taskRunner.setStart(transferArgs.getStartTime());
213 }
214 } else {
215 long originalSize = -1;
216 if (RequestPacket.isSendMode(mode) &&
217 !RequestPacket.isThroughMode(mode)) {
218 File file = new File(transferArgs.getFilename());
219
220 try {
221 final R66Session session = new R66Session(false);
222 session.getAuth().specialNoSessionAuth(false,
223 Configuration.configuration.getHostId());
224 session.getDir().changeDirectory(dbRule.getSendPath());
225 final R66File filer66 =
226 FileUtils.getFile(logger, session, transferArgs.getFilename(),
227 true, true, false, null);
228 file = filer66.getTrueFile();
229 } catch (final CommandAbstractException ignored) {
230 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
231 } catch (final OpenR66RunnerErrorException ignored) {
232 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
233 }
234 if (canRead(file)) {
235 originalSize = file.length();
236 if (originalSize == 0) {
237 originalSize = -1;
238 }
239 }
240 }
241 logger.debug("Filesize: {}", originalSize);
242 final String sep =
243 PartnerConfiguration.getSeparator(transferArgs.getRemoteHost());
244 final RequestPacket request =
245 new RequestPacket(transferArgs.getRulename(), mode,
246 transferArgs.getFilename(),
247 transferArgs.getBlockSize(), 0,
248 transferArgs.getId(),
249 transferArgs.getTransferInfo(), originalSize, sep);
250
251 final boolean isRetrieve = !RequestPacket.isRecvMode(request.getMode());
252 try {
253 taskRunner = new DbTaskRunner(dbRule, isRetrieve, request,
254 transferArgs.getRemoteHost(),
255 transferArgs.getStartTime());
256 } catch (final WaarpDatabaseException e) {
257 logger.error("Cannot get task: {}", e.getMessage());
258 future.setResult(
259 new R66Result(new OpenR66DatabaseGlobalException(e), null, true,
260 ErrorCode.Internal, null));
261 future.setFailure(e);
262 return null;
263 }
264 }
265 try {
266 taskRunner.saveStatus();
267 } catch (final OpenR66RunnerErrorException e) {
268 logger.error("Cannot save task: {}", e.getMessage());
269 future.setResult(
270 new R66Result(new OpenR66DatabaseGlobalException(e), null, true,
271 ErrorCode.Internal, null));
272 future.setFailure(e);
273 return null;
274 }
275 return taskRunner;
276 }
277
278 protected static String rhost;
279 protected static String localFilename;
280 protected static String rule;
281 protected static String transferInfo;
282 protected static boolean ismd5;
283 protected static int block = 0x10000;
284
285
286 protected static boolean nolog;
287 protected static long idt = ILLEGALVALUE;
288 protected static Timestamp ttimestart;
289 protected static boolean snormalInfoAsWarn = true;
290 protected static String sFollowId;
291
292 protected final static void clear() {
293 rhost = null;
294 localFilename = null;
295 rule = null;
296 transferInfo = null;
297 ismd5 = false;
298 block = 0x10000;
299 nolog = false;
300 idt = ILLEGALVALUE;
301 ttimestart = null;
302 snormalInfoAsWarn = true;
303 sFollowId = null;
304 }
305
306
307
308
309
310
311
312
313
314
315 protected static boolean getParams(final String[] args,
316 final boolean submitOnly) {
317 if (logger == null) {
318 logger = WaarpLoggerFactory.getLogger(AbstractTransfer.class);
319 }
320 if (args.length < 2) {
321 logger.error(INFO_ARGS);
322 return false;
323 }
324 if (submitOnly) {
325 if (!FileBasedConfiguration.setSubmitClientConfigurationFromXml(
326 Configuration.configuration, args[0])) {
327 logger.error(Messages.getString(
328 "Configuration.NeedCorrectConfig"));
329 return false;
330 }
331 } else if (!FileBasedConfiguration.setClientConfigurationFromXml(
332 Configuration.configuration, args[0])) {
333 logger.error(
334 Messages.getString("Configuration.NeedCorrectConfig"));
335 return false;
336 }
337 final TransferArgs transferArgsLocal = getParamsInternal(1, args);
338 if (transferArgsLocal == null) {
339 return false;
340 }
341 rhost = transferArgsLocal.getRemoteHost();
342 localFilename = transferArgsLocal.getFilename();
343 rule = transferArgsLocal.getRulename();
344 transferInfo = transferArgsLocal.getTransferInfo();
345 ismd5 = transferArgsLocal.isMD5();
346 block = transferArgsLocal.getBlockSize();
347 idt = transferArgsLocal.getId();
348 ttimestart = transferArgsLocal.getStartTime();
349 sFollowId = transferArgsLocal.getFollowId();
350 return true;
351 }
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380 public static TransferArgs getParamsInternal(final int rank,
381 final String[] args) {
382 if (logger == null) {
383 logger = WaarpLoggerFactory.getLogger(AbstractTransfer.class);
384 }
385 final TransferArgs transferArgs1 =
386 TransferArgs.getParamsInternal(rank, args, true);
387 if (transferArgs1 == null) {
388 return null;
389 }
390 snormalInfoAsWarn = transferArgs1.isNormalInfoAsWarn();
391 nolog = transferArgs1.isNolog();
392 return transferArgs1;
393 }
394
395
396
397
398
399
400
401 protected final void finalizeInErrorTransferRequest(final ClientRunner runner,
402 final DbTaskRunner taskRunner,
403 final ErrorCode code) {
404 if (runner.getLocalChannelReference() != null) {
405 runner.getLocalChannelReference().setErrorMessage(code.getMesg(), code);
406 }
407 taskRunner.setErrorTask();
408 try {
409 taskRunner.forceSaveStatus();
410 taskRunner.run();
411 taskRunner.saveStatus();
412 } catch (final OpenR66RunnerErrorException e1) {
413 runner.changeUpdatedInfo(UpdatedInfo.INERROR, code, true);
414 }
415 }
416
417 public final void setNormalInfoAsWarn(final boolean normalInfoAsWarn1) {
418 normalInfoAsWarn = normalInfoAsWarn1;
419 }
420
421 public final List<String> getRemoteFiles(final String[] localfilenames,
422 final String requested,
423 final NetworkTransaction networkTransaction) {
424 final List<String> files = new ArrayList<String>();
425 for (final String filenameNew : localfilenames) {
426 if (!(filenameNew.contains("*") || filenameNew.contains("?") ||
427 filenameNew.contains("~"))) {
428 files.add(filenameNew);
429 } else {
430
431 final R66Future futureInfo = new R66Future(true);
432 logger.info("{} {} to {}", Messages.getString("Transfer.3"),
433 filenameNew, requested);
434 final RequestInformation info =
435 new RequestInformation(futureInfo, requested,
436 transferArgs.getRulename(), filenameNew,
437 (byte) ASKENUM.ASKLIST.ordinal(), -1, false,
438 networkTransaction);
439 info.run();
440 futureInfo.awaitOrInterruptible();
441 if (futureInfo.isSuccess()) {
442 final ValidPacket valid =
443 (ValidPacket) futureInfo.getResult().getOther();
444 if (valid != null) {
445 final String line = valid.getSheader();
446 final String[] lines = COMPILE_NEWLINE.split(line);
447 for (final String string : lines) {
448 final File tmpFile = new File(string);
449 files.add(tmpFile.getPath());
450 }
451 }
452 } else {
453 logger.error(Messages.getString("Transfer.6") + filenameNew + " to " +
454 requested + ": " + (futureInfo.getCause() == null? "" :
455 futureInfo.getCause().getMessage()));
456 }
457 }
458 }
459 return files;
460 }
461
462 public final List<String> getLocalFiles(final DbRule dbrule,
463 final String[] localfilenames) {
464 final List<String> files = new ArrayList<String>();
465 final R66Session session = new R66Session(false);
466 session.getAuth().specialNoSessionAuth(false,
467 Configuration.configuration.getHostId());
468 final R66Dir dir = new R66Dir(session);
469 try {
470 dir.changeDirectory(dbrule.getSendPath());
471 } catch (final CommandAbstractException e) {
472 SysErrLogger.FAKE_LOGGER.ignoreLog(e);
473 }
474 if (localfilenames != null) {
475 for (final String filenameNew : localfilenames) {
476 if (!(filenameNew.contains("*") || filenameNew.contains("?") ||
477 filenameNew.contains("~"))) {
478 logger.info("Direct add: {}", filenameNew);
479 files.add(filenameNew);
480 } else {
481
482 logger.info("Local Ask for {} from {}", filenameNew,
483 dir.getFullPath());
484 final List<String> list;
485 try {
486 list = dir.list(filenameNew);
487 if (list != null) {
488 files.addAll(list);
489 }
490 } catch (final CommandAbstractException e) {
491 logger.warn(
492 Messages.getString("Transfer.14") + filenameNew + " : " +
493 e.getMessage());
494 }
495 }
496 }
497 }
498 return files;
499 }
500
501
502
503
504
505
506
507
508
509
510 public static LocalChannelReference tryConnect(final DbHostAuth host,
511 final R66Future future,
512 final NetworkTransaction networkTransaction) {
513 if (logger == null) {
514 logger = WaarpLoggerFactory.getLogger(AbstractTransfer.class);
515 }
516 logger.info("Try RequestTransfer to {}", host);
517 final SocketAddress socketAddress;
518 try {
519 socketAddress = host.getSocketAddress();
520 } catch (final IllegalArgumentException e) {
521 logger.debug("Cannot connect to {}", host);
522 future.setResult(new R66Result(new OpenR66ProtocolNoConnectionException(
523 "Cannot connect to server " + host.getHostid()), null, true,
524 ErrorCode.ConnectionImpossible, null));
525 future.setFailure(future.getResult().getException());
526 return null;
527 }
528 final boolean isSSL = host.isSsl();
529
530 final LocalChannelReference localChannelReference =
531 networkTransaction.createConnectionWithRetry(socketAddress, isSSL,
532 future);
533 if (localChannelReference == null) {
534 logger.debug("Cannot connect to {}", host);
535 future.setResult(new R66Result(new OpenR66ProtocolNoConnectionException(
536 "Cannot connect to server " + host.getHostid()), null, true,
537 ErrorCode.ConnectionImpossible, null));
538 future.setFailure(future.getResult().getException());
539 return null;
540 }
541 return localChannelReference;
542 }
543
544
545 protected static void prepareKoOutputFormat(final R66Future future,
546 final R66Result result,
547 final OutputFormat outputFormat) {
548 if (logger == null) {
549 logger = WaarpLoggerFactory.getLogger(AbstractTransfer.class);
550 }
551 partialOutputFormat(result.getRunner(), outputFormat);
552 if (result.getRunner().getErrorInfo() == ErrorCode.Warning) {
553 outputFormat.setValue(FIELDS.status.name(), 1);
554 outputFormat.setValue(FIELDS.statusTxt.name(),
555 Messages.getString("Transfer.Status") +
556 Messages.getString(
557 "RequestInformation.Warned"));
558 } else {
559 outputFormat.setValue(FIELDS.status.name(), 2);
560 outputFormat.setValue(FIELDS.statusTxt.name(),
561 Messages.getString("Transfer.Status") +
562 Messages.getString(
563 "RequestInformation.Failure"));
564 }
565 final String mesg = future.getCause() != null
566 ? future.getCause().getMessage() : "";
567 if (result.getRunner().getErrorInfo() == ErrorCode.Warning) {
568 logger.warn(outputFormat.loggerOut() + " : {}" + mesg);
569 } else {
570 logger.error(outputFormat.loggerOut() + " : {}" + mesg);
571 }
572 if (future.getCause() != null) {
573 outputFormat.setValue(FIELDS.error.name(),
574 future.getCause().getMessage());
575 }
576 }
577
578 protected static void prepareKoOutputFormat(final R66Future future,
579 final OutputFormat outputFormat) {
580 if (logger == null) {
581 logger = WaarpLoggerFactory.getLogger(AbstractTransfer.class);
582 }
583 outputFormat.setValue(FIELDS.status.name(), 2);
584 outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
585 "Transfer.FailedNoId"));
586 outputFormat.setValue(FIELDS.remote.name(), rhost);
587 logger.error(outputFormat.loggerOut(), future.getCause());
588 outputFormat.setValue(FIELDS.error.name(), future.getCause().getMessage());
589 }
590
591 protected static void prepareOkOutputFormat(final long delay,
592 final R66Result result,
593 final OutputFormat outputFormat) {
594 if (logger == null) {
595 logger = WaarpLoggerFactory.getLogger(AbstractTransfer.class);
596 }
597 if (result.getRunner().getErrorInfo() == ErrorCode.Warning) {
598 outputFormat.setValue(FIELDS.status.name(), 1);
599 outputFormat.setValue(FIELDS.statusTxt.name(),
600 Messages.getString("Transfer.Status") +
601 Messages.getString(
602 "RequestInformation.Warned"));
603 } else {
604 outputFormat.setValue(FIELDS.status.name(), 0);
605 outputFormat.setValue(FIELDS.statusTxt.name(),
606 Messages.getString("Transfer.Status") +
607 Messages.getString(
608 "RequestInformation.Success"));
609 }
610 partialOutputFormat(result.getRunner(), outputFormat);
611 outputFormat.setValue("filefinal", result.getFile() != null?
612 result.getFile().toString() : "no file");
613 outputFormat.setValue("delay", delay);
614 }
615
616 private static void partialOutputFormat(final DbTaskRunner runner,
617 final OutputFormat outputFormat) {
618 if (logger == null) {
619 logger = WaarpLoggerFactory.getLogger(AbstractTransfer.class);
620 }
621 outputFormat.setValue(FIELDS.remote.name(), rhost);
622 outputFormat.setValue(FIELDS.ruleid.name(), runner.getRuleId());
623 outputFormat.setValueString(runner.getJson());
624 outputFormat.setValue(FIELDS.statusCode.name(),
625 runner.getErrorInfo().getCode());
626 outputFormat.setValue(FIELDS.specialid.name(), runner.getSpecialId());
627 outputFormat.setValue(FIELDS.finalPath.name(), runner.getFilename());
628 outputFormat.setValue(FIELDS.requested.name(), runner.getRequested());
629 outputFormat.setValue(FIELDS.requester.name(), runner.getRequester());
630 outputFormat.setValue(FIELDS.fileInformation.name(),
631 runner.getFileInformation());
632 outputFormat.setValue(FIELDS.transferInformation.name(),
633 runner.getTransferInfo());
634 outputFormat.setValue(FIELDS.originalSize.name(), runner.getOriginalSize());
635 outputFormat.setValue(FIELDS.originalPath.name(),
636 runner.getOriginalFilename());
637 }
638
639 public static void prepareSubmitKoOutputFormat(final R66Future future,
640 final DbTaskRunner runner,
641 final OutputFormat outputFormat) {
642 if (logger == null) {
643 logger = WaarpLoggerFactory.getLogger(AbstractTransfer.class);
644 }
645 outputFormat.setValue(FIELDS.status.name(), 2);
646 if (runner == null) {
647 outputFormat.setValue(FIELDS.statusTxt.name(),
648 Messages.getString("SubmitTransfer.3") +
649 Messages.getString(
650 "Transfer.FailedNoId"));
651 outputFormat.setValue(FIELDS.remote.name(), rhost);
652 } else {
653 outputFormat.setValue(FIELDS.statusTxt.name(),
654 Messages.getString("SubmitTransfer.3") +
655 Messages.getString(
656 "RequestInformation.Failure"));
657 partialOutputFormat(runner, outputFormat);
658 }
659 logger.error(outputFormat.loggerOut(), future.getCause());
660 if (future.getCause() != null) {
661 outputFormat.setValue(FIELDS.error.name(),
662 future.getCause().getMessage());
663 }
664 }
665
666 public static void prepareSubmitOkOutputFormat(final DbTaskRunner runner,
667 final OutputFormat outputFormat) {
668 if (logger == null) {
669 logger = WaarpLoggerFactory.getLogger(AbstractTransfer.class);
670 }
671 outputFormat.setValue(FIELDS.status.name(), 0);
672 outputFormat.setValue(FIELDS.statusTxt.name(),
673 Messages.getString("SubmitTransfer.3") +
674 Messages.getString(
675 "RequestInformation.Success"));
676 partialOutputFormat(runner, outputFormat);
677 }
678
679 }