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.exception.WaarpDatabaseException;
23  import org.waarp.common.logging.SysErrLogger;
24  import org.waarp.common.logging.WaarpLoggerFactory;
25  import org.waarp.common.logging.WaarpSlf4JLoggerFactory;
26  import org.waarp.common.utility.WaarpSystemUtil;
27  import org.waarp.openr66.client.utils.OutputFormat;
28  import org.waarp.openr66.client.utils.OutputFormat.FIELDS;
29  import org.waarp.openr66.context.R66Result;
30  import org.waarp.openr66.database.data.DbRule;
31  import org.waarp.openr66.database.data.DbTaskRunner;
32  import org.waarp.openr66.protocol.configuration.Configuration;
33  import org.waarp.openr66.protocol.configuration.Messages;
34  import org.waarp.openr66.protocol.networkhandler.NetworkTransaction;
35  import org.waarp.openr66.protocol.utils.R66Future;
36  
37  import java.sql.Timestamp;
38  import java.util.ArrayList;
39  import java.util.Collections;
40  import java.util.List;
41  
42  import static org.waarp.common.database.DbConstant.*;
43  
44  /**
45   * Client to submit a transfer for multiple files to multiple hosts at
46   * once.<br>
47   * Files will have to be separated by ','.<br>
48   * Hosts will have to be separated by ','.<br>
49   * <br>
50   * For instance: -to host1,host2,host3 -file file1,file2 <br>
51   * Will generate: <br>
52   * -to host1 -file file1<br>
53   * -to host1 -file file2<br>
54   * -to host2 -file file1<br>
55   * -to host2 -file file2<br>
56   * -to host3 -file file1<br>
57   * -to host3 -file file2<br>
58   * <br>
59   * <br>
60   * Extra option is -client which allows the filename resolution on remote (recv
61   * files) when using
62   * wildcards.<br>
63   */
64  public class MultipleSubmitTransfer extends SubmitTransfer {
65    private int errorMultiple;
66    private int doneMultiple;
67    protected boolean submit;
68    protected final NetworkTransaction networkTransaction;
69    private final List<OutputFormat> results = new ArrayList<OutputFormat>();
70  
71    public MultipleSubmitTransfer(final R66Future future, final String remoteHost,
72                                  final String filename, final String rulename,
73                                  final String fileinfo, final boolean isMD5,
74                                  final int blocksize, final long id,
75                                  final Timestamp starttime,
76                                  final NetworkTransaction networkTransaction) {
77      super(future, remoteHost, filename, rulename, fileinfo, isMD5, blocksize,
78            id, starttime);
79      this.networkTransaction = networkTransaction;
80    }
81  
82    @Override
83    public void run() {
84      final String[] localfilenames = transferArgs.getFilename().split(",");
85      final String[] rhosts = transferArgs.getRemoteHost().split(",");
86      R66Result resultError = null;
87  
88      // first check if filenames contains wildcards
89      DbRule dbrule = null;
90      try {
91        dbrule = new DbRule(transferArgs.getRulename());
92      } catch (final WaarpDatabaseException e) {
93        logger.error(Messages.getString("SubmitTransfer.2") +
94                     transferArgs.getRulename()); //$NON-NLS-1$
95        WaarpSystemUtil.systemExit(2);
96        return;
97      }
98      if (!submit && dbrule.isRecvMode() && networkTransaction == null) {
99        logger.error(Messages.getString("Configuration.WrongInit") +
100                    " => -client argument is missing"); //$NON-NLS-1$
101       WaarpSystemUtil.systemExit(2);
102       return;
103     }
104     List<String> files = null;
105     if (dbrule.isSendMode()) {
106       files = getLocalFiles(dbrule, localfilenames);
107     } else if (submit) {
108       files = new ArrayList<String>();
109       Collections.addAll(files, localfilenames);
110     }
111     for (String host : rhosts) {
112       host = host.trim();
113       if (!host.isEmpty()) {
114         if (!submit && dbrule.isRecvMode()) {
115           files = getRemoteFiles(localfilenames, host, networkTransaction);
116         }
117         for (String filename : files) {
118           filename = filename.trim();
119           if (!filename.isEmpty()) {
120             final R66Future future = new R66Future(true);
121             final SubmitTransfer transaction =
122                 new SubmitTransfer(future, host, filename,
123                                    transferArgs.getRulename(),
124                                    transferArgs.getTransferInfo(),
125                                    transferArgs.isMD5(),
126                                    transferArgs.getBlockSize(),
127                                    transferArgs.getId(),
128                                    transferArgs.getStartTime());
129             transaction.transferArgs.setFollowId(transferArgs.getFollowId());
130             transaction.normalInfoAsWarn = normalInfoAsWarn;
131             transaction.run();
132             future.awaitOrInterruptible();
133             final DbTaskRunner runner = future.getResult().getRunner();
134             final OutputFormat outputFormat =
135                 new OutputFormat(MultipleSubmitTransfer.class.getSimpleName(),
136                                  null);
137             if (future.isSuccess()) {
138               prepareSubmitOkOutputFormat(runner, outputFormat);
139               getResults().add(outputFormat);
140               if (transaction.normalInfoAsWarn) {
141                 logger.warn(outputFormat.loggerOut());
142               } else if (logger.isInfoEnabled()) {
143                 logger.info(outputFormat.loggerOut());
144               }
145               setDoneMultiple(getDoneMultiple() + 1);
146             } else {
147               prepareSubmitKoOutputFormat(future, runner, outputFormat);
148               getResults().add(outputFormat);
149               setErrorMultiple(getErrorMultiple() + 1);
150               resultError = future.getResult();
151             }
152           }
153         }
154       }
155     }
156     if (getErrorMultiple() > 0) {
157       if (resultError != null) {
158         future.setResult(resultError);
159       }
160       future.cancel();
161     } else {
162       future.setSuccess();
163     }
164   }
165 
166   /**
167    * @param args configuration file, the remoteHost Id, the file to
168    *     transfer, the rule, file transfer
169    *     information as arguments and optionally isMD5=1 for true or 0 for
170    *     false(default) and the
171    *     blocksize if different than default
172    */
173   public static void main(final String[] args) {
174     WaarpLoggerFactory.setDefaultFactoryIfNotSame(
175         new WaarpSlf4JLoggerFactory(null));
176     if (logger == null) {
177       logger = WaarpLoggerFactory.getLogger(MultipleSubmitTransfer.class);
178     }
179     boolean submit = true;
180     for (final String string : args) {
181       if ("-client".equalsIgnoreCase(string)) {
182         submit = false;
183         break;
184       }
185     }
186     if (!getParams(args, submit)) {
187       logger.error(Messages.getString("Configuration.WrongInit")); //$NON-NLS-1$
188       if (!OutputFormat.isQuiet()) {
189         SysErrLogger.FAKE_LOGGER.sysout(
190             Messages.getString("Configuration.WrongInit")); //$NON-NLS-1$
191       }
192       if (admin != null) {
193         admin.close();
194       }
195       WaarpSystemUtil.systemExit(1);
196       return;
197     }
198     NetworkTransaction networkTransaction = null;
199     if (!submit) {
200       Configuration.configuration.pipelineInit();
201       networkTransaction = new NetworkTransaction();
202     }
203     try {
204       final R66Future future = new R66Future(true);
205       final MultipleSubmitTransfer transaction =
206           new MultipleSubmitTransfer(future, rhost, localFilename, rule,
207                                      transferInfo, ismd5, block, idt,
208                                      ttimestart, networkTransaction);
209       transaction.normalInfoAsWarn = snormalInfoAsWarn;
210       transaction.run();
211       future.awaitOrInterruptible();
212       final OutputFormat outputFormat = new OutputFormat(
213           "Unique " + MultipleSubmitTransfer.class.getSimpleName(), args);
214       if (future.isSuccess()) {
215         outputFormat.setValue(FIELDS.status.name(), 0);
216         outputFormat.setValue(FIELDS.statusTxt.name(), "Multiple " +
217                                                        Messages.getString(
218                                                            "SubmitTransfer.3") +
219                                                        Messages.getString(
220                                                            "RequestInformation.Success")); //$NON-NLS-1$
221         outputFormat.setValue(FIELDS.remote.name(), rhost);
222         outputFormat.setValue("ok", transaction.getDoneMultiple());
223         if (transaction.normalInfoAsWarn) {
224           logger.warn(outputFormat.loggerOut());
225         } else if (logger.isInfoEnabled()) {
226           logger.info(outputFormat.loggerOut());
227         }
228         if (!OutputFormat.isQuiet()) {
229           outputFormat.sysout();
230           for (final OutputFormat result : transaction.getResults()) {
231             SysErrLogger.FAKE_LOGGER.sysout();
232             result.sysout();
233           }
234         }
235         if (networkTransaction != null) {
236           networkTransaction.closeAll();
237           networkTransaction = null;
238         }
239         admin.close();
240         WaarpSystemUtil.systemExit(0);
241       } else {
242         outputFormat.setValue(FIELDS.status.name(), 2);
243         outputFormat.setValue(FIELDS.statusTxt.name(), "Multiple " +
244                                                        Messages.getString(
245                                                            "SubmitTransfer.14") +
246                                                        Messages.getString(
247                                                            "RequestInformation.Failure")); //$NON-NLS-1$
248         outputFormat.setValue(FIELDS.remote.name(), rhost);
249         outputFormat.setValue("ok", transaction.getDoneMultiple());
250         outputFormat.setValue("ko", transaction.getErrorMultiple());
251         logger.error(outputFormat.loggerOut());
252         if (!OutputFormat.isQuiet()) {
253           outputFormat.sysout();
254           for (final OutputFormat result : transaction.getResults()) {
255             SysErrLogger.FAKE_LOGGER.sysout();
256             result.sysout();
257           }
258         }
259         if (networkTransaction != null) {
260           networkTransaction.closeAll();
261           networkTransaction = null;
262         }
263         admin.close();
264         WaarpSystemUtil.systemExit(transaction.getErrorMultiple());
265       }
266     } finally {
267       if (networkTransaction != null) {
268         networkTransaction.closeAll();
269       }
270     }
271   }
272 
273   /**
274    * @return the errorMultiple
275    */
276   public int getErrorMultiple() {
277     return errorMultiple;
278   }
279 
280   /**
281    * @param errorMultiple the errorMultiple to set
282    */
283   private void setErrorMultiple(final int errorMultiple) {
284     this.errorMultiple = errorMultiple;
285   }
286 
287   /**
288    * @return the doneMultiple
289    */
290   public int getDoneMultiple() {
291     return doneMultiple;
292   }
293 
294   /**
295    * @param doneMultiple the doneMultiple to set
296    */
297   private void setDoneMultiple(final int doneMultiple) {
298     this.doneMultiple = doneMultiple;
299   }
300 
301   /**
302    * @return the results
303    */
304   public List<OutputFormat> getResults() {
305     return results;
306   }
307 }