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.commander;
21  
22  import org.waarp.common.database.data.AbstractDbData;
23  import org.waarp.common.database.data.AbstractDbData.UpdatedInfo;
24  import org.waarp.common.database.exception.WaarpDatabaseException;
25  import org.waarp.common.file.FileUtils;
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.WaarpShutdownHook;
30  import org.waarp.openr66.configuration.ExtensionFilter;
31  import org.waarp.openr66.database.data.DbConfiguration;
32  import org.waarp.openr66.database.data.DbHostAuth;
33  import org.waarp.openr66.database.data.DbRule;
34  import org.waarp.openr66.database.data.DbTaskRunner;
35  import org.waarp.openr66.protocol.configuration.Configuration;
36  
37  import java.io.File;
38  import java.util.concurrent.ConcurrentLinkedQueue;
39  import java.util.regex.Pattern;
40  
41  /**
42   * Commander is responsible to read list of updated data from time to time in
43   * order to achieve new runner or
44   * new configuration updates.
45   * <p>
46   * Based on no Database support
47   */
48  public class CommanderNoDb implements CommanderInterface {
49    /**
50     * Internal Logger
51     */
52    private static final WaarpLogger logger =
53        WaarpLoggerFactory.getLogger(CommanderNoDb.class);
54    private static final Pattern COMPILE_ = Pattern.compile("_");
55  
56    private InternalRunner internalRunner;
57    public static final ConcurrentLinkedQueue<AbstractDbData> todoList =
58        new ConcurrentLinkedQueue<AbstractDbData>();
59  
60    /**
61     * Prepare requests that will be executed from time to time
62     *
63     * @param runner
64     */
65    public CommanderNoDb(final InternalRunner runner) {
66      internalConstructor(runner);
67    }
68  
69    /**
70     * Prepare requests that will be executed from time to time
71     *
72     * @param runner
73     * @param fromStartup True if call from startup of the server
74     */
75    public CommanderNoDb(final InternalRunner runner, final boolean fromStartup) {
76      internalConstructor(runner);
77      if (fromStartup) {
78        ClientRunner.activeRunners = new ConcurrentLinkedQueue<ClientRunner>();
79        // Change RUNNING or INTERRUPTED to TOSUBMIT since they should be ready
80        final File directory = new File(
81            Configuration.configuration.getBaseDirectory() +
82            Configuration.configuration.getArchivePath());
83        final File[] files = FileUtils.getFiles(directory, new ExtensionFilter(
84            DbTaskRunner.XMLEXTENSION));
85        for (final File file : files) {
86          final String shortname = file.getName();
87          final String[] info = COMPILE_.split(shortname);
88          if (info.length < 5) {
89            continue;
90          }
91          final DbRule rule;
92          try {
93            rule = new DbRule(info[2]);
94          } catch (final WaarpDatabaseException e) {
95            logger.warn("Cannot find the rule named: " + info[2]);
96            continue;
97          }
98          final long id = Long.parseLong(info[3]);
99          try {
100           final DbTaskRunner task =
101               new DbTaskRunner(null, rule, id, info[0], info[1]);
102           final UpdatedInfo status = task.getUpdatedInfo();
103           if (status == UpdatedInfo.RUNNING ||
104               status == UpdatedInfo.INTERRUPTED) {
105             task.changeUpdatedInfo(UpdatedInfo.TOSUBMIT);
106             task.update();
107           }
108         } catch (final WaarpDatabaseException e) {
109           logger.warn("Cannot reload the task named: " + shortname);
110         }
111       }
112     }
113   }
114 
115   private void internalConstructor(final InternalRunner runner) {
116     internalRunner = runner;
117   }
118 
119   /**
120    * Finalize internal data
121    */
122   @Override
123   public final void finalizeCommander() {
124     // no since it will be reloaded
125     // todoList.clear()
126   }
127 
128   @Override
129   public void run() {
130     Thread.currentThread().setName("OpenR66Commander");
131     while (!todoList.isEmpty()) {
132       try {
133         final AbstractDbData data = todoList.poll();
134         // First check Configuration
135         if (data instanceof DbConfiguration) {
136           // should be only one...
137           final DbConfiguration configuration = (DbConfiguration) data;
138           if (configuration.isOwnConfiguration()) {
139             configuration.updateConfiguration();
140           }
141           configuration.changeUpdatedInfo(UpdatedInfo.NOTUPDATED);
142           configuration.update();
143         }
144         // Check HostAuthent
145         else if (data instanceof DbHostAuth) {
146           final DbHostAuth hostAuth = (DbHostAuth) data;
147           // Nothing to do except validate
148           hostAuth.changeUpdatedInfo(UpdatedInfo.NOTUPDATED);
149           hostAuth.update();
150         }
151         // Check Rules
152         else if (data instanceof DbRule) {
153           // Nothing to do except validate
154           final DbRule rule = (DbRule) data;
155           rule.changeUpdatedInfo(UpdatedInfo.NOTUPDATED);
156           rule.update();
157         }
158         // Check TaskRunner
159         else if (data instanceof DbTaskRunner) {
160           final DbTaskRunner taskRunner = (DbTaskRunner) data;
161           logger.debug("get a task: {}", taskRunner);
162           // Launch if possible this task
163           final String key =
164               taskRunner.getRequested() + ' ' + taskRunner.getRequester() +
165               ' ' + taskRunner.getSpecialId();
166           if (Configuration.configuration.getLocalTransaction()
167                                          .getFromRequest(key) != null) {
168             // already running
169             continue;
170           }
171           if (taskRunner.isRequestOnRequested()) {
172             // cannot schedule a request where the host is the requested host
173             taskRunner.changeUpdatedInfo(UpdatedInfo.INTERRUPTED);
174             taskRunner.update();
175             continue;
176           }
177           // last check: number can have raised up since Commander checks
178           if (internalRunner.nbInternalRunner() >=
179               Configuration.configuration.getRunnerThread()) {
180             break;
181           }
182           if (internalRunner.submitTaskRunner(taskRunner)) {
183             try {
184               Thread.sleep(Configuration.RETRYINMS);
185             } catch (final InterruptedException e) {//NOSONAR
186               SysErrLogger.FAKE_LOGGER.ignoreLog(e);
187             }
188           } else {
189             break;
190           }
191         }
192         if (WaarpShutdownHook.isShutdownStarting()) {
193           // no more task to submit
194           return;
195         }
196       } catch (final WaarpDatabaseException e) {
197         logger.error("Error in Commander: {}", e.getMessage());
198       }
199     }
200   }
201 
202 }