View Javadoc
1   /*
2    * This file is part of Waarp Project (named also Waarp or GG).
3    *
4    *  Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
5    *  tags. See the COPYRIGHT.txt in the distribution for a full listing of
6    * individual contributors.
7    *
8    *  All Waarp Project is free software: you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License, or (at your
11   * option) any later version.
12   *
13   * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
14   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16   *
17   *  You should have received a copy of the GNU General Public License along with
18   * Waarp . If not, see <http://www.gnu.org/licenses/>.
19   */
20  package org.waarp.openr66.client;
21  
22  import org.waarp.common.database.data.AbstractDbData.UpdatedInfo;
23  import org.waarp.common.database.exception.WaarpDatabaseException;
24  import org.waarp.common.logging.SysErrLogger;
25  import org.waarp.common.logging.WaarpLogger;
26  import org.waarp.common.logging.WaarpLoggerFactory;
27  import org.waarp.common.logging.WaarpSlf4JLoggerFactory;
28  import org.waarp.common.utility.WaarpSystemUtil;
29  import org.waarp.openr66.client.utils.OutputFormat;
30  import org.waarp.openr66.client.utils.OutputFormat.FIELDS;
31  import org.waarp.openr66.commander.CommanderNoDb;
32  import org.waarp.openr66.configuration.FileBasedConfiguration;
33  import org.waarp.openr66.context.ErrorCode;
34  import org.waarp.openr66.context.R66FiniteDualStates;
35  import org.waarp.openr66.context.R66Result;
36  import org.waarp.openr66.context.authentication.R66Auth;
37  import org.waarp.openr66.context.task.exception.OpenR66RunnerErrorException;
38  import org.waarp.openr66.database.data.DbHostAuth;
39  import org.waarp.openr66.database.data.DbTaskRunner;
40  import org.waarp.openr66.protocol.configuration.Configuration;
41  import org.waarp.openr66.protocol.configuration.Messages;
42  import org.waarp.openr66.protocol.configuration.PartnerConfiguration;
43  import org.waarp.openr66.protocol.exception.OpenR66DatabaseGlobalException;
44  import org.waarp.openr66.protocol.exception.OpenR66Exception;
45  import org.waarp.openr66.protocol.exception.OpenR66ProtocolBusinessException;
46  import org.waarp.openr66.protocol.localhandler.LocalChannelReference;
47  import org.waarp.openr66.protocol.localhandler.packet.AbstractLocalPacket;
48  import org.waarp.openr66.protocol.localhandler.packet.JsonCommandPacket;
49  import org.waarp.openr66.protocol.localhandler.packet.LocalPacketFactory;
50  import org.waarp.openr66.protocol.localhandler.packet.ValidPacket;
51  import org.waarp.openr66.protocol.localhandler.packet.json.RestartTransferJsonPacket;
52  import org.waarp.openr66.protocol.localhandler.packet.json.StopOrCancelJsonPacket;
53  import org.waarp.openr66.protocol.networkhandler.NetworkTransaction;
54  import org.waarp.openr66.protocol.utils.R66Future;
55  
56  import java.text.ParseException;
57  import java.text.SimpleDateFormat;
58  import java.util.Date;
59  
60  import static org.waarp.common.database.DbConstant.*;
61  
62  /**
63   * Class to request information or request cancellation or restart
64   */
65  public class RequestTransfer implements Runnable {
66    private static final String REQUEST_ON_TRANSFER = "Request on Transfer";
67  
68    /**
69     * Internal Logger
70     */
71    static volatile WaarpLogger logger;
72  
73    protected static String infoArgs =
74        Messages.getString("RequestTransfer.0") //$NON-NLS-1$
75        + Messages.getString("Message.OutputFormat");
76  
77    protected final NetworkTransaction networkTransaction;
78    final R66Future future;
79    final long specialId;
80    final String requested;
81    final String requester;
82    final boolean cancel;
83    final boolean stop;
84    final boolean restart;
85    final String restarttime;
86    boolean normalInfoAsWarn = true;
87  
88    static long sspecialId;
89    static String srequested;
90    static String srequester;
91    static String rhost;
92    static boolean scancel;
93    static boolean sstop;
94    static boolean srestart;
95    static String srestarttime;
96    protected static boolean snormalInfoAsWarn = true;
97  
98    /**
99     * Parse the parameter and set current values
100    *
101    * @param args
102    *
103    * @return True if all parameters were found and correct
104    */
105   protected static boolean getParams(final String[] args) {
106     if (logger == null) {
107       logger = WaarpLoggerFactory.getLogger(RequestTransfer.class);
108     }
109     infoArgs = Messages.getString("RequestTransfer.0") +
110                Messages.getString("Message.OutputFormat"); //$NON-NLS-1$
111     if (args.length < 5) {
112       logger.error(infoArgs);
113       return false;
114     }
115     if (!FileBasedConfiguration.setClientConfigurationFromXml(
116         Configuration.configuration, args[0])) {
117       logger.error(
118           Messages.getString("Configuration.NeedCorrectConfig")); //$NON-NLS-1$
119       return false;
120     }
121     for (int i = 1; i < args.length; i++) {
122       if ("-id".equalsIgnoreCase(args[i])) {
123         i++;
124         try {
125           sspecialId = Long.parseLong(args[i]);
126         } catch (final NumberFormatException e) {
127           logger.error(
128               Messages.getString("RequestTransfer.1") + args[i] + ": {}",
129               e.getMessage()); //$NON-NLS-1$
130           return false;
131         }
132       } else if ("-to".equalsIgnoreCase(args[i])) {
133         i++;
134         srequested = args[i];
135         if (Configuration.configuration.getAliases().containsKey(srequested)) {
136           srequested = Configuration.configuration.getAliases().get(srequested);
137         }
138         rhost = srequested;
139         try {
140           srequester = Configuration.configuration.getHostId(srequested);
141         } catch (final WaarpDatabaseException e) {
142           logger.error(
143               Messages.getString("RequestTransfer.5") + srequested + ": {}",
144               e.getMessage()); //$NON-NLS-1$
145           return false;
146         }
147       } else if ("-from".equalsIgnoreCase(args[i])) {
148         i++;
149         srequester = args[i];
150         if (Configuration.configuration.getAliases().containsKey(srequester)) {
151           srequester = Configuration.configuration.getAliases().get(srequester);
152         }
153         rhost = srequester;
154         try {
155           srequested = Configuration.configuration.getHostId(srequester);
156         } catch (final WaarpDatabaseException e) {
157           logger.error(
158               Messages.getString("RequestTransfer.5") + srequester + ": {}",
159               e.getMessage()); //$NON-NLS-1$
160           return false;
161         }
162       } else if ("-cancel".equalsIgnoreCase(args[i])) {
163         scancel = true;
164       } else if ("-stop".equalsIgnoreCase(args[i])) {
165         sstop = true;
166       } else if ("-restart".equalsIgnoreCase(args[i])) {
167         srestart = true;
168       } else if ("-start".equalsIgnoreCase(args[i])) {
169         i++;
170         srestarttime = args[i];
171       } else if ("-logWarn".equalsIgnoreCase(args[i])) {
172         snormalInfoAsWarn = true;
173       } else if ("-notlogWarn".equalsIgnoreCase(args[i])) {
174         snormalInfoAsWarn = false;
175       } else if ("-delay".equalsIgnoreCase(args[i])) {
176         i++;
177         final SimpleDateFormat dateFormat =
178             new SimpleDateFormat(AbstractTransfer.TIMESTAMP_FORMAT);
179         if (args[i].charAt(0) == '+') {
180           final Date date = new Date(System.currentTimeMillis() +
181                                      Long.parseLong(args[i].substring(1)));
182           srestarttime = dateFormat.format(date);
183         } else {
184           final Date date = new Date(Long.parseLong(args[i]));
185           srestarttime = dateFormat.format(date);
186         }
187       }
188       OutputFormat.getParams(args);
189     }
190     if (scancel && srestart || scancel && sstop || srestart && sstop) {
191       logger.error(
192           Messages.getString("RequestTransfer.15") + infoArgs); //$NON-NLS-1$
193       return false;
194     }
195     if (sspecialId == ILLEGALVALUE || srequested == null) {
196       logger.error(
197           Messages.getString("RequestTransfer.16") + infoArgs); //$NON-NLS-1$
198       return false;
199     }
200 
201     return true;
202   }
203 
204   /**
205    * @param future
206    * @param specialId
207    * @param requested
208    * @param requester
209    * @param cancel
210    * @param stop
211    * @param restart
212    * @param networkTransaction
213    */
214   public RequestTransfer(final R66Future future, final long specialId,
215                          final String requested, final String requester,
216                          final boolean cancel, final boolean stop,
217                          final boolean restart,
218                          final NetworkTransaction networkTransaction) {
219     this(future, specialId, requested, requester, cancel, stop, restart, null,
220          networkTransaction);
221   }
222 
223   /**
224    * @param future
225    * @param specialId
226    * @param requested
227    * @param requester
228    * @param cancel
229    * @param stop
230    * @param restart
231    * @param restarttime in yyyyMMddHHmmss format
232    * @param networkTransaction
233    */
234   public RequestTransfer(final R66Future future, final long specialId,
235                          final String requested, final String requester,
236                          final boolean cancel, final boolean stop,
237                          final boolean restart, final String restarttime,
238                          final NetworkTransaction networkTransaction) {
239     this.future = future;
240     this.specialId = specialId;
241     this.requested = requested;
242     this.requester = requester;
243     this.cancel = cancel;
244     this.stop = stop;
245     this.restart = restart;
246     this.restarttime = restarttime;
247     this.networkTransaction = networkTransaction;
248     if (logger == null) {
249       logger = WaarpLoggerFactory.getLogger(RequestTransfer.class);
250     }
251   }
252 
253   @Override
254   public void run() {
255     DbTaskRunner runner = null;
256     try {
257       if (logger == null) {
258         logger = WaarpLoggerFactory.getLogger(RequestTransfer.class);
259       }
260       try {
261         runner = new DbTaskRunner(null, null, specialId, requester, requested);
262         logger.info("Found previous Runner: {}", runner);
263       } catch (final WaarpDatabaseException e) {
264         // Maybe we can ask to the remote
265         final R66Future futureInfo = new R66Future(true);
266         final RequestInformation requestInformation =
267             new RequestInformation(futureInfo, requested, null, null, (byte) -1,
268                                    specialId, true, networkTransaction);
269         requestInformation.normalInfoAsWarn = normalInfoAsWarn;
270         requestInformation.run();
271         futureInfo.awaitOrInterruptible();
272         if (futureInfo.isSuccess()) {
273           final R66Result r66result = futureInfo.getResult();
274           final ValidPacket info = (ValidPacket) r66result.getOther();
275           final String xml = info.getSheader();
276           try {
277             runner = DbTaskRunner.fromStringXml(xml, true);
278             runner.changeUpdatedInfo(UpdatedInfo.TOSUBMIT);
279             // useful ?
280             CommanderNoDb.todoList.add(runner);
281 
282             logger.info("Get Runner from remote: {}", runner);
283             if (runner.getSpecialId() == ILLEGALVALUE || !runner.isSender()) {
284               logger.error(
285                   Messages.getString("RequestTransfer.18")); //$NON-NLS-1$
286               future.setResult(
287                   new R66Result(new OpenR66DatabaseGlobalException(e), null,
288                                 true, ErrorCode.Internal, null));
289               future.setFailure(e);
290               return;
291             }
292             if (runner.isAllDone()) {
293               logger.error(
294                   Messages.getString("RequestTransfer.21")); //$NON-NLS-1$
295               future.setResult(
296                   new R66Result(new OpenR66DatabaseGlobalException(e), null,
297                                 true, ErrorCode.Internal, null));
298               future.setFailure(e);
299               return;
300             }
301           } catch (final OpenR66ProtocolBusinessException e1) {
302             logger.error(
303                 Messages.getString("RequestTransfer.18")); //$NON-NLS-1$
304             future.setResult(
305                 new R66Result(new OpenR66DatabaseGlobalException(e1), null,
306                               true, ErrorCode.Internal, null));
307             future.setFailure(e);
308             return;
309           }
310         } else {
311           logger.error(Messages.getString("RequestTransfer.18")); //$NON-NLS-1$
312           future.setResult(
313               new R66Result(new OpenR66DatabaseGlobalException(e), null, true,
314                             ErrorCode.Internal, null));
315           future.setFailure(e);
316           return;
317         }
318       }
319       if (cancel || stop || restart) {
320         if (cancel) {
321           // Cancel the task and delete any file if in retrieve
322           if (runner.isAllDone()) {
323             // nothing to do since already finished
324             setDone(runner);
325             logger.info("Transfer already finished: {}", runner);
326             future.setResult(
327                 new R66Result(null, true, ErrorCode.TransferOk, runner));
328             future.getResult().setRunner(runner);
329             future.setSuccess();
330           } else {
331             // Send a request of cancel
332             final ErrorCode code =
333                 sendStopOrCancel(LocalPacketFactory.CANCELPACKET);
334             future.setResult(new R66Result(null, true, code, runner));
335             future.getResult().setRunner(runner);
336             switch (code) {
337               case CompleteOk:
338                 logger.info("Transfer cancel requested and done: {}", runner);
339                 future.setSuccess();
340                 break;
341               case TransferOk:
342                 logger.info(
343                     "Transfer cancel requested but already finished: {}",
344                     runner);
345                 future.setSuccess();
346                 break;
347               default:
348                 logger.info("Transfer cancel requested but internal error: {}",
349                             runner);
350                 future.setFailure(new WaarpDatabaseException(
351                     "Transfer cancel requested but internal error"));
352                 break;
353             }
354           }
355         } else if (stop) {
356           // Just stop the task
357           // Send a request
358           final ErrorCode code =
359               sendStopOrCancel(LocalPacketFactory.STOPPACKET);
360           future.setResult(new R66Result(null, true, code, runner));
361           future.getResult().setRunner(runner);
362           switch (code) {
363             case CompleteOk:
364               logger.info("Transfer stop requested and done: {}", runner);
365               future.setSuccess();
366               break;
367             case TransferOk:
368               logger.info("Transfer stop requested but already finished: {}",
369                           runner);
370               future.setSuccess();
371               break;
372             default:
373               logger.info("Transfer stop requested but internal error: {}",
374                           runner);
375               future.setFailure(new WaarpDatabaseException(
376                   "Transfer stop requested but internal error"));
377               break;
378           }
379         } else if (restart) {
380           // Restart if already stopped and not finished
381           final ErrorCode code =
382               sendValid(runner, LocalPacketFactory.VALIDPACKET);
383           future.setResult(new R66Result(null, true, code, runner));
384           future.getResult().setRunner(runner);
385           switch (code) {
386             case QueryStillRunning:
387               logger.info(
388                   "Transfer restart requested but already active and running: {}",
389                   runner);
390               future.setSuccess();
391               break;
392             case Running:
393               logger.info("Transfer restart requested but already running: {}",
394                           runner);
395               future.setSuccess();
396               break;
397             case PreProcessingOk:
398               logger.info("Transfer restart requested and restarted: {}",
399                           runner);
400               future.setSuccess();
401               break;
402             case CompleteOk:
403               logger.info("Transfer restart requested but already finished: {}",
404                           runner);
405               future.setSuccess();
406               break;
407             case RemoteError:
408               logger.info("Transfer restart requested but remote error: {}",
409                           runner);
410               future.setSuccess();
411               break;
412             case PassThroughMode:
413               logger.info(
414                   "Transfer not restarted since it is in PassThrough mode: {}",
415                   runner);
416               future.setSuccess();
417               break;
418             default:
419               logger.info("Transfer restart requested but internal error: {}",
420                           runner);
421               future.setFailure(new WaarpDatabaseException(
422                   "Transfer restart requested but internal error"));
423               break;
424           }
425         }
426       } else {
427         // Only request
428         if (logger.isInfoEnabled()) {
429           logger.info("Transfer information: {}    {}", future.isDone(),
430                       runner.toShortString());
431         }
432         future.setResult(
433             new R66Result(null, true, runner.getErrorInfo(), runner));
434         future.setSuccess();
435       }
436     } finally {
437       if (!future.isDone()) {
438         if (runner != null) {
439           // Default set to success
440           future.setResult(
441               new R66Result(null, true, runner.getErrorInfo(), runner));
442           future.setSuccess();
443         } else {
444           future.setFailure(new WaarpDatabaseException(
445               "Transfer requested but internal error"));
446         }
447       }
448     }
449   }
450 
451   /**
452    * Set the runner to DONE
453    *
454    * @param runner
455    */
456   private void setDone(final DbTaskRunner runner) {
457     if (runner.getUpdatedInfo() != UpdatedInfo.DONE) {
458       runner.changeUpdatedInfo(UpdatedInfo.DONE);
459       runner.forceSaveStatus();
460     }
461   }
462 
463   private ErrorCode sendValid(final DbTaskRunner runner, final byte code) {
464     DbHostAuth host;
465     host = R66Auth.getServerAuth(requester);
466     if (host == null) {
467       logger.error(
468           Messages.getString("RequestTransfer.39") + requester); //$NON-NLS-1$
469       final OpenR66Exception e =
470           new OpenR66RunnerErrorException("Requester host cannot be found");
471       future.setResult(
472           new R66Result(e, null, true, ErrorCode.TransferError, null));
473       future.setFailure(e);
474       return ErrorCode.Internal;
475     }
476     // check if requester is "client" so no connect from him but direct action
477     logger.debug("Requester Host isClient: {}", host.isClient());
478     if (host.isClient()) {
479       if (code == LocalPacketFactory.VALIDPACKET) {
480         if (logger.isInfoEnabled()) {
481           logger.info("{} {}", Messages.getString("RequestTransfer.42"),
482                       runner.toShortString());//$NON-NLS-1$
483         }
484         final R66Future transfer = new R66Future(true);
485         final DirectTransfer transaction =
486             new DirectTransfer(transfer, runner.getRequested(),
487                                runner.getOriginalFilename(), runner.getRuleId(),
488                                runner.getFileInformation(), false,
489                                runner.getBlocksize(), runner.getSpecialId(),
490                                networkTransaction);
491         transaction.normalInfoAsWarn = normalInfoAsWarn;
492         transaction.run();
493         transfer.awaitOrInterruptible();
494         logger.info("Request done with {}",
495                     (transfer.isSuccess()? "success" : "error"));
496         if (transfer.isSuccess()) {
497           future.setResult(
498               new R66Result(null, true, ErrorCode.PreProcessingOk, runner));
499           future.getResult().setRunner(runner);
500           future.setSuccess();
501           return ErrorCode.PreProcessingOk;
502         } else {
503           final R66Result result = transfer.getResult();
504           ErrorCode error = ErrorCode.Internal;
505           if (result != null) {
506             error = result.getCode();
507           }
508           final OpenR66Exception e = new OpenR66RunnerErrorException(
509               "Transfer in direct mode failed: " + error.getMesg());
510           future.setFailure(e);
511           return error;
512         }
513       } else {
514         // get remote host instead
515         host = R66Auth.getServerAuth(requested);
516         if (host == null) {
517           logger.error(Messages.getString("Message.HostNotFound") +
518                        requested); //$NON-NLS-1$
519           final OpenR66Exception e =
520               new OpenR66RunnerErrorException("Requested host cannot be found");
521           future.setResult(
522               new R66Result(e, null, true, ErrorCode.TransferError, null));
523           future.setFailure(e);
524           return ErrorCode.ConnectionImpossible;
525         }
526       }
527     }
528 
529     final LocalChannelReference localChannelReference =
530         AbstractTransfer.tryConnect(host, future, networkTransaction);
531     if (localChannelReference == null) {
532       return ErrorCode.ConnectionImpossible;
533     }
534     final boolean useJson = PartnerConfiguration.useJson(host.getHostid());
535     logger.debug("UseJson: {}", useJson);
536     final AbstractLocalPacket packet;
537     if (useJson) {
538       final RestartTransferJsonPacket node = new RestartTransferJsonPacket();
539       node.setComment(REQUEST_ON_TRANSFER);
540       node.setRequested(requested);
541       node.setRequester(requester);
542       node.setSpecialid(specialId);
543       if (restarttime != null && code == LocalPacketFactory.VALIDPACKET) {
544         // restart time set
545         logger.debug("Restart with time: {}", restarttime);
546         // time to reschedule in yyyyMMddHHmmss format
547         final SimpleDateFormat dateFormat =
548             new SimpleDateFormat(AbstractTransfer.TIMESTAMP_FORMAT);
549         try {
550           final Date date = dateFormat.parse(restarttime);
551           node.setRestarttime(date);
552         } catch (final ParseException ignored) {
553           // nothing
554         }
555       }
556       packet = new JsonCommandPacket(node, code);
557     } else {
558       if (restarttime != null && code == LocalPacketFactory.VALIDPACKET) {
559         // restart time set
560         logger.debug("Restart with time: {}", restarttime);
561         packet = new ValidPacket(REQUEST_ON_TRANSFER,
562                                  requested + ' ' + requester + ' ' + specialId +
563                                  ' ' + restarttime, code);
564       } else {
565         packet = new ValidPacket(REQUEST_ON_TRANSFER,
566                                  requested + ' ' + requester + ' ' + specialId,
567                                  code);
568       }
569     }
570     localChannelReference.sessionNewState(R66FiniteDualStates.VALIDOTHER);
571     if (AbstractTransfer.sendValidPacket(host, localChannelReference, packet,
572                                          future)) {
573       return ErrorCode.Internal;
574     }
575 
576     logger.info(
577         "Request done with " + (future.isSuccess()? "success" : "error"));
578     final R66Result result = future.getResult();
579     if (result != null) {
580       return result.getCode();
581     }
582     return ErrorCode.Internal;
583   }
584 
585   private ErrorCode sendStopOrCancel(final byte code) {
586     final DbHostAuth host;
587     host = R66Auth.getServerAuth(requester);
588     if (host == null) {
589       logger.error(
590           Messages.getString("RequestTransfer.39") + requester); //$NON-NLS-1$
591       final OpenR66Exception e =
592           new OpenR66RunnerErrorException("Requester host cannot be found");
593       future.setResult(
594           new R66Result(e, null, true, ErrorCode.TransferError, null));
595       future.setFailure(e);
596       return ErrorCode.Internal;
597     }
598 
599     final LocalChannelReference localChannelReference =
600         AbstractTransfer.tryConnect(host, future, networkTransaction);
601     if (localChannelReference == null) {
602       return ErrorCode.ConnectionImpossible;
603     }
604 
605     final boolean useJson = PartnerConfiguration.useJson(host.getHostid());
606     logger.debug("UseJson: {}", useJson);
607     final AbstractLocalPacket packet;
608     if (useJson) {
609       final StopOrCancelJsonPacket node = new StopOrCancelJsonPacket();
610       node.setComment(REQUEST_ON_TRANSFER);
611       node.setRequested(requested);
612       node.setRequester(requester);
613       node.setSpecialid(specialId);
614       packet = new JsonCommandPacket(node, code);
615     } else {
616       packet = new ValidPacket(REQUEST_ON_TRANSFER,
617                                requested + ' ' + requester + ' ' + specialId,
618                                code);
619     }
620     localChannelReference.sessionNewState(R66FiniteDualStates.VALIDOTHER);
621     if (!AbstractTransfer.sendValidPacket(host, localChannelReference, packet,
622                                           future)) {
623       return ErrorCode.Internal;
624     }
625 
626     logger.info(
627         "Request done with " + (future.isSuccess()? "success" : "error"));
628     final R66Result result = future.getResult();
629     if (result != null) {
630       return result.getCode();
631     }
632     return ErrorCode.Internal;
633   }
634 
635   /**
636    * @param args
637    */
638   public static void main(final String[] args) {
639     WaarpLoggerFactory.setDefaultFactoryIfNotSame(
640         new WaarpSlf4JLoggerFactory(null));
641     if (logger == null) {
642       logger = WaarpLoggerFactory.getLogger(RequestTransfer.class);
643     }
644     if (!getParams(args)) {
645       logger.error(Messages.getString("Configuration.WrongInit")); //$NON-NLS-1$
646       if (!OutputFormat.isQuiet()) {
647         SysErrLogger.FAKE_LOGGER.sysout(
648             Messages.getString("Configuration.WrongInit")); //$NON-NLS-1$
649       }
650       if (admin != null) {
651         admin.close();
652       }
653       WaarpSystemUtil.systemExit(1);
654       return;
655     }
656     int value = 99;
657     try {
658       Configuration.configuration.pipelineInit();
659       final NetworkTransaction networkTransaction = new NetworkTransaction();
660       final R66Future result = new R66Future(true);
661       final RequestTransfer requestTransfer =
662           new RequestTransfer(result, sspecialId, srequested, srequester,
663                               scancel, sstop, srestart, srestarttime,
664                               networkTransaction);
665       requestTransfer.normalInfoAsWarn = snormalInfoAsWarn;
666       requestTransfer.run();
667       result.awaitOrInterruptible();
668       final R66Result finalValue = result.getResult();
669       final OutputFormat outputFormat =
670           new OutputFormat(RequestTransfer.class.getSimpleName(), args);
671       if (scancel || sstop || srestart) {
672         if (scancel) {
673           value = cancel(result, requestTransfer, finalValue, outputFormat);
674         } else if (sstop) {
675           value = stop(result, requestTransfer, finalValue, outputFormat);
676         } else if (srestart) {
677           value = restart(result, requestTransfer, finalValue, outputFormat);
678         }
679       } else {
680         value = 0;
681         // Only request
682         outputFormat.setValue(FIELDS.status.name(), value);
683         outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
684             "RequestTransfer.83")); //$NON-NLS-1$
685         outputFormat.setValue(FIELDS.remote.name(), rhost);
686         if (result.isDone()) {
687           outputFormat.setValueString(result.getRunner().getJson());
688         }
689         if (requestTransfer.normalInfoAsWarn) {
690           logger.warn(outputFormat.loggerOut());
691         } else if (logger.isInfoEnabled()) {
692           logger.info(outputFormat.loggerOut());
693         }
694         if (!OutputFormat.isQuiet()) {
695           outputFormat.sysout();
696         }
697       }
698     } finally {
699       if (!WaarpSystemUtil.isJunit()) {
700         if (admin != null) {
701           admin.close();
702         }
703         WaarpSystemUtil.systemExit(value);
704       }
705     }
706   }
707 
708   private static int restart(final R66Future result,
709                              final RequestTransfer requestTransfer,
710                              final R66Result finalValue,
711                              final OutputFormat outputFormat) {
712     final int value;
713     switch (finalValue.getCode()) {
714       case QueryStillRunning:
715         value = 0;
716         outputFormat.setValue(FIELDS.status.name(), value);
717         outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
718             "RequestTransfer.76")); //$NON-NLS-1$
719         outputFormat.setValue(FIELDS.remote.name(), rhost);
720         outputFormat.setValueString(result.getRunner().getJson());
721         logger.warn(outputFormat.loggerOut());
722         if (!OutputFormat.isQuiet()) {
723           outputFormat.sysout();
724         }
725         break;
726       case Running:
727         value = 0;
728         outputFormat.setValue(FIELDS.status.name(), value);
729         outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
730             "RequestTransfer.77")); //$NON-NLS-1$
731         outputFormat.setValue(FIELDS.remote.name(), rhost);
732         outputFormat.setValueString(result.getRunner().getJson());
733         logger.warn(outputFormat.loggerOut());
734         if (!OutputFormat.isQuiet()) {
735           outputFormat.sysout();
736         }
737         break;
738       case PreProcessingOk:
739         value = 0;
740         outputFormat.setValue(FIELDS.status.name(), value);
741         outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
742             "RequestTransfer.78")); //$NON-NLS-1$
743         outputFormat.setValue(FIELDS.remote.name(), rhost);
744         outputFormat.setValueString(result.getRunner().getJson());
745         if (requestTransfer.normalInfoAsWarn) {
746           logger.warn(outputFormat.loggerOut());
747         } else if (logger.isInfoEnabled()) {
748           logger.info(outputFormat.loggerOut());
749         }
750         if (!OutputFormat.isQuiet()) {
751           outputFormat.sysout();
752         }
753         break;
754       case CompleteOk:
755         value = 4;
756         outputFormat.setValue(FIELDS.status.name(), value);
757         outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
758             "RequestTransfer.79")); //$NON-NLS-1$
759         outputFormat.setValue(FIELDS.remote.name(), rhost);
760         outputFormat.setValueString(result.getRunner().getJson());
761         logger.warn(outputFormat.loggerOut());
762         if (!OutputFormat.isQuiet()) {
763           outputFormat.sysout();
764         }
765         break;
766       case RemoteError:
767         value = 5;
768         outputFormat.setValue(FIELDS.status.name(), value);
769         outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
770             "RequestTransfer.80")); //$NON-NLS-1$
771         outputFormat.setValue(FIELDS.remote.name(), rhost);
772         outputFormat.setValueString(result.getRunner().getJson());
773         logger.warn(outputFormat.loggerOut());
774         if (!OutputFormat.isQuiet()) {
775           outputFormat.sysout();
776         }
777         break;
778       case PassThroughMode:
779         value = 6;
780         outputFormat.setValue(FIELDS.status.name(), value);
781         outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
782             "RequestTransfer.81")); //$NON-NLS-1$
783         outputFormat.setValue(FIELDS.remote.name(), rhost);
784         outputFormat.setValueString(result.getRunner().getJson());
785         logger.warn(outputFormat.loggerOut());
786         if (!OutputFormat.isQuiet()) {
787           outputFormat.sysout();
788         }
789         break;
790       default:
791         value = 3;
792         outputFormat.setValue(FIELDS.status.name(), value);
793         outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
794             "RequestTransfer.82")); //$NON-NLS-1$
795         outputFormat.setValue(FIELDS.remote.name(), rhost);
796         outputFormat.setValueString(result.getRunner().getJson());
797         if (result.getCause() != null) {
798           outputFormat.setValue(FIELDS.error.name(),
799                                 result.getCause().getMessage());
800         }
801         logger.warn(outputFormat.loggerOut());
802         if (!OutputFormat.isQuiet()) {
803           outputFormat.sysout();
804         }
805         break;
806     }
807     return value;
808   }
809 
810   private static int stop(final R66Future result,
811                           final RequestTransfer requestTransfer,
812                           final R66Result finalValue,
813                           final OutputFormat outputFormat) {
814     final int value;
815     switch (finalValue.getCode()) {
816       case CompleteOk:
817         value = 0;
818         outputFormat.setValue(FIELDS.status.name(), value);
819         outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
820             "RequestTransfer.73")); //$NON-NLS-1$
821         outputFormat.setValue(FIELDS.remote.name(), rhost);
822         outputFormat.setValueString(result.getRunner().getJson());
823         if (requestTransfer.normalInfoAsWarn) {
824           logger.warn(outputFormat.loggerOut());
825         } else if (logger.isInfoEnabled()) {
826           logger.info(outputFormat.loggerOut());
827         }
828         if (!OutputFormat.isQuiet()) {
829           outputFormat.sysout();
830         }
831         break;
832       case TransferOk:
833         value = 0;
834         outputFormat.setValue(FIELDS.status.name(), value);
835         outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
836             "RequestTransfer.74")); //$NON-NLS-1$
837         outputFormat.setValue(FIELDS.remote.name(), rhost);
838         outputFormat.setValueString(result.getRunner().getJson());
839         logger.warn(outputFormat.loggerOut());
840         if (!OutputFormat.isQuiet()) {
841           outputFormat.sysout();
842         }
843         break;
844       default:
845         value = 3;
846         outputFormat.setValue(FIELDS.status.name(), value);
847         outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
848             "RequestTransfer.75")); //$NON-NLS-1$
849         outputFormat.setValue(FIELDS.remote.name(), rhost);
850         outputFormat.setValueString(result.getRunner().getJson());
851         if (result.getCause() != null) {
852           outputFormat.setValue(FIELDS.error.name(),
853                                 result.getCause().getMessage());
854         }
855         logger.warn(outputFormat.loggerOut());
856         if (!OutputFormat.isQuiet()) {
857           outputFormat.sysout();
858         }
859         break;
860     }
861     return value;
862   }
863 
864   private static int cancel(final R66Future result,
865                             final RequestTransfer requestTransfer,
866                             final R66Result finalValue,
867                             final OutputFormat outputFormat) {
868     final int value;
869     if (result.isSuccess()) {
870       value = 0;
871       outputFormat.setValue(FIELDS.status.name(), value);
872       outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
873           "RequestTransfer.21")); //$NON-NLS-1$
874       outputFormat.setValue(FIELDS.remote.name(), rhost);
875       outputFormat.setValueString(result.getRunner().getJson());
876       if (requestTransfer.normalInfoAsWarn) {
877         logger.warn(outputFormat.loggerOut());
878       } else if (logger.isInfoEnabled()) {
879         logger.info(outputFormat.loggerOut());
880       }
881       if (!OutputFormat.isQuiet()) {
882         outputFormat.sysout();
883       }
884     } else {
885       switch (finalValue.getCode()) {
886         case CompleteOk:
887           value = 0;
888           outputFormat.setValue(FIELDS.status.name(), value);
889           outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
890               "RequestTransfer.70")); //$NON-NLS-1$
891           outputFormat.setValue(FIELDS.remote.name(), rhost);
892           outputFormat.setValueString(result.getRunner().getJson());
893           logger.warn(outputFormat.loggerOut());
894           if (!OutputFormat.isQuiet()) {
895             outputFormat.sysout();
896           }
897           break;
898         case TransferOk:
899           value = 3;
900           outputFormat.setValue(FIELDS.status.name(), value);
901           outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
902               "RequestTransfer.71")); //$NON-NLS-1$
903           outputFormat.setValue(FIELDS.remote.name(), rhost);
904           outputFormat.setValueString(result.getRunner().getJson());
905           logger.warn(outputFormat.loggerOut());
906           if (!OutputFormat.isQuiet()) {
907             outputFormat.sysout();
908           }
909           break;
910         default:
911           value = 4;
912           outputFormat.setValue(FIELDS.status.name(), value);
913           outputFormat.setValue(FIELDS.statusTxt.name(), Messages.getString(
914               "RequestTransfer.72")); //$NON-NLS-1$
915           outputFormat.setValue(FIELDS.remote.name(), rhost);
916           outputFormat.setValueString(result.getRunner().getJson());
917           if (result.getCause() != null) {
918             outputFormat.setValue(FIELDS.error.name(),
919                                   result.getCause().getMessage());
920           }
921           logger.error(outputFormat.loggerOut());
922           if (!OutputFormat.isQuiet()) {
923             outputFormat.sysout();
924           }
925           break;
926       }
927     }
928     return value;
929   }
930 
931 }