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.protocol.configuration;
21  
22  import io.netty.bootstrap.ServerBootstrap;
23  import io.netty.channel.Channel;
24  import io.netty.channel.ChannelFuture;
25  import io.netty.channel.EventLoopGroup;
26  import io.netty.channel.group.ChannelGroup;
27  import io.netty.channel.group.DefaultChannelGroup;
28  import io.netty.channel.nio.NioEventLoopGroup;
29  import io.netty.handler.traffic.AbstractTrafficShapingHandler;
30  import io.netty.handler.traffic.GlobalTrafficShapingHandler;
31  import io.netty.util.HashedWheelTimer;
32  import io.netty.util.Timer;
33  import org.waarp.common.crypto.Des;
34  import org.waarp.common.crypto.ssl.WaarpSecureKeyStore;
35  import org.waarp.common.crypto.ssl.WaarpSslContextFactory;
36  import org.waarp.common.crypto.ssl.WaarpSslUtility;
37  import org.waarp.common.database.exception.WaarpDatabaseException;
38  import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
39  import org.waarp.common.database.exception.WaarpDatabaseSqlException;
40  import org.waarp.common.digest.FilesystemBasedDigest;
41  import org.waarp.common.digest.FilesystemBasedDigest.DigestAlgo;
42  import org.waarp.common.file.filesystembased.FilesystemBasedFileParameterImpl;
43  import org.waarp.common.future.WaarpFuture;
44  import org.waarp.common.logging.SysErrLogger;
45  import org.waarp.common.logging.WaarpLogger;
46  import org.waarp.common.logging.WaarpLoggerFactory;
47  import org.waarp.common.logging.WaarpSlf4JLoggerFactory;
48  import org.waarp.common.role.RoleDefault;
49  import org.waarp.common.utility.SystemPropertyUtil;
50  import org.waarp.common.utility.WaarpNettyUtil;
51  import org.waarp.common.utility.WaarpShutdownHook;
52  import org.waarp.common.utility.WaarpShutdownHook.ShutdownConfiguration;
53  import org.waarp.common.utility.WaarpSystemUtil;
54  import org.waarp.common.utility.WaarpThreadFactory;
55  import org.waarp.gateway.kernel.rest.HttpRestHandler;
56  import org.waarp.gateway.kernel.rest.RestConfiguration;
57  import org.waarp.openr66.client.NoOpRecvThroughHandler;
58  import org.waarp.openr66.commander.ClientRunner;
59  import org.waarp.openr66.commander.Commander;
60  import org.waarp.openr66.commander.InternalRunner;
61  import org.waarp.openr66.commander.ThreadPoolRunnerExecutor;
62  import org.waarp.openr66.configuration.FileBasedConfiguration;
63  import org.waarp.openr66.context.R66BusinessFactoryInterface;
64  import org.waarp.openr66.context.R66DefaultBusinessFactory;
65  import org.waarp.openr66.context.R66FiniteDualStates;
66  import org.waarp.openr66.context.task.localexec.LocalExecClient;
67  import org.waarp.openr66.database.data.DbHostAuth;
68  import org.waarp.openr66.database.data.DbTaskRunner;
69  import org.waarp.openr66.exception.ServerException;
70  import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoSslException;
71  import org.waarp.openr66.protocol.http.HttpInitializer;
72  import org.waarp.openr66.protocol.http.adminssl.HttpReponsiveSslInitializer;
73  import org.waarp.openr66.protocol.http.adminssl.HttpSslHandler;
74  import org.waarp.openr66.protocol.http.adminssl.HttpSslInitializer;
75  import org.waarp.openr66.protocol.http.rest.HttpRestR66Handler;
76  import org.waarp.openr66.protocol.http.restv2.RestServiceInitializer;
77  import org.waarp.openr66.protocol.localhandler.LocalTransaction;
78  import org.waarp.openr66.protocol.localhandler.Monitoring;
79  import org.waarp.openr66.protocol.localhandler.RetrieveRunner;
80  import org.waarp.openr66.protocol.monitoring.ElasticsearchMonitoringExporterClientBuilder;
81  import org.waarp.openr66.protocol.monitoring.MonitorExporterTransfers;
82  import org.waarp.openr66.protocol.networkhandler.NetworkServerInitializer;
83  import org.waarp.openr66.protocol.networkhandler.NetworkTransaction;
84  import org.waarp.openr66.protocol.networkhandler.R66ConstraintLimitHandler;
85  import org.waarp.openr66.protocol.networkhandler.ssl.NetworkSslServerInitializer;
86  import org.waarp.openr66.protocol.snmp.R66PrivateMib;
87  import org.waarp.openr66.protocol.snmp.R66VariableFactory;
88  import org.waarp.openr66.protocol.utils.R66ShutdownHook;
89  import org.waarp.openr66.protocol.utils.Version;
90  import org.waarp.openr66.thrift.R66ThriftServerService;
91  import org.waarp.snmp.WaarpMOFactory;
92  import org.waarp.snmp.WaarpSnmpAgent;
93  
94  import java.io.File;
95  import java.io.IOException;
96  import java.lang.management.ManagementFactory;
97  import java.net.InetSocketAddress;
98  import java.util.ArrayList;
99  import java.util.HashMap;
100 import java.util.HashSet;
101 import java.util.List;
102 import java.util.Map;
103 import java.util.Set;
104 import java.util.TimerTask;
105 import java.util.concurrent.ConcurrentHashMap;
106 import java.util.concurrent.ConcurrentMap;
107 import java.util.concurrent.ExecutorService;
108 import java.util.concurrent.Executors;
109 import java.util.concurrent.RejectedExecutionHandler;
110 import java.util.concurrent.ScheduledExecutorService;
111 import java.util.concurrent.SynchronousQueue;
112 import java.util.concurrent.ThreadPoolExecutor;
113 import java.util.concurrent.TimeUnit;
114 import java.util.concurrent.atomic.AtomicBoolean;
115 
116 /**
117  * Configuration class
118  */
119 public class Configuration {
120   private static final String ISSUE_WHILE_DEBUGGING = "Issue while debugging";
121 
122   /**
123    * Internal Logger
124    */
125   private static final WaarpLogger logger =
126       WaarpLoggerFactory.getLogger(Configuration.class);
127 
128   // Static values
129   /**
130    * General Configuration object
131    */
132   public static Configuration configuration = new Configuration();
133 
134   public static final String SnmpName = "Waarp OpenR66 SNMP";
135   public static final int SnmpPrivateId = 66666;
136   public static final int SnmpR66Id = 66;
137   public static final String SnmpDefaultAuthor = "Frederic Bregier";
138   public static final String SnmpVersion = "Waarp OpenR66 " + Version.ID;
139   public static final String SnmpDefaultLocalization = "Paris, France";
140   public static final int SnmpService = 72;
141 
142   /**
143    * Time elapse for retry in ms
144    */
145   public static final long RETRYINMS = 10;
146 
147   /**
148    * Number of retry before error
149    */
150   public static final int RETRYNB = 3;
151 
152   /**
153    * Hack to say Windows or Unix (USR1 not OK on Windows)
154    */
155   private static boolean isUnix;
156 
157   /**
158    * Default size for buffers (NIO)
159    */
160   public static final int BUFFERSIZEDEFAULT = 0x10000; // 64K
161 
162   /**
163    * Time elapse for WRITE OR CLOSE WAIT elaps in ms
164    */
165   public static final long WAITFORNETOP = 200;
166 
167   /**
168    * Extension of file during transfer
169    */
170   public static final String EXT_R66 = ".r66";
171 
172   /**
173    * Rank to redo when a restart occurs
174    */
175   private static int rankRestart = 30;
176   /**
177    * Number of DbSession for internal needs
178    */
179   private static int nbDbSession;
180   /**
181    * FileParameter
182    */
183   private static final FilesystemBasedFileParameterImpl fileParameter =
184       new FilesystemBasedFileParameterImpl();
185 
186   private R66BusinessFactoryInterface r66BusinessFactory =
187       new R66DefaultBusinessFactory();
188   // Global Dynamic values
189   /**
190    * Version validation
191    */
192   private boolean extendedProtocol = true;
193   /**
194    * Global digest
195    */
196   private boolean globalDigest = true;
197   /**
198    * Local digest
199    */
200   private boolean localDigest = true;
201   /**
202    * White List of allowed Partners to use Business Requests
203    */
204   private final HashSet<String> businessWhiteSet = new HashSet<String>();
205   /**
206    * Roles list for identified partners
207    */
208   private final HashMap<String, RoleDefault> roles =
209       new HashMap<String, RoleDefault>();
210   /**
211    * Aliases list for identified partners
212    */
213   private final HashMap<String, String> aliases = new HashMap<String, String>();
214   /**
215    * reverse Aliases list for identified partners
216    */
217   private final HashMap<String, String[]> reverseAliases =
218       new HashMap<String, String[]>();
219   /**
220    * Versions for each HostID
221    */
222   private final ConcurrentHashMap<String, PartnerConfiguration> versions =
223       new ConcurrentHashMap<String, PartnerConfiguration>();
224   /**
225    * Actual Host ID
226    */
227   private String hostId;
228   /**
229    * Actual SSL Host ID
230    */
231   private String hostSslId;
232 
233   /**
234    * Server Administration user name
235    */
236   private String adminName;
237   /**
238    * Server Administration Key
239    */
240   private byte[] serverAdminKey;
241   /**
242    * Server Administration Key file
243    */
244   private String serverKeyFile;
245   /**
246    * Server Actual Authentication
247    */
248   private DbHostAuth hostAuth;
249   /**
250    * Server Actual SSL Authentication
251    */
252   private DbHostAuth hostSslAuth;
253 
254   private String authFile;
255 
256   /**
257    * Default number of threads in pool for Server (true network listeners).
258    * Server will change this value on
259    * startup if not set. The value should be closed to the number of CPU.
260    */
261   private int serverThread;
262 
263   /**
264    * Default number of threads in pool for Client. The value is for true
265    * client
266    * for Executor in the Pipeline for
267    * Business logic. The value does not indicate a limit of concurrent
268    * clients,
269    * but a limit on truly packet
270    * concurrent actions.
271    */
272   private int clientThread = 10;
273 
274   /**
275    * Default session limit 1 Gbit, so up to 100 full simultaneous clients
276    */
277   private static final long DEFAULT_SESSION_LIMIT = 1073741824L;
278 
279   /**
280    * Default global limit 100 Gbit
281    */
282   private static final long DEFAULT_GLOBAL_LIMIT = 107374182400L;
283 
284   /**
285    * Default server port
286    */
287   private int serverPort = 6666;
288 
289   /**
290    * Default SSL server port
291    */
292   private int serverSslPort = 6667;
293 
294   /**
295    * Default HTTP server port
296    */
297   private int serverHttpport = 8066;
298 
299   /**
300    * Default HTTP server port
301    */
302   private int serverHttpsPort = 8067;
303 
304   /**
305    * Default server IPs
306    */
307   private String[] serverAddresses = null;
308 
309   /**
310    * Default SSL server IPs
311    */
312   private String[] serverSslAddresses = null;
313 
314   /**
315    * Default HTTP server IPs
316    */
317   private String[] serverHttpAddresses = null;
318 
319   /**
320    * Default HTTP server IPs
321    */
322   private String[] serverHttpsAddresses = null;
323 
324   /**
325    * Nb of milliseconds after connection is in timeout
326    */
327   private long timeoutCon = 30000;
328 
329   /**
330    * Size by default of block size for receive/sending files. Should be a
331    * multiple of 8192 (maximum = 2^30K due
332    * to block limitation to 4 bytes)
333    */
334   private int blockSize = 0x10000; // 64K
335 
336   /**
337    * Max global memory limit: default is 1GB
338    * (used in Web and REST API)
339    */
340   private int maxGlobalMemory = 1073741824;
341 
342   /**
343    * Rest configuration list
344    */
345   private final List<RestConfiguration> restConfigurations =
346       new ArrayList<RestConfiguration>();
347 
348   /**
349    * Base Directory
350    */
351   private String baseDirectory;
352 
353   /**
354    * In path (receive)
355    */
356   private String inPath;
357 
358   /**
359    * Out path (send, copy, pending)
360    */
361   private String outPath;
362 
363   /**
364    * Archive path
365    */
366   private String archivePath;
367 
368   /**
369    * Working path
370    */
371   private String workingPath;
372 
373   /**
374    * Config path
375    */
376   private String configPath;
377 
378   /**
379    * Http Admin base
380    */
381   private String httpBasePath = "src/main/admin/";
382 
383   /**
384    * Model for Http Admin: 0 = standard (i18n only), 1 = responsive (i18n +
385    * bootstrap + dynamic table + refresh)
386    */
387   private int httpModel = 1;
388 
389   /**
390    * True if the service is going to shutdown
391    */
392   private boolean isShutdown;
393 
394   /**
395    * Limit in Write byte/s to apply globally to the FTP Server
396    */
397   private long serverGlobalWriteLimit = getDEFAULT_GLOBAL_LIMIT();
398 
399   /**
400    * Limit in Read byte/s to apply globally to the FTP Server
401    */
402   private long serverGlobalReadLimit = getDEFAULT_GLOBAL_LIMIT();
403 
404   /**
405    * Limit in Write byte/s to apply by session to the FTP Server
406    */
407   private long serverChannelWriteLimit = getDEFAULT_SESSION_LIMIT();
408 
409   /**
410    * Limit in Read byte/s to apply by session to the FTP Server
411    */
412   private long serverChannelReadLimit = getDEFAULT_SESSION_LIMIT();
413 
414   /**
415    * Delay in ms between two checks
416    */
417   private long delayLimit =
418       AbstractTrafficShapingHandler.DEFAULT_CHECK_INTERVAL;
419 
420   /**
421    * Does this OpenR66 server will use and accept SSL connections
422    */
423   private boolean useSSL;
424   /**
425    * Does this OpenR66 server will use and accept non SSL connections
426    */
427   private boolean useNOSSL = true;
428   /**
429    * Algorithm to use for Digest: fastest, replacement could be SHA512
430    */
431   private FilesystemBasedDigest.DigestAlgo digest = DigestAlgo.MD5;
432 
433   /**
434    * Does this OpenR66 server will try to compress HTTP connections
435    */
436   private boolean useHttpCompression;
437 
438   /**
439    * Does this OpenR66 server will use Waarp LocalExec Daemon for ExecTask and
440    * ExecMoveTask
441    */
442   private boolean useLocalExec;
443 
444   /**
445    * Crypto Key
446    */
447   private Des cryptoKey;
448   /**
449    * Associated file for CryptoKey
450    */
451   private String cryptoFile;
452 
453   /**
454    * List of all Server Channels to enable the close call on them using Netty
455    * ChannelGroup
456    */
457   protected ChannelGroup serverChannelGroup;
458 
459   /**
460    * List of all Server Channels connected to remote to enable the close call
461    * on them using Netty ChannelGroup
462    */
463   protected ChannelGroup serverConnectedChannelGroup;
464   /**
465    * Main bind address in no ssl mode
466    */
467   protected Channel bindNoSSL;
468   /**
469    * Main bind address in ssl mode
470    */
471   protected Channel bindSSL;
472 
473   /**
474    * Does the current program running as Server
475    */
476   private boolean isServer;
477 
478   /**
479    * ExecutorService Other Worker
480    */
481   protected final ExecutorService execOtherWorker =
482       Executors.newCachedThreadPool(new WaarpThreadFactory("OtherWorker"));
483 
484   protected EventLoopGroup serverGroup;
485   protected EventLoopGroup workerGroup;
486   protected EventLoopGroup handlerGroup;
487   protected EventLoopGroup subTaskGroup;
488   protected EventLoopGroup httpWorkerGroup;
489   protected ThreadPoolRunnerExecutor retrieveRunnerGroup;
490 
491   /**
492    * ExecutorService Scheduled tasks
493    */
494   protected final ScheduledExecutorService scheduledExecutorService;
495 
496   /**
497    * Bootstrap for server
498    */
499   protected ServerBootstrap serverBootstrap;
500 
501   /**
502    * Bootstrap for SSL server
503    */
504   protected ServerBootstrap serverSslBootstrap;
505   /**
506    * Factory for NON SSL Server
507    */
508   protected NetworkServerInitializer networkServerInitializer;
509   /**
510    * Factory for SSL Server
511    */
512   protected NetworkSslServerInitializer networkSslServerInitializer;
513 
514   /**
515    * Bootstrap for Http server
516    */
517   protected ServerBootstrap httpBootstrap;
518   /**
519    * Bootstrap for Https server
520    */
521   protected ServerBootstrap httpsBootstrap;
522   /**
523    * List of all Http Channels to enable the close call on them using Netty
524    * ChannelGroup
525    */
526   protected ChannelGroup httpChannelGroup;
527 
528   /**
529    * Timer for CloseOpertations
530    */
531   private final Timer timerCloseOperations =
532       new HashedWheelTimer(new WaarpThreadFactory("TimerClose"), 50,
533                            TimeUnit.MILLISECONDS, 1024);
534   private final AtomicBoolean timerCloseClosed = new AtomicBoolean(false);
535   /**
536    * Global TrafficCounter (set from global configuration)
537    */
538   protected GlobalTrafficShapingHandler globalTrafficShapingHandler;
539 
540   /**
541    * LocalTransaction
542    */
543   protected LocalTransaction localTransaction;
544   /**
545    * InternalRunner
546    */
547   private InternalRunner internalRunner;
548   /**
549    * Maximum number of concurrent active transfer by submission.
550    */
551   private int runnerThread = Commander.LIMIT_SUBMIT;
552   /**
553    * Delay in ms between two steps of Commander
554    */
555   private long delayCommander = 5000;
556   /**
557    * Delay in ms between two retries
558    */
559   private long delayRetry = 30000;
560   /**
561    * Constraint Limit Handler on CPU usage and Connection limitation
562    */
563   private R66ConstraintLimitHandler constraintLimitHandler =
564       new R66ConstraintLimitHandler();
565   /**
566    * Do we check Remote Address from DbHost
567    */
568   private boolean checkRemoteAddress;
569   /**
570    * Do we check address even for Client
571    */
572   private boolean checkClientAddress;
573   /**
574    * For No Db client, do we saved TaskRunner in a XML
575    */
576   private boolean saveTaskRunnerWithNoDb;
577   /**
578    * In case of Multiple OpenR66 monitor servers behing a load balancer (HA
579    * solution)
580    */
581   private int multipleMonitors = 1;
582   /**
583    * Monitoring object
584    */
585   private Monitoring monitoring;
586   /**
587    * Monitoring: how long in ms to get back in monitoring
588    */
589   private long pastLimit = 86400000; // 24H
590   /**
591    * Monitoring: minimal interval in ms before redo real monitoring
592    */
593   private long minimalDelay = 5000; // 5 seconds
594   /**
595    * Monitoring: snmp configuration file (empty means no snmp support)
596    */
597   private String snmpConfig;
598   /**
599    * SNMP Agent (if any)
600    */
601   private WaarpSnmpAgent agentSnmp;
602   /**
603    * Associated MIB
604    */
605   private R66PrivateMib r66Mib;
606 
607   protected boolean configured;
608 
609   private static WaarpSecureKeyStore waarpSecureKeyStore;
610 
611   private static WaarpSslContextFactory waarpSslContextFactory;
612   /**
613    * Thrift support
614    */
615   private R66ThriftServerService thriftService;
616   private int thriftport = -1;
617 
618   private boolean isExecuteErrorBeforeTransferAllowed = true;
619 
620   private final ShutdownConfiguration shutdownConfiguration =
621       new ShutdownConfiguration();
622 
623   private boolean isHostProxyfied;
624 
625   private boolean authentNoReuse;
626 
627   private boolean transferGuid = false;
628 
629   private boolean warnOnStartup = true;
630 
631   private boolean chrootChecked = true;
632 
633   private boolean blacklistBadAuthent;
634 
635   private int maxfilenamelength = 255;
636 
637   private MonitorExporterTransfers monitorExporterTransfers = null;
638 
639   private boolean isMonitorExporterApiRest;
640   private String monitorExporterUrl = null;
641   private String monitorExporterEndPoint = null;
642   private int monitorExporterDelay = 1000;
643   private boolean monitorExporterKeepConnection = false;
644   private boolean monitorIntervalIncluded = true;
645   private boolean monitorTransformLongAsString = false;
646   private String monitorBasicAuthent = null;
647   private String monitorUsername = null;
648   private String monitorPwd = null;
649   private String monitorToken = null;
650   private String monitorApiKey = null;
651   private String monitorPrefix = null;
652   private String monitorIndex = null;
653   private boolean monitorCompression = true;
654 
655   private boolean compressionAvailable = false;
656 
657   private int timeStat;
658 
659   private int limitCache = 5000;
660 
661   private long timeLimitCache = 180000;
662 
663   private final java.util.Timer timerCleanLruCache =
664       new java.util.Timer("CleanLruCache", true);
665 
666   private final java.util.Timer timerStatistic =
667       new java.util.Timer("R66Statistic", true);
668 
669   public Configuration() {
670     // Init signal handler
671     getShutdownConfiguration().timeout = getTimeoutCon();
672     if (WaarpShutdownHook.shutdownHook == null) {
673       new R66ShutdownHook(getShutdownConfiguration());
674     }
675     computeNbThreads();
676     scheduledExecutorService = Executors.newScheduledThreadPool(4,
677                                                                 new WaarpThreadFactory(
678                                                                     "ScheduledRestartTask"));
679     // Init FiniteStates
680     R66FiniteDualStates.initR66FiniteStates();
681     if (!SystemPropertyUtil.isFileEncodingCorrect()) {
682       logger.error(
683           "Issue while trying to set UTF-8 as default file encoding: use -Dfile.encoding=UTF-8 as java command argument");
684       logger.warn("Currently file.encoding is: " +
685                   SystemPropertyUtil.get(SystemPropertyUtil.FILE_ENCODING));
686     }
687     setExecuteErrorBeforeTransferAllowed(SystemPropertyUtil.getBoolean(
688         R66SystemProperties.OPENR66_EXECUTEBEFORETRANSFERRED, true));
689     final boolean useSpaceSeparator = SystemPropertyUtil.getBoolean(
690         R66SystemProperties.OPENR66_USESPACESEPARATOR, false);
691     if (useSpaceSeparator) {
692       PartnerConfiguration.setSEPARATOR_FIELD(
693           PartnerConfiguration.BLANK_SEPARATOR_FIELD);
694     }
695     setHostProxyfied(SystemPropertyUtil.getBoolean(
696         R66SystemProperties.OPENR66_ISHOSTPROXYFIED, false));
697     setWarnOnStartup(SystemPropertyUtil.getBoolean(
698         R66SystemProperties.OPENR66_STARTUP_WARNING, true));
699     setAuthentNoReuse(SystemPropertyUtil.getBoolean(
700         R66SystemProperties.OPENR66_AUTHENT_NO_REUSE, false));
701     setTransferGuid(
702         SystemPropertyUtil.getBoolean(R66SystemProperties.OPENR66_TRANSFER_GUID,
703                                       false));
704     if (!SystemPropertyUtil.get(
705         R66SystemProperties.OPENR66_STARTUP_DATABASE_CHECK, "").isEmpty()) {
706       logger.warn("{} is deprecated in system properties use {} instead",
707                   R66SystemProperties.OPENR66_STARTUP_DATABASE_CHECK,
708                   R66SystemProperties.OPENR66_STARTUP_DATABASE_AUTOUPGRADE);
709       FileBasedConfiguration.autoupgrade = SystemPropertyUtil.getBoolean(
710           R66SystemProperties.OPENR66_STARTUP_DATABASE_CHECK, false);
711     } else {
712       FileBasedConfiguration.autoupgrade = SystemPropertyUtil.getBoolean(
713           R66SystemProperties.OPENR66_STARTUP_DATABASE_AUTOUPGRADE, false);
714     }
715 
716     setChrootChecked(SystemPropertyUtil.getBoolean(
717         R66SystemProperties.OPENR66_CHROOT_CHECKED, true));
718     setBlacklistBadAuthent(SystemPropertyUtil.getBoolean(
719         R66SystemProperties.OPENR66_BLACKLIST_BADAUTHENT, !isHostProxyfied()));
720     setMaxfilenamelength(SystemPropertyUtil.getInt(
721         R66SystemProperties.OPENR66_FILENAME_MAXLENGTH, 255));
722     setTimeStat(
723         SystemPropertyUtil.getInt(R66SystemProperties.OPENR66_TRACE_STATS, 0));
724     setLimitCache(
725         SystemPropertyUtil.getInt(R66SystemProperties.OPENR66_CACHE_LIMIT,
726                                   20000));
727     if (getLimitCache() <= 100) {
728       setLimitCache(100);
729     }
730     setTimeLimitCache(
731         SystemPropertyUtil.getLong(R66SystemProperties.OPENR66_CACHE_TIMELIMIT,
732                                    180000));
733     if (getTimeLimitCache() < 1000) {
734       setTimeLimitCache(1000);
735     }
736     DbTaskRunner.createLruCache(getLimitCache(), getTimeLimitCache());
737     if (getLimitCache() > 0 && getTimeLimitCache() > 1000) {
738       timerCleanLruCache.schedule(new CleanLruCache(), getTimeLimitCache());
739     }
740     if (isHostProxyfied()) {
741       setBlacklistBadAuthent(false);
742     }
743   }
744 
745   private String arrayToString(final String[] array) {
746     final StringBuilder ip;
747     if (array != null && array.length > 0) {
748       ip = new StringBuilder("[" + array[0]);
749       for (int i = 1; i < array.length; i++) {
750         ip.append(",").append(array[i]);
751       }
752       ip.append("]");
753     } else {
754       ip = new StringBuilder("[All Interfaces]");
755     }
756     return ip.toString();
757   }
758 
759   @Override
760   public final String toString() {
761     StringBuilder rest = null;
762     for (final RestConfiguration config : getRestConfigurations()) {
763       if (rest == null) {
764         rest = new StringBuilder((config.getRestAddress() != null?
765             '\'' + config.getRestAddress() + ':' : "'All:") +
766                                  config.getRestPort() + '\'');
767       } else {
768         rest.append(", ").append(config.getRestAddress() != null?
769                                      '\'' + config.getRestAddress() + ':' :
770                                      "'All:").append(config.getRestPort())
771             .append('\'');
772       }
773     }
774     final String serverIp = arrayToString(getServerIpsAddresses());
775     final String serverSslIp = arrayToString(getServerSslAddresses());
776     final String serverHttpIp = arrayToString(getServerHttpAddresses());
777     final String serverHttpsIp = arrayToString(getServerHttpsAddresses());
778     return "Config: { ServerIp: " + serverIp + ", ServerPort: " +
779            getServerPort() + ", ServerSslIp: " + serverSslIp +
780            ", ServerSslPort: " + getServerSslPort() + ", ServerViewIp: " +
781            serverHttpIp + ", ServerView: " + getServerHttpport() +
782            ", ServerAdminIp: " + serverHttpsIp + ", ServerAdmin: " +
783            getServerHttpsPort() + ", ThriftPort: " +
784            (getThriftport() > 0? getThriftport() : "'NoThriftSupport'") +
785            ", RestAddress: [" +
786            (rest != null? rest.toString() : "'NoRestSupport'") + ']' +
787            ", TimeOut: " + getTimeoutCon() + ", BaseDir: '" +
788            getBaseDirectory() + "', DigestAlgo: '" + getDigest().algoName +
789            "', checkRemote: " + isCheckRemoteAddress() + ", checkClient: " +
790            isCheckClientAddress() + ", snmpActive: " +
791            (getAgentSnmp() != null) + ", chrootChecked: " + isChrootChecked() +
792            ", blacklist: " + isBlacklistBadAuthent() + ", isHostProxified: " +
793            isHostProxyfied() + ", isCompressionEnabled: " +
794            isCompressionAvailable() + '}';
795   }
796 
797   /**
798    * Configure the pipeline for client (to be called only once)
799    */
800   public final void pipelineInit() {
801     if (isConfigured()) {
802       return;
803     }
804     // To verify against limit of database
805     setRunnerThread(getRunnerThread());
806     serverGroup = new NioEventLoopGroup(getServerThread(),
807                                         new WaarpThreadFactory("Service"));
808     workerGroup = new NioEventLoopGroup(getClientThread(),
809                                         new WaarpThreadFactory("Worker"));
810     handlerGroup = new NioEventLoopGroup(getClientThread(),
811                                          new WaarpThreadFactory("Handler"));
812     subTaskGroup = new NioEventLoopGroup(getClientThread(),
813                                          new WaarpThreadFactory("SubTask"));
814     final RejectedExecutionHandler rejectedExecutionHandler =
815         new RejectedExecutionHandler() {
816 
817           @Override
818           public final void rejectedExecution(final Runnable r,
819                                               final ThreadPoolExecutor executor) {
820             if (r instanceof RetrieveRunner) {
821               final RetrieveRunner retrieveRunner = (RetrieveRunner) r;
822               logger.info("Try to reschedule RetrieveRunner: {}",
823                           retrieveRunner.getLocalId());
824               try {
825                 Thread.sleep(WAITFORNETOP * 2);
826               } catch (final InterruptedException e) {//NOSONAR
827                 SysErrLogger.FAKE_LOGGER.ignoreLog(e);
828                 retrieveRunner.notStartRunner();
829                 return;
830               }
831               getRetrieveRunnerGroup().execute(retrieveRunner);
832             } else {
833               logger.warn("Not RetrieveRunner: {}", r.getClass().getName());
834             }
835           }
836         };
837 
838     int nbRunnerThread = getRunnerThread();
839     if (nbRunnerThread == 1) {
840       nbRunnerThread = 2;
841     }
842     retrieveRunnerGroup =
843         new ThreadPoolRunnerExecutor(nbRunnerThread / 2, nbRunnerThread * 3, 1,
844                                      TimeUnit.SECONDS,
845                                      new SynchronousQueue<Runnable>(),
846                                      new WaarpThreadFactory("RetrieveRunner"),
847                                      rejectedExecutionHandler);
848     localTransaction = new LocalTransaction();
849     WaarpLoggerFactory.setDefaultFactoryIfNotSame(
850         new WaarpSlf4JLoggerFactory(null));
851     if (isWarnOnStartup()) {
852       logger.warn("Server Thread: " + getServerThread() + " Client Thread: " +
853                   getClientThread() + " Runner Thread: " + getRunnerThread());
854     } else {
855       logger.info("Server Thread: " + getServerThread() + " Client Thread: " +
856                   getClientThread() + " Runner Thread: " + getRunnerThread());
857     }
858     logger.info("Current launched threads: " +
859                 ManagementFactory.getThreadMXBean().getThreadCount());
860     if (isUseLocalExec()) {
861       LocalExecClient.initialize();
862     }
863     setConfigured(true);
864   }
865 
866   public final void setConfigured(final boolean configured) {
867     this.configured = configured;
868   }
869 
870   public final boolean isConfigured() {
871     return configured;
872   }
873 
874   public final void serverPipelineInit() {
875     httpWorkerGroup = new NioEventLoopGroup(getServerThread() * 10,
876                                             new WaarpThreadFactory(
877                                                 "HttpWorker"));
878   }
879 
880   /**
881    * Startup the server
882    *
883    * @throws WaarpDatabaseSqlException
884    * @throws WaarpDatabaseNoConnectionException
885    */
886   public void serverStartup()
887       throws WaarpDatabaseNoConnectionException, WaarpDatabaseSqlException,
888              ServerException {
889     setServer(true);
890     if (isBlacklistBadAuthent()) {
891       setBlacklistBadAuthent(!DbHostAuth.hasProxifiedHosts());
892     }
893     getShutdownConfiguration().timeout = getTimeoutCon();
894     if (getTimeLimitCache() < getTimeoutCon() * 10) {
895       setTimeLimitCache(getTimeoutCon() * 10);
896       DbTaskRunner.updateLruCacheTimeout(getTimeLimitCache());
897     }
898     WaarpShutdownHook.addShutdownHook();
899     logger.debug("Use NoSSL: {} Use SSL: {}", isUseNOSSL(), isUseSSL());
900     if (!isUseNOSSL() && !isUseSSL()) {
901       logger.error(Messages.getString("Configuration.NoSSL")); //$NON-NLS-1$
902       WaarpSystemUtil.systemExit(-1);
903       return;
904     }
905     if (SystemPropertyUtil.getBoolean(
906         R66SystemProperties.OPENR66_JUNIT_RECV_THROUGH, false)) {
907       logger.warn("DEBUG PERF MODE using RECV THROUGH");
908       ClientRunner.setRecvHandlerJunit(new NoOpRecvThroughHandler());
909     }
910     pipelineInit();
911     serverPipelineInit();
912     r66Startup();
913     startHttpSupport();
914     startMonitoring();
915     launchStatistics();
916     startRestSupport();
917     startMonitorExporterTransfers();
918     logger.info("Current launched threads: " +
919                 ManagementFactory.getThreadMXBean().getThreadCount());
920   }
921 
922   /**
923    * Used to log statistics information regularly
924    */
925   public final void launchStatistics() {
926     if (getTimeStat() > 0) {
927       timerStatistic.scheduleAtFixedRate(new UsageStatistic(), 1000,
928                                          getTimeStat() * 1000L);
929     }
930   }
931 
932   private Channel bindTo(final String ip, final int port,
933                          final ServerBootstrap serverBootstrapToBind,
934                          final String messageError) throws ServerException {
935     final InetSocketAddress inetSocketAddress =
936         ip == null? new InetSocketAddress(port) :
937             new InetSocketAddress(ip, port);
938     final ChannelFuture future =
939         serverBootstrapToBind.bind(inetSocketAddress).awaitUninterruptibly();
940     if (future.isSuccess()) {
941       final Channel channel = future.channel();
942       serverChannelGroup.add(channel);
943       return channel;
944     } else {
945       throw new ServerException(messageError + " [" + ip + ":" + port + "]",
946                                 future.cause());
947     }
948   }
949 
950   private Channel bindTo(final String[] ips, final int port,
951                          final ServerBootstrap serverBootstrapToBind,
952                          final String messageError) throws ServerException {
953     if (ips == null || ips.length == 0) {
954       return bindTo((String) null, port, serverBootstrapToBind, messageError);
955     } else {
956       Channel channel = null;
957       for (final String ip : ips) {
958         channel = bindTo(ip, port, serverBootstrapToBind, messageError);
959       }
960       return channel;
961     }
962   }
963 
964   public void r66Startup()
965       throws WaarpDatabaseNoConnectionException, WaarpDatabaseSqlException,
966              ServerException {
967     logger.info(Messages.getString("Configuration.Start") +
968                 arrayToString(getServerIpsAddresses()) + ':' + getServerPort() +
969                 ':' + isUseNOSSL() + ':' + getHostId() + //$NON-NLS-1$
970                 ' ' + arrayToString(getServerSslAddresses()) + ':' +
971                 getServerSslPort() + ':' + isUseSSL() + ':' + getHostSslId());
972     // add into configuration
973     getConstraintLimitHandler().setServer(true);
974     // Global Server
975     serverChannelGroup =
976         new DefaultChannelGroup("OpenR66", subTaskGroup.next());
977     serverConnectedChannelGroup =
978         new DefaultChannelGroup("OpenR66Connected", subTaskGroup.next());
979     if (isUseNOSSL()) {
980       serverBootstrap = new ServerBootstrap();
981       WaarpNettyUtil.setServerBootstrap(serverBootstrap, serverGroup,
982                                         workerGroup, (int) getTimeoutCon(),
983                                         getBlockSize() + 64, false);
984       networkServerInitializer = new NetworkServerInitializer(true);
985       serverBootstrap.childHandler(networkServerInitializer);
986       final String[] serverIps = getServerIpsAddresses();
987       bindNoSSL = bindTo(serverIps, getServerPort(), serverBootstrap,
988                          Messages.getString("Configuration.R66NotBound"));
989     } else {
990       networkServerInitializer = null;
991       logger.warn(
992           Messages.getString("Configuration.NOSSLDeactivated")); //$NON-NLS-1$
993     }
994 
995     if (isUseSSL() && getHostSslId() != null) {
996       serverSslBootstrap = new ServerBootstrap();
997       WaarpNettyUtil.setServerBootstrap(serverSslBootstrap, serverGroup,
998                                         workerGroup, (int) getTimeoutCon(),
999                                         getBlockSize() + 64, false);
1000       networkSslServerInitializer = new NetworkSslServerInitializer(false);
1001       serverSslBootstrap.childHandler(networkSslServerInitializer);
1002       final String[] serverIps = getServerSslAddresses();
1003       bindSSL = bindTo(serverIps, getServerSslPort(), serverSslBootstrap,
1004                        Messages.getString("Configuration.R66SSLNotBound"));
1005     } else {
1006       networkSslServerInitializer = null;
1007       logger.warn(
1008           Messages.getString("Configuration.SSLMODEDeactivated")); //$NON-NLS-1$
1009     }
1010 
1011     // Factory for TrafficShapingHandler
1012     setupLimitHandler();
1013 
1014     // Now start the InternalRunner
1015     internalRunner = new InternalRunner();
1016 
1017     if (getThriftport() > 0) {
1018       setThriftService(
1019           new R66ThriftServerService(new WaarpFuture(true), getThriftport()));
1020       execOtherWorker.execute(getThriftService());
1021       getThriftService().awaitInitialization();
1022     } else {
1023       setThriftService(null);
1024     }
1025   }
1026 
1027   public void startHttpSupport() throws ServerException {
1028     // Now start the HTTP support
1029     logger.info(
1030         Messages.getString("Configuration.HTTPStart") + getServerHttpport() +
1031         //$NON-NLS-1$
1032         " HTTPS: " + getServerHttpsPort());
1033     httpChannelGroup =
1034         new DefaultChannelGroup("HttpOpenR66", subTaskGroup.next());
1035     if (getServerHttpport() > 0) {
1036       // Configure the server.
1037       httpBootstrap = new ServerBootstrap();
1038       WaarpNettyUtil.setServerBootstrap(httpBootstrap, httpWorkerGroup,
1039                                         httpWorkerGroup, (int) getTimeoutCon());
1040       // Set up the event pipeline factory.
1041       httpBootstrap.childHandler(new HttpInitializer(isUseHttpCompression()));
1042       // Bind and start to accept incoming connections.
1043       final String[] serverIps = getServerHttpAddresses();
1044       bindTo(serverIps, getServerHttpport(), httpBootstrap,
1045              "Can't start HTTP service");
1046     }
1047     // Now start the HTTPS support
1048     // Bind and start to accept incoming connections.
1049     if (getServerHttpsPort() > 0) {
1050       // Configure the server.
1051       httpsBootstrap = new ServerBootstrap();
1052       // Set up the event pipeline factory.
1053       WaarpNettyUtil.setServerBootstrap(httpsBootstrap, httpWorkerGroup,
1054                                         httpWorkerGroup, (int) getTimeoutCon());
1055       if (getHttpModel() == 0) {
1056         httpsBootstrap.childHandler(
1057             new HttpSslInitializer(isUseHttpCompression()));
1058       } else {
1059         // Default
1060         httpsBootstrap.childHandler(
1061             new HttpReponsiveSslInitializer(isUseHttpCompression()));
1062       }
1063       final String[] serverIps = getServerHttpsAddresses();
1064       bindTo(serverIps, getServerHttpsPort(), httpsBootstrap,
1065              "Can't start HTTPS service");
1066     }
1067   }
1068 
1069   public final void startRestSupport() {
1070     HttpRestHandler.initialize(
1071         getBaseDirectory() + '/' + getWorkingPath() + "/httptemp");
1072     for (final RestConfiguration config : getRestConfigurations()) {
1073       RestServiceInitializer.initRestService(config);
1074       // REST V1 is included within V2
1075       // so no HttpRestR66Handler.initializeService(config)
1076       logger.info(
1077           Messages.getString("Configuration.HTTPStart") + " (REST Support) " +
1078           config);
1079     }
1080   }
1081 
1082   public final void startMonitoring() throws WaarpDatabaseSqlException {
1083     setMonitoring(new Monitoring(getPastLimit(), getMinimalDelay(), null));
1084     setNbDbSession(getNbDbSession() + 1);
1085     if (getSnmpConfig() != null) {
1086       final int snmpPortShow =
1087           isUseNOSSL()? getServerPort() : getServerSslPort();
1088       final R66PrivateMib r66MibTemp =
1089           new R66PrivateMib(SnmpName, snmpPortShow, SnmpPrivateId, SnmpR66Id,
1090                             SnmpDefaultAuthor, SnmpVersion,
1091                             SnmpDefaultLocalization, SnmpService);
1092       WaarpMOFactory.setFactory(new R66VariableFactory());
1093       setAgentSnmp(
1094           new WaarpSnmpAgent(new File(getSnmpConfig()), getMonitoring(),
1095                              r66MibTemp));
1096       try {
1097         getAgentSnmp().start();
1098       } catch (final IOException e) {
1099         throw new WaarpDatabaseSqlException(
1100             Messages.getString("Configuration.SNMPError"), e); //$NON-NLS-1$
1101       }
1102       setR66Mib(r66MibTemp);
1103     }
1104   }
1105 
1106   public final void startJunitRestSupport(final RestConfiguration config) {
1107     HttpRestR66Handler.initializeService(config);
1108   }
1109 
1110   public final InternalRunner getInternalRunner() {
1111     return internalRunner;
1112   }
1113 
1114   /**
1115    * Prepare the server to stop
1116    * <p>
1117    * To be called early before other stuff will be closed
1118    */
1119   public final void prepareServerStop() {
1120     if (getThriftService() != null) {
1121       getThriftService().releaseResources();
1122     }
1123     if (internalRunner != null) {
1124       internalRunner.prepareStopInternalRunner();
1125     }
1126   }
1127 
1128   /**
1129    * Unbind network connectors
1130    */
1131   public final void unbindServer() {
1132     if (bindNoSSL != null) {
1133       bindNoSSL.close();
1134       bindNoSSL = null;
1135     }
1136     if (bindSSL != null) {
1137       bindSSL.close();
1138       bindSSL = null;
1139     }
1140   }
1141 
1142   public final void shutdownGracefully() {
1143     if (workerGroup != null && !workerGroup.isShuttingDown()) {
1144       workerGroup.shutdownGracefully();
1145     }
1146     if (handlerGroup != null && !handlerGroup.isShuttingDown()) {
1147       handlerGroup.shutdownGracefully();
1148     }
1149     if (httpWorkerGroup != null && !httpWorkerGroup.isShuttingDown()) {
1150       httpWorkerGroup.shutdownGracefully();
1151     }
1152     if (subTaskGroup != null && !subTaskGroup.isShuttingDown()) {
1153       subTaskGroup.shutdownGracefully();
1154     }
1155     if (serverGroup != null && !serverGroup.isShuttingDown()) {
1156       serverGroup.shutdownGracefully();
1157     }
1158     if (retrieveRunnerGroup != null && !retrieveRunnerGroup.isShutdown()) {
1159 
1160       retrieveRunnerGroup.shutdown();
1161       try {
1162         if (!retrieveRunnerGroup.awaitTermination(getTimeoutCon() / 2,
1163                                                   TimeUnit.MILLISECONDS)) {
1164           retrieveRunnerGroup.shutdownNow();
1165         }
1166       } catch (final InterruptedException e) {//NOSONAR
1167         SysErrLogger.FAKE_LOGGER.ignoreLog(e);
1168         retrieveRunnerGroup.shutdownNow();
1169         Thread.currentThread().interrupt();
1170       }
1171     }
1172   }
1173 
1174   public final void shutdownQuickly() {
1175     if (workerGroup != null && !workerGroup.isShuttingDown()) {
1176       workerGroup.shutdownGracefully(10, 10, TimeUnit.MILLISECONDS);
1177     }
1178     if (httpWorkerGroup != null && !httpWorkerGroup.isShuttingDown()) {
1179       httpWorkerGroup.shutdownGracefully(10, 10, TimeUnit.MILLISECONDS);
1180     }
1181     if (handlerGroup != null && !handlerGroup.isShuttingDown()) {
1182       handlerGroup.shutdownGracefully(10, 10, TimeUnit.MILLISECONDS);
1183     }
1184     if (subTaskGroup != null && !subTaskGroup.isShuttingDown()) {
1185       subTaskGroup.shutdownGracefully(10, 10, TimeUnit.MILLISECONDS);
1186     }
1187     if (serverGroup != null && !serverGroup.isShuttingDown()) {
1188       serverGroup.shutdownGracefully(10, 10, TimeUnit.MILLISECONDS);
1189     }
1190     if (retrieveRunnerGroup != null && !retrieveRunnerGroup.isShutdown()) {
1191       retrieveRunnerGroup.shutdownNow();
1192     }
1193   }
1194 
1195   /**
1196    * Stops the server
1197    * <p>
1198    * To be called after all other stuff are closed (channels, connections)
1199    */
1200   public void serverStop() {
1201     WaarpSslUtility.forceCloseAllSslChannels();
1202     if (internalRunner != null) {
1203       internalRunner.stopInternalRunner();
1204     }
1205     if (scheduledExecutorService != null) {
1206       scheduledExecutorService.shutdown();
1207     }
1208     timerCleanLruCache.cancel();
1209     timerStatistic.cancel();
1210     if (monitorExporterTransfers != null) {
1211       try {
1212         monitorExporterTransfers.close();
1213       } catch (final IOException e) {
1214         SysErrLogger.FAKE_LOGGER.ignoreLog(e);
1215       }
1216       monitorExporterTransfers = null;
1217     }
1218     if (getAgentSnmp() != null) {
1219       getAgentSnmp().stop();
1220       setAgentSnmp(null);
1221     } else if (getMonitoring() != null) {
1222       getMonitoring().releaseResources();
1223       setMonitoring(null);
1224     }
1225     shutdownGracefully();
1226     if (execOtherWorker != null) {
1227       if (!WaarpSystemUtil.isJunit()) {
1228         execOtherWorker.shutdownNow();
1229       }
1230     }
1231     if (timerCloseOperations != null) {
1232       timerCloseClosed.set(true);
1233       timerCloseOperations.stop();
1234     }
1235   }
1236 
1237   /**
1238    * To be called after all other stuff are closed for Client
1239    */
1240   public final void clientStop() {
1241     clientStop(true);
1242   }
1243 
1244   /**
1245    * To be called after all other stuff are closed for Client
1246    *
1247    * @param shutdownQuickly For client only, shall be true to speedup
1248    *     the
1249    *     end of the process
1250    */
1251   public final void clientStop(final boolean shutdownQuickly) {
1252     WaarpSslUtility.forceCloseAllSslChannels();
1253     if (!configuration.isServer()) {
1254       WaarpSystemUtil.stopLogger(false);
1255     }
1256     if (scheduledExecutorService != null) {
1257       scheduledExecutorService.shutdown();
1258     }
1259     timerCleanLruCache.cancel();
1260     timerStatistic.cancel();
1261     if (localTransaction != null) {
1262       localTransaction.closeAll();
1263       localTransaction = null;
1264     }
1265     if (shutdownQuickly) {
1266       shutdownQuickly();
1267     } else {
1268       shutdownGracefully();
1269     }
1270     if (isUseLocalExec()) {
1271       LocalExecClient.releaseResources();
1272     }
1273     getR66BusinessFactory().releaseResources();
1274     if (timerCloseOperations != null && !timerCloseClosed.get()) {
1275       timerCloseClosed.set(true);
1276       timerCloseOperations.stop();
1277     }
1278   }
1279 
1280   /**
1281    * Try to reload the Commander
1282    *
1283    * @return True if reloaded, else in error
1284    */
1285   public final boolean reloadCommanderDelay() {
1286     if (internalRunner != null) {
1287       try {
1288         internalRunner.reloadInternalRunner();
1289         return true;
1290       } catch (final WaarpDatabaseNoConnectionException ignored) {
1291         // nothing
1292       } catch (final WaarpDatabaseSqlException ignored) {
1293         // nothing
1294       }
1295     }
1296     return false;
1297   }
1298 
1299   /**
1300    * submit a task in a fixed delay
1301    *
1302    * @param thread
1303    * @param delay
1304    * @param unit
1305    */
1306   public final void launchInFixedDelay(final Thread thread, final long delay,
1307                                        final TimeUnit unit) {
1308     scheduledExecutorService.schedule(thread, delay, unit);
1309   }
1310 
1311   /**
1312    * submit a task in a repeated delay
1313    *
1314    * @param thread
1315    * @param delay
1316    * @param unit
1317    */
1318   public final void scheduleWithFixedDelay(final Thread thread,
1319                                            final long delay,
1320                                            final TimeUnit unit) {
1321     scheduledExecutorService.scheduleWithFixedDelay(thread, delay, delay, unit);
1322   }
1323 
1324   public final void setupLimitHandler() {
1325     if (globalTrafficShapingHandler != null) {
1326       return;
1327     }
1328     globalTrafficShapingHandler = new GlobalTrafficShapingHandler(subTaskGroup,
1329                                                                   getServerGlobalWriteLimit(),
1330                                                                   getServerGlobalReadLimit(),
1331                                                                   getDelayLimit());
1332     getConstraintLimitHandler().setHandler(globalTrafficShapingHandler);
1333   }
1334 
1335   /**
1336    * Reset the global monitor for bandwidth limitation and change future
1337    * channel
1338    * monitors
1339    *
1340    * @param writeGlobalLimit
1341    * @param readGlobalLimit
1342    * @param writeSessionLimit
1343    * @param readSessionLimit
1344    * @param delayLimit
1345    */
1346   public final void changeNetworkLimit(long writeGlobalLimit,
1347                                        long readGlobalLimit,
1348                                        long writeSessionLimit,
1349                                        long readSessionLimit,
1350                                        final long delayLimit) {
1351     if (writeGlobalLimit <= 0) {
1352       writeGlobalLimit = 0;
1353     }
1354     if (readGlobalLimit <= 0) {
1355       readGlobalLimit = 0;
1356     }
1357     if (writeSessionLimit <= 0) {
1358       writeSessionLimit = 0;
1359     }
1360     if (readSessionLimit <= 0) {
1361       readSessionLimit = 0;
1362     }
1363     if (writeGlobalLimit < writeSessionLimit) {
1364       writeSessionLimit = writeGlobalLimit;
1365       logger.warn("Wanted global write limit is inferior " +
1366                   "to session limit. Will force session limit to {} ",
1367                   writeGlobalLimit);
1368     }
1369     if (readGlobalLimit < readSessionLimit) {
1370       readSessionLimit = readGlobalLimit;
1371       logger.warn("Wanted global read limit is inferior " +
1372                   "to session limit. Will force session limit to {} ",
1373                   readGlobalLimit);
1374     }
1375     setServerGlobalReadLimit(readGlobalLimit);
1376     setServerGlobalWriteLimit(writeGlobalLimit);
1377     setServerChannelReadLimit(readSessionLimit);
1378     setServerChannelWriteLimit(writeSessionLimit);
1379     setDelayLimit(delayLimit);
1380     if (globalTrafficShapingHandler != null) {
1381       globalTrafficShapingHandler.configure(writeGlobalLimit, readGlobalLimit,
1382                                             delayLimit);
1383       logger.info(Messages.getString("Configuration.BandwidthChange"),
1384                   globalTrafficShapingHandler);
1385     }
1386   }
1387 
1388   /**
1389    * Compute number of threads for both client and server from the real number
1390    * of available processors (double +
1391    * 1) if the value is less than 32 threads else (available +1).
1392    */
1393   public void computeNbThreads() {
1394     int nb = Runtime.getRuntime().availableProcessors() * 2 + 1;
1395     if (nb > 32) {
1396       nb = Runtime.getRuntime().availableProcessors() + 1;
1397     }
1398     if (getServerThread() <= 0 || getServerThread() > nb) {
1399       logger.info(Messages.getString("Configuration.ThreadNumberChange") +
1400                   nb); //$NON-NLS-1$
1401       setServerThread(nb);
1402       if (getClientThread() < getServerThread() * 10) {
1403         setClientThread(getServerThread() * 10);
1404       }
1405     } else if (getClientThread() < nb) {
1406       setClientThread(nb);
1407     }
1408   }
1409 
1410   /**
1411    * @return an executorService to be used for any thread
1412    */
1413   public final ExecutorService getExecutorService() {
1414     return execOtherWorker;
1415   }
1416 
1417   public final Timer getTimerClose() {
1418     return timerCloseOperations;
1419   }
1420 
1421   public final boolean isTimerCloseReady() {
1422     return !timerCloseClosed.get();
1423   }
1424 
1425   /**
1426    * @return the globalTrafficShapingHandler
1427    */
1428   public final GlobalTrafficShapingHandler getGlobalTrafficShapingHandler() {
1429     return globalTrafficShapingHandler;
1430   }
1431 
1432   /**
1433    * @return the serverChannelGroup
1434    */
1435   public final ChannelGroup getServerChannelGroup() {
1436     return serverChannelGroup;
1437   }
1438 
1439   /**
1440    * @return the server connected channels group
1441    */
1442   public final ChannelGroup getServerConnectedChannelGroup() {
1443     return serverConnectedChannelGroup;
1444   }
1445 
1446   /**
1447    * @return the httpChannelGroup
1448    */
1449   public final ChannelGroup getHttpChannelGroup() {
1450     return httpChannelGroup;
1451   }
1452 
1453   /**
1454    * @return the serverPipelineExecutor
1455    */
1456   public final EventLoopGroup getNetworkWorkerGroup() {
1457     return workerGroup;
1458   }
1459 
1460   /**
1461    * @return the retrieveRunnerGroup
1462    */
1463   public final ThreadPoolRunnerExecutor getRetrieveRunnerGroup() {
1464     return retrieveRunnerGroup;
1465   }
1466 
1467   /**
1468    * @return the serverPipelineExecutor
1469    */
1470   public final EventLoopGroup getHandlerGroup() {
1471     return handlerGroup;
1472   }
1473 
1474   /**
1475    * @return the subTaskGroup
1476    */
1477   public final EventLoopGroup getSubTaskGroup() {
1478     return subTaskGroup;
1479   }
1480 
1481   /**
1482    * @return the httpWorkerGroup
1483    */
1484   public final EventLoopGroup getHttpWorkerGroup() {
1485     return httpWorkerGroup;
1486   }
1487 
1488   /**
1489    * @return the localTransaction
1490    */
1491   public final LocalTransaction getLocalTransaction() {
1492     return localTransaction;
1493   }
1494 
1495   /**
1496    * @return the FilesystemBasedFileParameterImpl
1497    */
1498   public static FilesystemBasedFileParameterImpl getFileParameter() {
1499     return fileParameter;
1500   }
1501 
1502   /**
1503    * @return the SERVERADMINKEY
1504    */
1505   public final byte[] getServerAdminKey() {
1506     return serverAdminKey;
1507   }
1508 
1509   /**
1510    * Is the given key a valid one
1511    *
1512    * @param newkey
1513    *
1514    * @return True if the key is valid (or any key is valid)
1515    */
1516   public final boolean isKeyValid(final byte[] newkey) {
1517     if (newkey == null) {
1518       return false;
1519     }
1520     return FilesystemBasedDigest.equalPasswd(serverAdminKey, newkey);
1521   }
1522 
1523   /**
1524    * @param serverkey the SERVERADMINKEY to set
1525    */
1526   public final void setSERVERKEY(final byte[] serverkey) {
1527     serverAdminKey = serverkey;
1528   }
1529 
1530   /**
1531    * @param isSSL
1532    *
1533    * @return the HostId according to SSL
1534    *
1535    * @throws OpenR66ProtocolNoSslException
1536    */
1537   public final String getHostId(final boolean isSSL)
1538       throws OpenR66ProtocolNoSslException {
1539     if (isSSL) {
1540       if (getHostSslId() == null) {
1541         throw new OpenR66ProtocolNoSslException(
1542             Messages.getString("Configuration.ExcNoSSL")); //$NON-NLS-1$
1543       }
1544       return getHostSslId();
1545     } else {
1546       return getHostId();
1547     }
1548   }
1549 
1550   /**
1551    * @param remoteHost
1552    *
1553    * @return the HostId according to remoteHost (and its SSL status)
1554    *
1555    * @throws WaarpDatabaseException
1556    */
1557   public final String getHostId(final String remoteHost)
1558       throws WaarpDatabaseException {
1559     final DbHostAuth dbHostAuth = new DbHostAuth(remoteHost);
1560     try {
1561       return configuration.getHostId(dbHostAuth.isSsl());
1562     } catch (final OpenR66ProtocolNoSslException e) {
1563       throw new WaarpDatabaseException(e);
1564     }
1565   }
1566 
1567   private static class UsageStatistic extends TimerTask {
1568 
1569     @Override
1570     public void run() {
1571       logger.warn(hashStatus());
1572     }
1573 
1574   }
1575 
1576   public static String hashStatus() {
1577     String result = "\n";
1578     try {
1579       result += configuration.localTransaction.hashStatus() + '\n';
1580     } catch (final Exception e) {
1581       logger.warn(ISSUE_WHILE_DEBUGGING + " : {}", e.getMessage());
1582     }
1583     try {
1584       result += ClientRunner.hashStatus() + '\n';
1585     } catch (final Exception e) {
1586       logger.warn(ISSUE_WHILE_DEBUGGING + " : {}", e.getMessage());
1587     }
1588     try {
1589       result += DbTaskRunner.hashStatus() + '\n';
1590     } catch (final Exception e) {
1591       logger.warn(ISSUE_WHILE_DEBUGGING + " : {}", e.getMessage());
1592     }
1593     try {
1594       result += HttpSslHandler.hashStatus() + '\n';
1595     } catch (final Exception e) {
1596       logger.warn(ISSUE_WHILE_DEBUGGING + " : {}", e.getMessage());
1597     }
1598     try {
1599       result += NetworkTransaction.hashStatus();
1600     } catch (final Exception e) {
1601       logger.warn(ISSUE_WHILE_DEBUGGING + " : {}", e.getMessage());
1602     }
1603     return result;
1604   }
1605 
1606   /**
1607    * @return the nBDBSESSION
1608    */
1609   public static int getNbDbSession() {
1610     return nbDbSession;
1611   }
1612 
1613   /**
1614    * @param nBDBSESSION the nBDBSESSION to set
1615    */
1616   public static void setNbDbSession(final int nBDBSESSION) {
1617     nbDbSession = nBDBSESSION;
1618   }
1619 
1620   /**
1621    * @return the rANKRESTART
1622    */
1623   public static int getRankRestart() {
1624     return rankRestart;
1625   }
1626 
1627   /**
1628    * @param rANKRESTART the rANKRESTART to set
1629    */
1630   public static void setRankRestart(final int rANKRESTART) {
1631     rankRestart = rANKRESTART;
1632   }
1633 
1634   /**
1635    * @return the iSUNIX
1636    */
1637   public static boolean isIsUnix() {
1638     return isUnix;
1639   }
1640 
1641   /**
1642    * @param iSUNIX the iSUNIX to set
1643    */
1644   public static void setIsUnix(final boolean iSUNIX) {
1645     isUnix = iSUNIX;
1646   }
1647 
1648   /**
1649    * @return the r66BusinessFactory
1650    */
1651   public final R66BusinessFactoryInterface getR66BusinessFactory() {
1652     return r66BusinessFactory;
1653   }
1654 
1655   /**
1656    * @return the extendedProtocol
1657    */
1658   public final boolean isExtendedProtocol() {
1659     return extendedProtocol;
1660   }
1661 
1662   /**
1663    * @param extendedProtocol the extendedProtocol to set
1664    */
1665   public final void setExtendedProtocol(final boolean extendedProtocol) {
1666     this.extendedProtocol = extendedProtocol;
1667   }
1668 
1669   /**
1670    * @return the globalDigest
1671    */
1672   public final boolean isGlobalDigest() {
1673     return globalDigest;
1674   }
1675 
1676   /**
1677    * @param globalDigest the globalDigest to set
1678    */
1679   public final void setGlobalDigest(final boolean globalDigest) {
1680     this.globalDigest = globalDigest;
1681   }
1682 
1683   /**
1684    * @return the localDigest
1685    */
1686   public final boolean isLocalDigest() {
1687     return localDigest;
1688   }
1689 
1690   /**
1691    * @param localDigest the localDigest to set
1692    */
1693   public final void setLocalDigest(final boolean localDigest) {
1694     this.localDigest = localDigest;
1695   }
1696 
1697   /**
1698    * @return the businessWhiteSet
1699    */
1700   public final Set<String> getBusinessWhiteSet() {
1701     return businessWhiteSet;
1702   }
1703 
1704   /**
1705    * @return the roles
1706    */
1707   public final Map<String, RoleDefault> getRoles() {
1708     return roles;
1709   }
1710 
1711   /**
1712    * @return the aliases
1713    */
1714   public final Map<String, String> getAliases() {
1715     return aliases;
1716   }
1717 
1718   /**
1719    * @return the reverseAliases
1720    */
1721   public final Map<String, String[]> getReverseAliases() {
1722     return reverseAliases;
1723   }
1724 
1725   /**
1726    * @return the versions
1727    */
1728   public final ConcurrentMap<String, PartnerConfiguration> getVersions() {
1729     return versions;
1730   }
1731 
1732   /**
1733    * @return the hOST_ID
1734    */
1735   public final String getHostId() {
1736     return hostId;
1737   }
1738 
1739   /**
1740    * @param hostID the hOST_ID to set
1741    */
1742   public final void setHostId(final String hostID) {
1743     hostId = hostID;
1744     WaarpLoggerFactory.setLocalName(hostId);
1745   }
1746 
1747   /**
1748    * @return the hOST_SSLID
1749    */
1750   public final String getHostSslId() {
1751     return hostSslId;
1752   }
1753 
1754   /**
1755    * @param hostSSLID the hOST_SSLID to set
1756    */
1757   public final void setHostSslId(final String hostSSLID) {
1758     hostSslId = hostSSLID;
1759   }
1760 
1761   /**
1762    * @return the aDMINNAME
1763    */
1764   public final String getAdminName() {
1765     return adminName;
1766   }
1767 
1768   /**
1769    * @param aDMINNAME the aDMINNAME to set
1770    */
1771   public final void setAdminName(final String aDMINNAME) {
1772     adminName = aDMINNAME;
1773   }
1774 
1775   /**
1776    * @return the serverKeyFile
1777    */
1778   public final String getServerKeyFile() {
1779     return serverKeyFile;
1780   }
1781 
1782   /**
1783    * @param serverKeyFile the serverKeyFile to set
1784    */
1785   public final void setServerKeyFile(final String serverKeyFile) {
1786     this.serverKeyFile = serverKeyFile;
1787   }
1788 
1789   /**
1790    * @return the hOST_AUTH
1791    */
1792   public final DbHostAuth getHostAuth() {
1793     return hostAuth;
1794   }
1795 
1796   /**
1797    * @param hostAUTH the hOST_AUTH to set
1798    */
1799   public final void setHostAuth(final DbHostAuth hostAUTH) {
1800     hostAuth = hostAUTH;
1801   }
1802 
1803   /**
1804    * @return the hOST_SSLAUTH
1805    */
1806   public final DbHostAuth getHostSslAuth() {
1807     return hostSslAuth;
1808   }
1809 
1810   /**
1811    * @param hostSSLAUTH the hOST_SSLAUTH to set
1812    */
1813   public final void setHostSslAuth(final DbHostAuth hostSSLAUTH) {
1814     hostSslAuth = hostSSLAUTH;
1815   }
1816 
1817   public final String getAuthFile() {
1818     return authFile;
1819   }
1820 
1821   public final void setAuthFile(final String file) {
1822     authFile = file;
1823   }
1824 
1825   /**
1826    * @return the sERVER_THREAD
1827    */
1828   public final int getServerThread() {
1829     return serverThread;
1830   }
1831 
1832   /**
1833    * @param serverTHREAD the sERVER_THREAD to set
1834    */
1835   public final void setServerThread(final int serverTHREAD) {
1836     serverThread = serverTHREAD;
1837   }
1838 
1839   /**
1840    * @return the cLIENT_THREAD
1841    */
1842   public final int getClientThread() {
1843     return clientThread;
1844   }
1845 
1846   /**
1847    * @param clientTHREAD the cLIENT_THREAD to set
1848    */
1849   public final void setClientThread(final int clientTHREAD) {
1850     if (clientTHREAD > Commander.LIMIT_MAX_SUBMIT) {
1851       clientThread = Commander.LIMIT_MAX_SUBMIT;
1852     } else {
1853       clientThread = clientTHREAD;
1854     }
1855   }
1856 
1857   /**
1858    * @return the dEFAULT_SESSION_LIMIT
1859    */
1860   public final long getDEFAULT_SESSION_LIMIT() {
1861     return DEFAULT_SESSION_LIMIT;
1862   }
1863 
1864   /**
1865    * @return the dEFAULT_GLOBAL_LIMIT
1866    */
1867   public final long getDEFAULT_GLOBAL_LIMIT() {
1868     return DEFAULT_GLOBAL_LIMIT;
1869   }
1870 
1871   /**
1872    * @return the sERVER_PORT
1873    */
1874   public final int getServerPort() {
1875     return serverPort;
1876   }
1877 
1878   /**
1879    * @param serverPORT the sERVER_PORT to set
1880    */
1881   public final void setServerPort(final int serverPORT) {
1882     serverPort = serverPORT;
1883   }
1884 
1885   /**
1886    * @return the sERVER_SSLPORT
1887    */
1888   public final int getServerSslPort() {
1889     return serverSslPort;
1890   }
1891 
1892   /**
1893    * @param serverSSLPORT the sERVER_SSLPORT to set
1894    */
1895   public final void setServerSslPort(final int serverSSLPORT) {
1896     serverSslPort = serverSSLPORT;
1897   }
1898 
1899   /**
1900    * @return the sERVER_HTTPPORT
1901    */
1902   public final int getServerHttpport() {
1903     return serverHttpport;
1904   }
1905 
1906   /**
1907    * @param serverHTTPPORT the sERVER_HTTPPORT to set
1908    */
1909   public final void setServerHttpport(final int serverHTTPPORT) {
1910     serverHttpport = serverHTTPPORT;
1911   }
1912 
1913   /**
1914    * @return the sERVER_HTTPSPORT
1915    */
1916   public final int getServerHttpsPort() {
1917     return serverHttpsPort;
1918   }
1919 
1920   /**
1921    * @param serverHTTPSPORT the sERVER_HTTPSPORT to set
1922    */
1923   public final void setServerHttpsPort(final int serverHTTPSPORT) {
1924     serverHttpsPort = serverHTTPSPORT;
1925   }
1926 
1927   /**
1928    * @return the sERVER_Addresses
1929    */
1930   public final String[] getServerIpsAddresses() {
1931     return serverAddresses;
1932   }
1933 
1934   /**
1935    * @param serverAddresses the sERVER_Addresses to set
1936    */
1937   public final void setServerAddresses(final String[] serverAddresses) {
1938     this.serverAddresses = serverAddresses;
1939   }
1940 
1941   /**
1942    * @return the sERVER_SSLAddresses
1943    */
1944   public final String[] getServerSslAddresses() {
1945     return serverSslAddresses;
1946   }
1947 
1948   /**
1949    * @param serverSSLAddresses the sERVER_SSLIAddresses to set
1950    */
1951   public final void setServerSslAddresses(final String[] serverSSLAddresses) {
1952     serverSslAddresses = serverSSLAddresses;
1953   }
1954 
1955   /**
1956    * @return the sERVER_HTTPAddresses
1957    */
1958   public final String[] getServerHttpAddresses() {
1959     return serverHttpAddresses;
1960   }
1961 
1962   /**
1963    * @param serverHTTPAddresses the sERVER_HTTPAddresses to set
1964    */
1965   public final void setServerHttpAddresses(final String[] serverHTTPAddresses) {
1966     serverHttpAddresses = serverHTTPAddresses;
1967   }
1968 
1969   /**
1970    * @return the sERVER_HTTPSAddresses
1971    */
1972   public final String[] getServerHttpsAddresses() {
1973     return serverHttpsAddresses;
1974   }
1975 
1976   /**
1977    * @param serverHTTPSAddresses the sERVER_HTTPSAddresses to set
1978    */
1979   public final void setServerHttpsAddresses(
1980       final String[] serverHTTPSAddresses) {
1981     serverHttpsAddresses = serverHTTPSAddresses;
1982   }
1983 
1984   /**
1985    * @return the tIMEOUTCON
1986    */
1987   public final long getTimeoutCon() {
1988     return timeoutCon;
1989   }
1990 
1991   /**
1992    * @param timeoutCON the timeoutCON to set
1993    */
1994   public final void setTimeoutCon(final long timeoutCON) {
1995     timeoutCon = timeoutCON;
1996   }
1997 
1998   /**
1999    * @return the bLOCKSIZE
2000    */
2001   public final int getBlockSize() {
2002     return blockSize;
2003   }
2004 
2005   /**
2006    * @param blockSIZE the bLOCKSIZE to set
2007    */
2008   public final void setBlockSize(final int blockSIZE) {
2009     blockSize = blockSIZE;
2010   }
2011 
2012   /**
2013    * @return the maxGlobalMemory
2014    */
2015   public final int getMaxGlobalMemory() {
2016     return maxGlobalMemory;
2017   }
2018 
2019   /**
2020    * @param maxGlobalMemory the maxGlobalMemory to set
2021    */
2022   public final void setMaxGlobalMemory(final int maxGlobalMemory) {
2023     this.maxGlobalMemory = maxGlobalMemory;
2024   }
2025 
2026   /**
2027    * @return the restConfigurations
2028    */
2029   public final List<RestConfiguration> getRestConfigurations() {
2030     return restConfigurations;
2031   }
2032 
2033   /**
2034    * @return the baseDirectory
2035    */
2036   public final String getBaseDirectory() {
2037     return baseDirectory;
2038   }
2039 
2040   /**
2041    * @param baseDirectory the baseDirectory to set
2042    */
2043   public final void setBaseDirectory(final String baseDirectory) {
2044     this.baseDirectory = baseDirectory;
2045   }
2046 
2047   /**
2048    * @return the inPath
2049    */
2050   public final String getInPath() {
2051     return inPath;
2052   }
2053 
2054   /**
2055    * @param inPath the inPath to set
2056    */
2057   public final void setInPath(final String inPath) {
2058     this.inPath = inPath;
2059   }
2060 
2061   /**
2062    * @return the outPath
2063    */
2064   public final String getOutPath() {
2065     return outPath;
2066   }
2067 
2068   /**
2069    * @param outPath the outPath to set
2070    */
2071   public final void setOutPath(final String outPath) {
2072     this.outPath = outPath;
2073   }
2074 
2075   /**
2076    * @return the archivePath
2077    */
2078   public final String getArchivePath() {
2079     return archivePath;
2080   }
2081 
2082   /**
2083    * @param archivePath the archivePath to set
2084    */
2085   public final void setArchivePath(final String archivePath) {
2086     this.archivePath = archivePath;
2087   }
2088 
2089   /**
2090    * @return the workingPath
2091    */
2092   public final String getWorkingPath() {
2093     return workingPath;
2094   }
2095 
2096   /**
2097    * @param workingPath the workingPath to set
2098    */
2099   public final void setWorkingPath(final String workingPath) {
2100     this.workingPath = workingPath;
2101   }
2102 
2103   /**
2104    * @return the configPath
2105    */
2106   public final String getConfigPath() {
2107     return configPath;
2108   }
2109 
2110   /**
2111    * @param configPath the configPath to set
2112    */
2113   public final void setConfigPath(final String configPath) {
2114     this.configPath = configPath;
2115   }
2116 
2117   /**
2118    * @return the httpBasePath
2119    */
2120   public final String getHttpBasePath() {
2121     return httpBasePath;
2122   }
2123 
2124   /**
2125    * @param httpBasePath the httpBasePath to set
2126    */
2127   public final void setHttpBasePath(final String httpBasePath) {
2128     this.httpBasePath = httpBasePath;
2129   }
2130 
2131   /**
2132    * @return the httpModel
2133    */
2134   public final int getHttpModel() {
2135     return httpModel;
2136   }
2137 
2138   /**
2139    * @param httpModel the httpModel to set
2140    */
2141   public final void setHttpModel(final int httpModel) {
2142     this.httpModel = httpModel;
2143   }
2144 
2145   /**
2146    * @return the isShutdown
2147    */
2148   public final boolean isShutdown() {
2149     return isShutdown;
2150   }
2151 
2152   /**
2153    * @param isShutdown the isShutdown to set
2154    */
2155   public final void setShutdown(final boolean isShutdown) {
2156     this.isShutdown = isShutdown;
2157   }
2158 
2159   /**
2160    * @return the serverGlobalWriteLimit
2161    */
2162   public final long getServerGlobalWriteLimit() {
2163     return serverGlobalWriteLimit;
2164   }
2165 
2166   /**
2167    * @param serverGlobalWriteLimit the serverGlobalWriteLimit to set
2168    */
2169   public final void setServerGlobalWriteLimit(
2170       final long serverGlobalWriteLimit) {
2171     this.serverGlobalWriteLimit = serverGlobalWriteLimit;
2172   }
2173 
2174   /**
2175    * @return the serverGlobalReadLimit
2176    */
2177   public final long getServerGlobalReadLimit() {
2178     return serverGlobalReadLimit;
2179   }
2180 
2181   /**
2182    * @param serverGlobalReadLimit the serverGlobalReadLimit to set
2183    */
2184   public final void setServerGlobalReadLimit(final long serverGlobalReadLimit) {
2185     this.serverGlobalReadLimit = serverGlobalReadLimit;
2186   }
2187 
2188   /**
2189    * @return the serverChannelWriteLimit
2190    */
2191   public final long getServerChannelWriteLimit() {
2192     return serverChannelWriteLimit;
2193   }
2194 
2195   /**
2196    * @param serverChannelWriteLimit the serverChannelWriteLimit to set
2197    */
2198   public final void setServerChannelWriteLimit(
2199       final long serverChannelWriteLimit) {
2200     this.serverChannelWriteLimit = serverChannelWriteLimit;
2201   }
2202 
2203   /**
2204    * @return the serverChannelReadLimit
2205    */
2206   public final long getServerChannelReadLimit() {
2207     return serverChannelReadLimit;
2208   }
2209 
2210   /**
2211    * @param serverChannelReadLimit the serverChannelReadLimit to set
2212    */
2213   public final void setServerChannelReadLimit(
2214       final long serverChannelReadLimit) {
2215     this.serverChannelReadLimit = serverChannelReadLimit;
2216   }
2217 
2218   /**
2219    * @return the delayLimit
2220    */
2221   public final long getDelayLimit() {
2222     return delayLimit;
2223   }
2224 
2225   /**
2226    * @param delayLimit the delayLimit to set
2227    */
2228   public final void setDelayLimit(final long delayLimit) {
2229     this.delayLimit = delayLimit;
2230   }
2231 
2232   /**
2233    * @return the useSSL
2234    */
2235   public final boolean isUseSSL() {
2236     return useSSL;
2237   }
2238 
2239   /**
2240    * @param useSSL the useSSL to set
2241    */
2242   public final void setUseSSL(final boolean useSSL) {
2243     this.useSSL = useSSL;
2244   }
2245 
2246   /**
2247    * @return the useNOSSL
2248    */
2249   public final boolean isUseNOSSL() {
2250     return useNOSSL;
2251   }
2252 
2253   /**
2254    * @param useNOSSL the useNOSSL to set
2255    */
2256   public final void setUseNOSSL(final boolean useNOSSL) {
2257     this.useNOSSL = useNOSSL;
2258   }
2259 
2260   /**
2261    * @return the digest
2262    */
2263   public final FilesystemBasedDigest.DigestAlgo getDigest() {
2264     return digest;
2265   }
2266 
2267   /**
2268    * @param digest the digest to set
2269    */
2270   public final void setDigest(final FilesystemBasedDigest.DigestAlgo digest) {
2271     this.digest = digest;
2272   }
2273 
2274   /**
2275    * @return the useHttpCompression
2276    */
2277   public final boolean isUseHttpCompression() {
2278     return useHttpCompression;
2279   }
2280 
2281   /**
2282    * @param useHttpCompression the useHttpCompression to set
2283    */
2284   public final void setUseHttpCompression(final boolean useHttpCompression) {
2285     this.useHttpCompression = useHttpCompression;
2286   }
2287 
2288   /**
2289    * @return the cryptoKey
2290    */
2291   public final Des getCryptoKey() {
2292     return cryptoKey;
2293   }
2294 
2295   /**
2296    * @param cryptoKey the cryptoKey to set
2297    */
2298   public final void setCryptoKey(final Des cryptoKey) {
2299     this.cryptoKey = cryptoKey;
2300   }
2301 
2302   /**
2303    * @return the cryptoFile
2304    */
2305   public final String getCryptoFile() {
2306     return cryptoFile;
2307   }
2308 
2309   /**
2310    * @param cryptoFile the cryptoFile to set
2311    */
2312   public final void setCryptoFile(final String cryptoFile) {
2313     this.cryptoFile = cryptoFile;
2314   }
2315 
2316   /**
2317    * @return the useLocalExec
2318    */
2319   public final boolean isUseLocalExec() {
2320     return useLocalExec;
2321   }
2322 
2323   /**
2324    * @param useLocalExec the useLocalExec to set
2325    */
2326   public final void setUseLocalExec(final boolean useLocalExec) {
2327     this.useLocalExec = useLocalExec;
2328   }
2329 
2330   /**
2331    * @return the isServer
2332    */
2333   public final boolean isServer() {
2334     return isServer;
2335   }
2336 
2337   /**
2338    * @param isServer the isServer to set
2339    */
2340   protected final void setServer(final boolean isServer) {
2341     this.isServer = isServer;
2342   }
2343 
2344   /**
2345    * @return the rUNNER_THREAD
2346    */
2347   public final int getRunnerThread() {
2348     return runnerThread;
2349   }
2350 
2351   /**
2352    * @param runnerTHREAD the rUNNER_THREAD to set
2353    */
2354   public final void setRunnerThread(final int runnerTHREAD) {
2355     if (runnerTHREAD > Commander.LIMIT_MAX_SUBMIT) {
2356       logger.warn("RunnerThread at {} will be limited to default maximum {}",
2357                   runnerTHREAD, Commander.LIMIT_MAX_SUBMIT);
2358       runnerThread = Commander.LIMIT_MAX_SUBMIT;
2359     } else {
2360       runnerThread = runnerTHREAD <= 1? 2 : runnerTHREAD;
2361     }
2362   }
2363 
2364   /**
2365    * @return the delayCommander
2366    */
2367   public final long getDelayCommander() {
2368     return delayCommander;
2369   }
2370 
2371   /**
2372    * @param delayCommander the delayCommander to set
2373    */
2374   public final void setDelayCommander(final long delayCommander) {
2375     this.delayCommander = delayCommander;
2376   }
2377 
2378   /**
2379    * @return the delayRetry
2380    */
2381   public final long getDelayRetry() {
2382     return delayRetry;
2383   }
2384 
2385   /**
2386    * @param delayRetry the delayRetry to set
2387    */
2388   public final void setDelayRetry(final long delayRetry) {
2389     this.delayRetry = delayRetry;
2390   }
2391 
2392   /**
2393    * @return the constraintLimitHandler
2394    */
2395   public final R66ConstraintLimitHandler getConstraintLimitHandler() {
2396     return constraintLimitHandler;
2397   }
2398 
2399   /**
2400    * @param constraintLimitHandler the constraintLimitHandler to set
2401    */
2402   public final void setConstraintLimitHandler(
2403       final R66ConstraintLimitHandler constraintLimitHandler) {
2404     this.constraintLimitHandler = constraintLimitHandler;
2405   }
2406 
2407   /**
2408    * @return the checkRemoteAddress
2409    */
2410   public final boolean isCheckRemoteAddress() {
2411     return checkRemoteAddress;
2412   }
2413 
2414   /**
2415    * @param checkRemoteAddress the checkRemoteAddress to set
2416    */
2417   public final void setCheckRemoteAddress(final boolean checkRemoteAddress) {
2418     this.checkRemoteAddress = checkRemoteAddress;
2419   }
2420 
2421   /**
2422    * @return the checkClientAddress
2423    */
2424   public final boolean isCheckClientAddress() {
2425     return checkClientAddress;
2426   }
2427 
2428   /**
2429    * @param checkClientAddress the checkClientAddress to set
2430    */
2431   public final void setCheckClientAddress(final boolean checkClientAddress) {
2432     this.checkClientAddress = checkClientAddress;
2433   }
2434 
2435   /**
2436    * @return the saveTaskRunnerWithNoDb
2437    */
2438   public final boolean isSaveTaskRunnerWithNoDb() {
2439     return saveTaskRunnerWithNoDb;
2440   }
2441 
2442   /**
2443    * @param saveTaskRunnerWithNoDb the saveTaskRunnerWithNoDb to set
2444    */
2445   public final void setSaveTaskRunnerWithNoDb(
2446       final boolean saveTaskRunnerWithNoDb) {
2447     this.saveTaskRunnerWithNoDb = saveTaskRunnerWithNoDb;
2448   }
2449 
2450   /**
2451    * @return the multipleMonitors
2452    */
2453   public final int getMultipleMonitors() {
2454     return multipleMonitors;
2455   }
2456 
2457   /**
2458    * @param multipleMonitors the multipleMonitors to set
2459    */
2460   public final void setMultipleMonitors(final int multipleMonitors) {
2461     this.multipleMonitors = multipleMonitors;
2462   }
2463 
2464   /**
2465    * @return the monitoring
2466    */
2467   public final Monitoring getMonitoring() {
2468     return monitoring;
2469   }
2470 
2471   /**
2472    * @param monitoring the monitoring to set
2473    */
2474   public final void setMonitoring(final Monitoring monitoring) {
2475     this.monitoring = monitoring;
2476   }
2477 
2478   /**
2479    * @return the pastLimit
2480    */
2481   public final long getPastLimit() {
2482     return pastLimit;
2483   }
2484 
2485   /**
2486    * @param pastLimit the pastLimit to set
2487    */
2488   public final void setPastLimit(final long pastLimit) {
2489     this.pastLimit = pastLimit;
2490   }
2491 
2492   /**
2493    * @return the minimalDelay
2494    */
2495   public final long getMinimalDelay() {
2496     return minimalDelay;
2497   }
2498 
2499   /**
2500    * @param minimalDelay the minimalDelay to set
2501    */
2502   public final void setMinimalDelay(final long minimalDelay) {
2503     this.minimalDelay = minimalDelay;
2504   }
2505 
2506   /**
2507    * @return the snmpConfig
2508    */
2509   public final String getSnmpConfig() {
2510     return snmpConfig;
2511   }
2512 
2513   /**
2514    * @param snmpConfig the snmpConfig to set
2515    */
2516   public final void setSnmpConfig(final String snmpConfig) {
2517     this.snmpConfig = snmpConfig;
2518   }
2519 
2520   /**
2521    * @return the agentSnmp
2522    */
2523   public final WaarpSnmpAgent getAgentSnmp() {
2524     return agentSnmp;
2525   }
2526 
2527   /**
2528    * @param agentSnmp the agentSnmp to set
2529    */
2530   public final void setAgentSnmp(final WaarpSnmpAgent agentSnmp) {
2531     this.agentSnmp = agentSnmp;
2532   }
2533 
2534   /**
2535    * @return the r66Mib
2536    */
2537   public final R66PrivateMib getR66Mib() {
2538     return r66Mib;
2539   }
2540 
2541   /**
2542    * @param r66Mib the r66Mib to set
2543    */
2544   public final void setR66Mib(final R66PrivateMib r66Mib) {
2545     this.r66Mib = r66Mib;
2546   }
2547 
2548   /**
2549    * @return the waarpSecureKeyStore
2550    */
2551   public static WaarpSecureKeyStore getWaarpSecureKeyStore() {
2552     return waarpSecureKeyStore;
2553   }
2554 
2555   /**
2556    * @param waarpSecureKeyStore the waarpSecureKeyStore to set
2557    */
2558   public static void setWaarpSecureKeyStore(
2559       final WaarpSecureKeyStore waarpSecureKeyStore) {
2560     Configuration.waarpSecureKeyStore = waarpSecureKeyStore;
2561   }
2562 
2563   /**
2564    * @return the waarpSslContextFactory
2565    */
2566   public static WaarpSslContextFactory getWaarpSslContextFactory() {
2567     return waarpSslContextFactory;
2568   }
2569 
2570   /**
2571    * @param waarpSslContextFactory the waarpSslContextFactory to set
2572    */
2573   public static void setWaarpSslContextFactory(
2574       final WaarpSslContextFactory waarpSslContextFactory) {
2575     Configuration.waarpSslContextFactory = waarpSslContextFactory;
2576   }
2577 
2578   /**
2579    * @return the thriftService
2580    */
2581   public final R66ThriftServerService getThriftService() {
2582     return thriftService;
2583   }
2584 
2585   /**
2586    * @param thriftService the thriftService to set
2587    */
2588   public final void setThriftService(
2589       final R66ThriftServerService thriftService) {
2590     this.thriftService = thriftService;
2591   }
2592 
2593   /**
2594    * @return the thriftport
2595    */
2596   public final int getThriftport() {
2597     return thriftport;
2598   }
2599 
2600   /**
2601    * @param thriftport the thriftport to set
2602    */
2603   public final void setThriftport(final int thriftport) {
2604     this.thriftport = thriftport;
2605   }
2606 
2607   /**
2608    * @return the isExecuteErrorBeforeTransferAllowed
2609    */
2610   public final boolean isExecuteErrorBeforeTransferAllowed() {
2611     return isExecuteErrorBeforeTransferAllowed;
2612   }
2613 
2614   /**
2615    * @param isExecuteErrorBeforeTransferAllowed the
2616    *     isExecuteErrorBeforeTransferAllowed
2617    *     to set
2618    */
2619   public final void setExecuteErrorBeforeTransferAllowed(
2620       final boolean isExecuteErrorBeforeTransferAllowed) {
2621     this.isExecuteErrorBeforeTransferAllowed =
2622         isExecuteErrorBeforeTransferAllowed;
2623   }
2624 
2625   /**
2626    * @return the shutdownConfiguration
2627    */
2628   public final ShutdownConfiguration getShutdownConfiguration() {
2629     return shutdownConfiguration;
2630   }
2631 
2632   /**
2633    * @return the isHostProxyfied
2634    */
2635   public final boolean isHostProxyfied() {
2636     return isHostProxyfied;
2637   }
2638 
2639   /**
2640    * @param isHostProxyfied the isHostProxyfied to set
2641    */
2642   public final void setHostProxyfied(final boolean isHostProxyfied) {
2643     this.isHostProxyfied = isHostProxyfied;
2644   }
2645 
2646   /**
2647    * @return True if Authentication cannot be reused
2648    */
2649   public final boolean isAuthentNoReuse() {
2650     return authentNoReuse;
2651   }
2652 
2653   /**
2654    * @param authentNoReuse
2655    */
2656   public final void setAuthentNoReuse(final boolean authentNoReuse) {
2657     this.authentNoReuse = authentNoReuse;
2658   }
2659 
2660   /**
2661    * @param transferGuid
2662    */
2663   public final void setTransferGuid(final boolean transferGuid) {
2664     this.transferGuid = transferGuid;
2665     logger.warn("Startup: Transfer Id will use {}",
2666                 transferGuid? "GUID" : "SQL Sequence");
2667   }
2668 
2669   /**
2670    * @return True if the GUID is to use instead of getNextLong SQL based
2671    *     (default True)
2672    */
2673   public final boolean isTransferGuid() {
2674     return transferGuid;
2675   }
2676 
2677   /**
2678    * @return the warnOnStartup
2679    */
2680   public final boolean isWarnOnStartup() {
2681     return warnOnStartup;
2682   }
2683 
2684   /**
2685    * @param warnOnStartup the warnOnStartup to set
2686    */
2687   public final void setWarnOnStartup(final boolean warnOnStartup) {
2688     this.warnOnStartup = warnOnStartup;
2689   }
2690 
2691   /**
2692    * @return the chrootChecked
2693    */
2694   public final boolean isChrootChecked() {
2695     return chrootChecked;
2696   }
2697 
2698   /**
2699    * @param chrootChecked the chrootChecked to set
2700    */
2701   public final void setChrootChecked(final boolean chrootChecked) {
2702     this.chrootChecked = chrootChecked;
2703   }
2704 
2705   /**
2706    * @return the blacklistBadAuthent
2707    */
2708   public final boolean isBlacklistBadAuthent() {
2709     return blacklistBadAuthent;
2710   }
2711 
2712   /**
2713    * @param blacklistBadAuthent the blacklistBadAuthent to set
2714    */
2715   public final void setBlacklistBadAuthent(final boolean blacklistBadAuthent) {
2716     this.blacklistBadAuthent = blacklistBadAuthent;
2717   }
2718 
2719   /**
2720    * @return the maxfilenamelength
2721    */
2722   public final int getMaxfilenamelength() {
2723     return maxfilenamelength;
2724   }
2725 
2726   /**
2727    * @param maxfilenamelength the maxfilenamelength to set
2728    */
2729   public final void setMaxfilenamelength(final int maxfilenamelength) {
2730     this.maxfilenamelength = maxfilenamelength;
2731   }
2732 
2733   /**
2734    * @return the timeStat
2735    */
2736   public final int getTimeStat() {
2737     return timeStat;
2738   }
2739 
2740   /**
2741    * @param timeStat the timeStat to set
2742    */
2743   public final void setTimeStat(final int timeStat) {
2744     this.timeStat = timeStat;
2745   }
2746 
2747   /**
2748    * @return the limitCache
2749    */
2750   public final int getLimitCache() {
2751     return limitCache;
2752   }
2753 
2754   /**
2755    * @param limitCache the limitCache to set
2756    */
2757   public final void setLimitCache(final int limitCache) {
2758     this.limitCache = limitCache;
2759   }
2760 
2761   /**
2762    * @return the timeLimitCache
2763    */
2764   public final long getTimeLimitCache() {
2765     return timeLimitCache;
2766   }
2767 
2768   /**
2769    * @param timeLimitCache the timeLimitCache to set
2770    */
2771   public final void setTimeLimitCache(final long timeLimitCache) {
2772     this.timeLimitCache = timeLimitCache;
2773   }
2774 
2775   /**
2776    * Set the parameters for MonitorExporterTransfers using API REST
2777    *
2778    * @param url as 'http://myhost.com:8080' or 'https://myhost.com:8443'
2779    * @param basicAuthent Basic Authent in Base64 to connect to REST API if
2780    *     any (Basic authentication) (nullable)
2781    * @param token access token (Bearer Token authorization
2782    *     by Header) (nullable)
2783    * @param apiKey API Key (Base64 of 'apiId:apiKey') (ApiKey authorization
2784    *     by Header) (nullable)
2785    * @param endpoint as '/waarpr66monitor' or simply '/'
2786    * @param keepConnection True to keep the connexion opened, False to release the connexion each time
2787    * @param monitorIntervalIncluded True to include the interval information within 'waarpMonitor'
2788    *     field
2789    * @param monitorTransformLongAsString True to transform Long as String (ELK)
2790    * @param delay delay between 2 exports
2791    */
2792   public final void setMonitorExporterTransfers(final String url,
2793                                                 final String basicAuthent,
2794                                                 final String token,
2795                                                 final String apiKey,
2796                                                 final String endpoint,
2797                                                 final int delay,
2798                                                 final boolean keepConnection,
2799                                                 final boolean monitorIntervalIncluded,
2800                                                 final boolean monitorTransformLongAsString) {
2801     this.monitorExporterDelay = delay;
2802     this.monitorExporterUrl = url;
2803     this.monitorExporterEndPoint = endpoint;
2804     this.monitorExporterKeepConnection = keepConnection;
2805     this.monitorIntervalIncluded = monitorIntervalIncluded;
2806     this.monitorTransformLongAsString = monitorTransformLongAsString;
2807     this.monitorBasicAuthent = basicAuthent;
2808     this.monitorToken = token;
2809     this.monitorApiKey = apiKey;
2810     isMonitorExporterApiRest = true;
2811   }
2812 
2813   /**
2814    * @return True if the compression is available
2815    */
2816   public final boolean isCompressionAvailable() {
2817     return compressionAvailable;
2818   }
2819 
2820   /**
2821    * @param compressionAvailable
2822    */
2823   public final void setCompressionAvailable(
2824       final boolean compressionAvailable) {
2825     this.compressionAvailable = compressionAvailable;
2826   }
2827 
2828   /**
2829    * Set the parameters for MonitorExporterTransfers using Elasticsearch (JRE
2830    * >= 8)
2831    *
2832    * @param remoteBaseUrl as 'http://myelastic.com:9200' or 'https://myelastic.com:9201'
2833    * @param username username to connect to Elasticsearch if any (Basic
2834    *     authentication) (nullable)
2835    * @param pwd password to connect to Elasticsearch if any (Basic
2836    *     authentication) (nullable)
2837    * @param token access token (Bearer Token authorization
2838    *     by Header) (nullable)
2839    * @param apiKey API Key (Base64 of 'apiId:apiKey') (ApiKey authorization
2840    *     by Header) (nullable)
2841    * @param prefix as '/prefix' or null if none
2842    * @param index as 'waarpr66monitor' as the index name within
2843    *     Elasticsearch, including extra dynamic information
2844    * @param intervalMonitoringIncluded True to include the interval information within 'waarpMonitor' field
2845    * @param transformLongAsString True to transform Long as String (ELK)
2846    * @param compression True to compress REST exchanges between the client
2847    *     and the Elasticsearch server
2848    * @param delay delay between 2 exports
2849    *
2850    * @return True if the Elasticsearch factory is available
2851    */
2852   public final boolean setMonitorExporterTransfers(final String remoteBaseUrl,
2853                                                    final String username,
2854                                                    final String pwd,
2855                                                    final String token,
2856                                                    final String apiKey,
2857                                                    final String prefix,
2858                                                    final String index,
2859                                                    final boolean intervalMonitoringIncluded,
2860                                                    final boolean transformLongAsString,
2861                                                    final boolean compression,
2862                                                    final int delay) {
2863     this.monitorExporterDelay = delay;
2864     this.monitorExporterUrl = remoteBaseUrl;
2865     this.monitorIntervalIncluded = intervalMonitoringIncluded;
2866     this.monitorTransformLongAsString = transformLongAsString;
2867     this.monitorUsername = username;
2868     this.monitorPwd = pwd;
2869     this.monitorToken = token;
2870     this.monitorApiKey = apiKey;
2871     this.monitorPrefix = prefix;
2872     this.monitorIndex = index;
2873     this.monitorCompression = compression;
2874     isMonitorExporterApiRest = false;
2875     try {
2876       ElasticsearchMonitoringExporterClientBuilder.getFactory();
2877     } catch (final Exception e) {
2878       logger.error("Elasticsearch for MonitorExpoerter is not available in " +
2879                    "the classpath: {}", e.getMessage());
2880       return false;
2881     }
2882     return true;
2883   }
2884 
2885   /**
2886    * Start the Monitor Exporter Transfers (through REST API)
2887    */
2888   public final void startMonitorExporterTransfers() {
2889     if (monitorExporterUrl != null && monitorExporterEndPoint != null &&
2890         monitorExporterDelay > 500) {
2891       if (isMonitorExporterApiRest) {
2892         this.monitorExporterTransfers =
2893             new MonitorExporterTransfers(monitorExporterUrl,
2894                                          monitorExporterEndPoint,
2895                                          monitorBasicAuthent, monitorToken,
2896                                          monitorApiKey,
2897                                          monitorExporterKeepConnection,
2898                                          monitorIntervalIncluded,
2899                                          monitorTransformLongAsString,
2900                                          getHttpWorkerGroup());
2901       } else {
2902         this.monitorExporterTransfers =
2903             new MonitorExporterTransfers(monitorExporterUrl, monitorPrefix,
2904                                          monitorIndex, monitorUsername,
2905                                          monitorPwd, monitorToken,
2906                                          monitorApiKey, monitorIntervalIncluded,
2907                                          monitorTransformLongAsString,
2908                                          monitorCompression);
2909       }
2910       scheduleWithFixedDelay(monitorExporterTransfers, monitorExporterDelay,
2911                              TimeUnit.MILLISECONDS);
2912     }
2913   }
2914 
2915   /**
2916    * @param r66BusinessFactory the r66BusinessFactory to set
2917    */
2918   public final void setR66BusinessFactory(
2919       final R66BusinessFactoryInterface r66BusinessFactory) {
2920     this.r66BusinessFactory = r66BusinessFactory;
2921   }
2922 
2923   private static class CleanLruCache extends TimerTask {
2924 
2925     @Override
2926     public void run() {
2927       final int nb = DbTaskRunner.clearCache();
2928       logger.info("Clear Cache: " + nb);
2929     }
2930 
2931   }
2932 }