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.gateway.ftp.exec;
21  
22  import org.waarp.common.command.exception.CommandAbstractException;
23  import org.waarp.common.command.exception.Reply421Exception;
24  import org.waarp.common.exception.InvalidArgumentException;
25  import org.waarp.common.future.WaarpFuture;
26  import org.waarp.common.logging.SysErrLogger;
27  import org.waarp.common.logging.WaarpLogger;
28  import org.waarp.common.logging.WaarpLoggerFactory;
29  import org.waarp.common.utility.ParametersChecker;
30  import org.waarp.common.utility.WaarpSystemUtil;
31  import org.waarp.common.utility.WaarpThreadFactory;
32  
33  import java.util.concurrent.ExecutorService;
34  import java.util.concurrent.Executors;
35  import java.util.concurrent.TimeUnit;
36  
37  /**
38   *
39   */
40  public class JavaExecutor extends AbstractExecutor {
41    /**
42     * Internal Logger
43     */
44    private static final WaarpLogger logger =
45        WaarpLoggerFactory.getLogger(JavaExecutor.class);
46    private final String[] args;
47    private final WaarpFuture futureCompletion;
48    private final long delay;
49  
50    /**
51     * @param command
52     * @param delay
53     * @param futureCompletion
54     */
55    public JavaExecutor(final String command, final long delay,
56                        final WaarpFuture futureCompletion) {
57      args = BLANK.split(command);
58      this.futureCompletion = futureCompletion;
59      this.delay = delay;
60    }
61  
62    @Override
63    public final void run() throws CommandAbstractException {
64      final String className = args[0];
65      try {
66        ParametersChecker.checkSanityString(className);
67      } catch (final InvalidArgumentException e) {
68        SysErrLogger.FAKE_LOGGER.ignoreLog(e);
69        logger.error(
70            "Status: " + e.getMessage() + "\n\t Exec in error with " + className);
71        throw new Reply421Exception("Pre Exec command is not correctly executed");
72      }
73      final GatewayRunnable runnable;
74      try {
75        runnable =
76            (GatewayRunnable) WaarpSystemUtil.newInstance(className);//NOSONAR
77      } catch (final Exception e) {
78        logger.error("ExecJava command is not available: " + className + ": {}",
79                     e.getMessage());
80        throw new Reply421Exception("Pre Exec command is not executable");
81      }
82      runnable.setArgs(true, useLocalExec, (int) delay, args);
83      logger.debug("{} {}", className, runnable.getClass().getName());
84      int status = -1;
85      if (delay <= 0) {
86        runnable.run();
87        status = runnable.getFinalStatus();
88      } else {
89        final ExecutorService executorService = Executors.newSingleThreadExecutor(
90            new WaarpThreadFactory("JavaExecutor"));
91        executorService.execute(runnable);
92        try {
93          Thread.yield();
94          executorService.shutdown();
95          if (delay > 100) {
96            if (!executorService.awaitTermination(delay, TimeUnit.MILLISECONDS)) {
97              executorService.shutdownNow();
98              logger.error("Exec is in Time Out");
99              status = -1;
100           } else {
101             status = runnable.getFinalStatus();
102           }
103         } else {
104           while (!executorService.awaitTermination(30, TimeUnit.SECONDS)) {
105             // nothing
106           }
107           status = runnable.getFinalStatus();
108         }
109       } catch (final InterruptedException e) {//NOSONAR
110         SysErrLogger.FAKE_LOGGER.ignoreLog(e);
111         logger.error("Status: " + e.getMessage() + "\n\t Exec in error with " +
112                      runnable);
113         throw new Reply421Exception(
114             "Pre Exec command is not correctly executed");
115       }
116     }
117     if (status == 0) {
118       futureCompletion.setSuccess();
119       logger.info("Exec OK with {}", runnable);
120     } else if (status == 1) {
121       logger.warn("Exec in warning with " + runnable);
122       futureCompletion.setSuccess();
123     } else {
124       logger.error("Status: " + status + " Exec in error with " + runnable);
125       throw new Reply421Exception("Pre command executed in error");
126     }
127   }
128 
129 }