View Javadoc

1   /**
2      This file is part of GoldenGate Project (named also GoldenGate or GG).
3   
4      Copyright 2009, Frederic Bregier, 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 GoldenGate Project is free software: you can redistribute it and/or 
9      modify it under the terms of the GNU General Public License as published 
10     by the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12  
13     GoldenGate is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17  
18     You should have received a copy of the GNU General Public License
19     along with GoldenGate .  If not, see <http://www.gnu.org/licenses/>.
20   */
21  package openr66.protocol.configuration;
22  
23  import goldengate.common.crypto.Des;
24  import goldengate.common.crypto.ssl.GgSecureKeyStore;
25  import goldengate.common.crypto.ssl.GgSslContextFactory;
26  import goldengate.common.database.DbSession;
27  import goldengate.common.database.exception.GoldenGateDatabaseException;
28  import goldengate.common.database.exception.GoldenGateDatabaseNoConnectionException;
29  import goldengate.common.database.exception.GoldenGateDatabaseSqlException;
30  import goldengate.common.digest.FilesystemBasedDigest;
31  import goldengate.common.digest.FilesystemBasedDigest.DigestAlgo;
32  import goldengate.common.file.filesystembased.FilesystemBasedFileParameterImpl;
33  import goldengate.common.logging.GgInternalLogger;
34  import goldengate.common.logging.GgInternalLoggerFactory;
35  import goldengate.common.utility.GgThreadFactory;
36  import goldengate.snmp.GgMOFactory;
37  import goldengate.snmp.GgSnmpAgent;
38  
39  import java.io.File;
40  import java.io.IOException;
41  import java.net.InetSocketAddress;
42  import java.util.HashSet;
43  import java.util.concurrent.ExecutorService;
44  import java.util.concurrent.Executors;
45  import java.util.concurrent.TimeUnit;
46  
47  import openr66.commander.InternalRunner;
48  import openr66.context.R66BusinessFactoryInterface;
49  import openr66.context.R66DefaultBusinessFactory;
50  import openr66.context.R66FiniteDualStates;
51  import openr66.context.task.localexec.LocalExecClient;
52  import openr66.database.data.DbHostAuth;
53  import openr66.protocol.exception.OpenR66ProtocolNoDataException;
54  import openr66.protocol.exception.OpenR66ProtocolNoSslException;
55  import openr66.protocol.http.HttpPipelineFactory;
56  import openr66.protocol.http.adminssl.HttpSslPipelineFactory;
57  import openr66.protocol.localhandler.LocalTransaction;
58  import openr66.protocol.localhandler.Monitoring;
59  import openr66.protocol.localhandler.packet.LocalPacketSizeEstimator;
60  import openr66.protocol.networkhandler.ChannelTrafficHandler;
61  import openr66.protocol.networkhandler.GlobalTrafficHandler;
62  import openr66.protocol.networkhandler.NetworkServerPipelineFactory;
63  import openr66.protocol.networkhandler.R66ConstraintLimitHandler;
64  import openr66.protocol.networkhandler.packet.NetworkPacketSizeEstimator;
65  import openr66.protocol.networkhandler.ssl.NetworkSslServerPipelineFactory;
66  import openr66.protocol.snmp.R66PrivateMib;
67  import openr66.protocol.snmp.R66VariableFactory;
68  import openr66.protocol.utils.OpenR66SignalHandler;
69  import openr66.protocol.utils.Version;
70  
71  import org.jboss.netty.bootstrap.ServerBootstrap;
72  import org.jboss.netty.channel.ChannelFactory;
73  import org.jboss.netty.channel.group.ChannelGroup;
74  import org.jboss.netty.channel.group.DefaultChannelGroup;
75  import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
76  import org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor;
77  import org.jboss.netty.handler.traffic.ChannelTrafficShapingHandler;
78  import org.jboss.netty.handler.traffic.GlobalTrafficShapingHandler;
79  import org.jboss.netty.logging.InternalLoggerFactory;
80  import org.jboss.netty.util.HashedWheelTimer;
81  import org.jboss.netty.util.ObjectSizeEstimator;
82  import org.jboss.netty.util.Timer;
83  import org.jboss.netty.util.internal.ExecutorUtil;
84  
85  /**
86   * Configuration class
87   *
88   * @author Frederic Bregier
89   */
90  public class Configuration {
91      /**
92       * Internal Logger
93       */
94      private static final GgInternalLogger logger = GgInternalLoggerFactory
95              .getLogger(Configuration.class);
96  
97      // Static values
98      /**
99       * General Configuration object
100      */
101     public static Configuration configuration = new Configuration();
102 
103     public static final String SnmpName = "GoldenGate OpenR66 SNMP"; 
104     public static final int SnmpPrivateId = 66666;
105     public static final int SnmpR66Id = 66;
106     public static final String SnmpDefaultAuthor = "Frederic Bregier";
107     public static final String SnmpVersion = "GoldenGate OpenR66 "+Version.ID; 
108     public static final String SnmpDefaultLocalization = "Paris, France";
109     public static final int SnmpService = 72;
110     /**
111      * True if JDK6 or upper, False if JDK5.
112      */
113     public static final boolean USEJDK6 = true;
114     /**
115      * Time elapse for retry in ms
116      */
117     public static final long RETRYINMS = 10;
118 
119     /**
120      * Number of retry before error
121      */
122     public static final int RETRYNB = 3;
123 
124     /**
125      * Hack to say Windows or Unix (USR1 not OK on Windows)
126      */
127     public static boolean ISUNIX;
128 
129     /**
130      * Default size for buffers (NIO)
131      */
132     public static final int BUFFERSIZEDEFAULT = 0x10000; // 64K
133 
134     /**
135      * Time elapse for WRITE OR CLOSE WAIT elaps in ms
136      */
137     public static final long WAITFORNETOP = 1000;
138 
139     /**
140      * Extension of file during transfer
141      */
142     public static final String EXT_R66 = ".r66";
143 
144     /**
145      * Rank to redo when a restart occurs
146      */
147     public static int RANKRESTART = 30;
148 
149     /**
150      * FileParameter
151      */
152     private static final FilesystemBasedFileParameterImpl fileParameter =
153         new FilesystemBasedFileParameterImpl();
154 
155     public R66BusinessFactoryInterface r66BusinessFactory
156         = new R66DefaultBusinessFactory();
157     // Global Dynamic values
158     /**
159      * Version validation
160      */
161     public boolean extendedProtocol = true;
162     /**
163      * White List of allowed Partners to use Business Requests
164      */
165     public HashSet<String> businessWhiteSet = new HashSet<String>();
166     /**
167      * Actual Host ID
168      */
169     public String HOST_ID;
170     /**
171      * Actual SSL Host ID
172      */
173     public String HOST_SSLID;
174 
175     /**
176      * Server Administration user name
177      */
178     public String ADMINNAME = null;
179     /**
180      * Server Administration Key
181      */
182     private byte[] SERVERADMINKEY = null;
183     /**
184      * Server Actual Authentication
185      */
186     public DbHostAuth HOST_AUTH;
187     /**
188      * Server Actual SSL Authentication
189      */
190     public DbHostAuth HOST_SSLAUTH;
191 
192     /**
193      * Default number of threads in pool for Server (true network listeners).
194      * Server will change this value on startup if not set. The value should be
195      * closed to the number of CPU.
196      */
197     public int SERVER_THREAD = 8;
198 
199     /**
200      * Default number of threads in pool for Client. The value is for true
201      * client for Executor in the Pipeline for Business logic. The value does
202      * not indicate a limit of concurrent clients, but a limit on truly packet
203      * concurrent actions.
204      */
205     public int CLIENT_THREAD = 80;
206 
207     /**
208      * Default session limit 64Mbit, so up to 16 full simultaneous clients
209      */
210     public final long DEFAULT_SESSION_LIMIT = 0x800000L;
211 
212     /**
213      * Default global limit 1024Mbit
214      */
215     public final long DEFAULT_GLOBAL_LIMIT = 0x8000000L;
216 
217     /**
218      * Default server port
219      */
220     public int SERVER_PORT = 6666;
221 
222     /**
223      * Default SSL server port
224      */
225     public int SERVER_SSLPORT = 6667;
226 
227     /**
228      * Default HTTP server port
229      */
230     public int SERVER_HTTPPORT = 8066;
231 
232     /**
233      * Default HTTP server port
234      */
235     public int SERVER_HTTPSPORT = 8067;
236 
237     /**
238      * Nb of milliseconds after connection is in timeout
239      */
240     public long TIMEOUTCON = 30000;
241 
242     /**
243      * Size by default of block size for receive/sending files. Should be a
244      * multiple of 8192 (maximum = 2^30K due to block limitation to 4 bytes)
245      */
246     public int BLOCKSIZE = 0x10000; // 64K
247 
248     /**
249      * Max global memory limit: default is 4GB
250      */
251     public long maxGlobalMemory = 0x100000000L;
252 
253     /**
254      * Base Directory
255      */
256     public String baseDirectory;
257 
258     /**
259      * In path (receive)
260      */
261     public String inPath = null;
262 
263     /**
264      * Out path (send, copy, pending)
265      */
266     public String outPath = null;
267 
268     /**
269      * Archive path
270      */
271     public String archivePath = null;
272 
273     /**
274      * Working path
275      */
276     public String workingPath = null;
277 
278     /**
279      * Config path
280      */
281     public String configPath = null;
282 
283     /**
284      * Http Admin base
285      */
286     public String httpBasePath = "src/main/admin/";
287 
288     /**
289      * True if the service is going to shutdown
290      */
291     public volatile boolean isShutdown = false;
292 
293     /**
294      * Limit in Write byte/s to apply globally to the FTP Server
295      */
296     public long serverGlobalWriteLimit = DEFAULT_GLOBAL_LIMIT;
297 
298     /**
299      * Limit in Read byte/s to apply globally to the FTP Server
300      */
301     public long serverGlobalReadLimit = DEFAULT_GLOBAL_LIMIT;
302 
303     /**
304      * Limit in Write byte/s to apply by session to the FTP Server
305      */
306     public long serverChannelWriteLimit = DEFAULT_SESSION_LIMIT;
307 
308     /**
309      * Limit in Read byte/s to apply by session to the FTP Server
310      */
311     public long serverChannelReadLimit = DEFAULT_SESSION_LIMIT;
312 
313     /**
314      * Any limitation on bandwidth active?
315      */
316     public boolean anyBandwidthLimitation = false;
317     /**
318      * Delay in ms between two checks
319      */
320     public long delayLimit = 10000;
321 
322     /**
323      * Does this OpenR66 server will use and accept SSL connections
324      */
325     public boolean useSSL = false;
326     /**
327      * Does this OpenR66 server will use and accept non SSL connections
328      */
329     public boolean useNOSSL = true;
330     /**
331      * Algorithm to use for Digest
332      */
333     public FilesystemBasedDigest.DigestAlgo digest = DigestAlgo.MD5;
334 
335     /**
336      * Does this OpenR66 server will try to compress HTTP connections
337      */
338     public boolean useHttpCompression = false;
339 
340     /**
341      * Does this OpenR66 server will use GoldenGate LocalExec Daemon for ExecTask and ExecMoveTask
342      */
343     public boolean useLocalExec = false;
344 
345     /**
346      * Crypto Key
347      */
348     public Des cryptoKey = null;
349 
350     /**
351      * List of all Server Channels to enable the close call on them using Netty
352      * ChannelGroup
353      */
354     private ChannelGroup serverChannelGroup = null;
355     /**
356      * Does the current program running as Server
357      */
358     public boolean isServer = false;
359 
360     /**
361      * ExecutorService Server Boss
362      */
363     protected ExecutorService execServerBoss = Executors
364             .newCachedThreadPool();
365 
366     /**
367      * ExecutorService Server Worker
368      */
369     protected ExecutorService execServerWorker = Executors
370             .newCachedThreadPool();
371 
372 
373     /**
374      * ExecutorService Other Worker
375      */
376     protected ExecutorService execOtherWorker = Executors
377             .newCachedThreadPool();
378 
379     /**
380      * ChannelFactory for Server part
381      */
382     private ChannelFactory serverChannelFactory = null;
383 
384     /**
385      * ThreadPoolExecutor for Server
386      */
387     private volatile OrderedMemoryAwareThreadPoolExecutor serverPipelineExecutor;
388 
389     /**
390      * ThreadPoolExecutor for LocalServer
391      */
392     private volatile OrderedMemoryAwareThreadPoolExecutor localPipelineExecutor;
393 
394     /**
395      * ThreadPoolExecutor for LocalClient
396      */
397     private volatile OrderedMemoryAwareThreadPoolExecutor localClientPipelineExecutor;
398 
399     /**
400      * ThreadPoolExecutor for Http and Https Server
401      */
402     protected volatile OrderedMemoryAwareThreadPoolExecutor httpPipelineExecutor;
403 
404     /**
405      * Bootstrap for server
406      */
407     private ServerBootstrap serverBootstrap = null;
408 
409     /**
410      * Bootstrap for SSL server
411      */
412     private ServerBootstrap serverSslBootstrap = null;
413     /**
414      * Factory for NON SSL Server
415      */
416     private NetworkServerPipelineFactory networkServerPipelineFactory;
417     /**
418      * Factory for SSL Server
419      */
420     private NetworkSslServerPipelineFactory networkSslServerPipelineFactory;
421 
422     /**
423      * Bootstrap for Http server
424      */
425     protected ServerBootstrap httpBootstrap = null;
426     /**
427      * Bootstrap for Https server
428      */
429     protected ServerBootstrap httpsBootstrap = null;
430     /**
431      * ChannelFactory for HttpServer part
432      */
433     protected ChannelFactory httpChannelFactory = null;
434     /**
435      * ChannelFactory for HttpsServer part
436      */
437     protected ChannelFactory httpsChannelFactory = null;
438     /**
439      * List of all Http Channels to enable the close call on them using Netty
440      * ChannelGroup
441      */
442     protected ChannelGroup httpChannelGroup = null;
443 
444     /**
445      * Timer for CloseOpertations
446      */
447     private Timer timerCloseOperations = 
448         new HashedWheelTimer(new GgThreadFactory("TimerClose"), 50, TimeUnit.MILLISECONDS, 1024);
449 
450     /**
451      * Timer for TrafficCounter
452      */
453     private Timer timerTrafficCounter = 
454         new HashedWheelTimer(new GgThreadFactory("TimerTraffic"), 10, TimeUnit.MILLISECONDS, 1024);
455     /**
456      * Global TrafficCounter (set from global configuration)
457      */
458     private volatile GlobalTrafficHandler globalTrafficShapingHandler = null;
459 
460     /**
461      * ObjectSizeEstimator
462      */
463     protected ObjectSizeEstimator objectSizeEstimator = null;
464 
465     /**
466      * LocalTransaction
467      */
468     private LocalTransaction localTransaction;
469     /**
470      * InternalRunner
471      */
472     private InternalRunner internalRunner;
473     /**
474      * Maximum number of concurrent active transfer by submission.
475      */
476     public int RUNNER_THREAD = 1000;
477     /**
478      * Delay in ms between two steps of Commander
479      */
480     public long delayCommander = 5000;
481     /**
482      * Delay in ms between two retries
483      */
484     public long delayRetry = 30000;
485     /**
486      * Constraint Limit Handler on CPU usage and Connection limitation
487      */
488     public R66ConstraintLimitHandler constraintLimitHandler = 
489         new R66ConstraintLimitHandler();
490     /**
491      * Do we check Remote Address from DbHost
492      */
493     public boolean checkRemoteAddress = false;
494     /**
495      * Do we check address even for Client
496      */
497     public boolean checkClientAddress = false;
498     /**
499      * For No Db client, do we saved TaskRunner in a XML
500      */
501     public boolean saveTaskRunnerWithNoDb = false;
502     /**
503      * In case of Multiple OpenR66 monitor servers behing a load balancer (HA solution)
504      */
505     public int multipleMonitors = 1;
506     /**
507      * Monitoring object
508      */
509     public Monitoring monitoring = null;
510     /**
511      * Monitoring: how long in ms to get back in monitoring
512      */
513     public long pastLimit = 86400000; // 24H
514     /**
515      * Monitoring: minimal interval in ms before redo real monitoring
516      */
517     public long minimalDelay = 5000; // 5 seconds
518     /**
519      * Monitoring: snmp configuration file (empty means no snmp support)
520      */
521     public String snmpConfig = null;
522     /**
523      * SNMP Agent (if any)
524      */
525     public GgSnmpAgent agentSnmp = null;
526     /**
527      * Associated MIB
528      */
529     public R66PrivateMib r66Mib = null;
530     
531     private volatile boolean configured = false;
532 
533     public static GgSecureKeyStore ggSecureKeyStore;
534 
535     public static GgSslContextFactory ggSslContextFactory;
536 
537     public Configuration() {
538         // Init signal handler
539         OpenR66SignalHandler.initSignalHandler();
540         computeNbThreads();
541         // Init FiniteStates
542         R66FiniteDualStates.initR66FiniteStates();
543     }
544     
545     /**
546      * Configure the pipeline for client (to be called ony once)
547      */
548     public void pipelineInit() {
549         if (configured) {
550             return;
551         }
552         localTransaction = new LocalTransaction();
553         InternalLoggerFactory.setDefaultFactory(InternalLoggerFactory
554                 .getDefaultFactory());
555         objectSizeEstimator = new NetworkPacketSizeEstimator();
556         httpPipelineInit();
557         logger.warn("Server Thread: "+SERVER_THREAD+" Client Thread: "+CLIENT_THREAD+" Runner Thread: "+RUNNER_THREAD);
558         serverPipelineExecutor = new OrderedMemoryAwareThreadPoolExecutor(
559                 CLIENT_THREAD, maxGlobalMemory / 10, maxGlobalMemory, 1000,
560                 TimeUnit.MILLISECONDS, objectSizeEstimator, new GgThreadFactory("ServerExecutor"));
561         localPipelineExecutor = new OrderedMemoryAwareThreadPoolExecutor(
562                 CLIENT_THREAD * 100, maxGlobalMemory / 10, maxGlobalMemory,
563                 1000, TimeUnit.MILLISECONDS, new LocalPacketSizeEstimator(),
564                 new GgThreadFactory("LocalExecutor"));
565         localClientPipelineExecutor = new OrderedMemoryAwareThreadPoolExecutor(
566                 CLIENT_THREAD * 100, maxGlobalMemory / 10, maxGlobalMemory,
567                 1000, TimeUnit.MILLISECONDS, new LocalPacketSizeEstimator(),
568                 new GgThreadFactory("LocalClientExecutor"));
569         if (useLocalExec) {
570             LocalExecClient.initialize();
571         }
572         configured = true;
573     }
574 
575     public void httpPipelineInit() {
576         httpPipelineExecutor = new OrderedMemoryAwareThreadPoolExecutor(
577                 CLIENT_THREAD, maxGlobalMemory / 10, maxGlobalMemory, 1000,
578                 TimeUnit.MILLISECONDS, objectSizeEstimator, new GgThreadFactory("HttpExecutor"));
579     }
580     
581     /**
582      * Startup the server
583      * @throws GoldenGateDatabaseSqlException
584      * @throws GoldenGateDatabaseNoConnectionException
585      */
586     public void serverStartup() throws GoldenGateDatabaseNoConnectionException, GoldenGateDatabaseSqlException {
587         isServer = true;
588         if ((!useNOSSL) && (!useSSL)) {
589             logger.error("OpenR66 has neither NOSSL nor SSL support included! Stop here!");
590             System.exit(-1);
591         }
592         pipelineInit();
593         r66Startup();
594         startHttpSupport();
595         startMonitoring();
596     }
597     
598     public void r66Startup() throws GoldenGateDatabaseNoConnectionException, GoldenGateDatabaseSqlException {
599         logger.debug("Start R66: "+SERVER_PORT+":"+useNOSSL+" "+SERVER_SSLPORT+":"+useSSL+":"+HOST_SSLID);
600         // add into configuration
601         this.constraintLimitHandler.setServer(true);
602         // Global Server
603         serverChannelGroup = new DefaultChannelGroup("OpenR66");
604 
605         serverChannelFactory = new NioServerSocketChannelFactory(
606                 execServerBoss, execServerWorker, SERVER_THREAD);
607         if (useNOSSL) {
608             serverBootstrap = new ServerBootstrap(serverChannelFactory);
609             networkServerPipelineFactory = new NetworkServerPipelineFactory(true);
610             serverBootstrap.setPipelineFactory(networkServerPipelineFactory);
611             serverBootstrap.setOption("child.tcpNoDelay", true);
612             serverBootstrap.setOption("child.keepAlive", true);
613             serverBootstrap.setOption("child.reuseAddress", true);
614             serverBootstrap.setOption("child.connectTimeoutMillis", TIMEOUTCON);
615             serverBootstrap.setOption("tcpNoDelay", true);
616             serverBootstrap.setOption("reuseAddress", true);
617             serverBootstrap.setOption("connectTimeoutMillis", TIMEOUTCON);
618 
619             serverChannelGroup.add(serverBootstrap.bind(new InetSocketAddress(
620                     SERVER_PORT)));
621         } else {
622             networkServerPipelineFactory = null;
623             logger.warn("NOSSL mode is deactivated");
624         }
625 
626         if (useSSL && HOST_SSLID != null) {
627             serverSslBootstrap = new ServerBootstrap(serverChannelFactory);
628             networkSslServerPipelineFactory = new NetworkSslServerPipelineFactory(false,
629                     execServerWorker);
630             serverSslBootstrap.setPipelineFactory(networkSslServerPipelineFactory);
631             serverSslBootstrap.setOption("child.tcpNoDelay", true);
632             serverSslBootstrap.setOption("child.keepAlive", true);
633             serverSslBootstrap.setOption("child.reuseAddress", true);
634             serverSslBootstrap.setOption("child.connectTimeoutMillis", TIMEOUTCON);
635             serverSslBootstrap.setOption("tcpNoDelay", true);
636             serverSslBootstrap.setOption("reuseAddress", true);
637             serverSslBootstrap.setOption("connectTimeoutMillis", TIMEOUTCON);
638 
639             serverChannelGroup.add(serverSslBootstrap.bind(new InetSocketAddress(
640                     SERVER_SSLPORT)));
641         } else {
642             networkSslServerPipelineFactory = null;
643             logger.warn("SSL mode is desactivated");
644         }
645 
646         // Factory for TrafficShapingHandler
647         globalTrafficShapingHandler = new GlobalTrafficHandler(
648                 objectSizeEstimator, timerTrafficCounter,
649                 serverGlobalWriteLimit, serverGlobalReadLimit, delayLimit);
650         this.constraintLimitHandler.setHandler(globalTrafficShapingHandler);
651 
652         // Now start the InternalRunner
653         internalRunner = new InternalRunner();
654     }
655     
656     public void startHttpSupport() {
657         // Now start the HTTP support
658         httpChannelGroup = new DefaultChannelGroup("HttpOpenR66");
659         // Configure the server.
660         httpChannelFactory = new NioServerSocketChannelFactory(
661                 execServerBoss,
662                 execServerWorker,
663                 SERVER_THREAD);
664         httpBootstrap = new ServerBootstrap(
665                 httpChannelFactory);
666         // Set up the event pipeline factory.
667         httpBootstrap.setPipelineFactory(new HttpPipelineFactory(useHttpCompression));
668         httpBootstrap.setOption("child.tcpNoDelay", true);
669         httpBootstrap.setOption("child.keepAlive", true);
670         httpBootstrap.setOption("child.reuseAddress", true);
671         httpBootstrap.setOption("child.connectTimeoutMillis", TIMEOUTCON);
672         httpBootstrap.setOption("tcpNoDelay", true);
673         httpBootstrap.setOption("reuseAddress", true);
674         httpBootstrap.setOption("connectTimeoutMillis", TIMEOUTCON);
675         // Bind and start to accept incoming connections.
676         httpChannelGroup.add(httpBootstrap.bind(new InetSocketAddress(SERVER_HTTPPORT)));
677 
678         // Now start the HTTPS support
679         // Configure the server.
680         httpsChannelFactory = new NioServerSocketChannelFactory(
681                 execServerBoss,
682                 execServerWorker,
683                 SERVER_THREAD);
684         httpsBootstrap = new ServerBootstrap(
685                 httpsChannelFactory);
686         // Set up the event pipeline factory.
687         httpsBootstrap.setPipelineFactory(new HttpSslPipelineFactory(useHttpCompression,
688                 false, execServerWorker));
689         httpsBootstrap.setOption("child.tcpNoDelay", true);
690         httpsBootstrap.setOption("child.keepAlive", true);
691         httpsBootstrap.setOption("child.reuseAddress", true);
692         httpsBootstrap.setOption("child.connectTimeoutMillis", TIMEOUTCON);
693         httpsBootstrap.setOption("tcpNoDelay", true);
694         httpsBootstrap.setOption("reuseAddress", true);
695         httpsBootstrap.setOption("connectTimeoutMillis", TIMEOUTCON);
696         // Bind and start to accept incoming connections.
697         httpChannelGroup.add(httpsBootstrap.bind(new InetSocketAddress(SERVER_HTTPSPORT)));
698     }
699     
700     public void startMonitoring() throws GoldenGateDatabaseSqlException {
701         monitoring = new Monitoring(pastLimit, minimalDelay, null);
702         if (snmpConfig != null) {
703             int snmpPortShow = (useNOSSL ? SERVER_PORT : SERVER_SSLPORT);
704             r66Mib = 
705                 new R66PrivateMib(SnmpName, 
706                         snmpPortShow, 
707                         SnmpPrivateId, 
708                         SnmpR66Id, 
709                         SnmpDefaultAuthor,
710                         SnmpVersion, 
711                         SnmpDefaultLocalization, 
712                         SnmpService);
713             GgMOFactory.factory = new R66VariableFactory();
714             agentSnmp = new GgSnmpAgent(new File(snmpConfig), monitoring, r66Mib);
715             try {
716                 agentSnmp.start();
717             } catch (IOException e) {
718                 throw new GoldenGateDatabaseSqlException("AgentSnmp Error while starting", e);
719             }
720         }
721     }
722     public InternalRunner getInternalRunner() {
723         return internalRunner;
724     }
725     /**
726      * Prepare the server to stop
727      *
728      * To be called early before other stuff will be closed
729      */
730     public void prepareServerStop() {
731         if (internalRunner != null) {
732             internalRunner.prepareStopInternalRunner();
733         }
734     }
735     /**
736      * Stops the server
737      *
738      * To be called after all other stuff are closed (channels, connections)
739      */
740     public void serverStop() {
741         if (internalRunner != null) {
742             internalRunner.stopInternalRunner();
743         }
744         if (agentSnmp != null) {
745             agentSnmp.stop();
746         } else if (monitoring != null) {
747             monitoring.releaseResources();
748             monitoring = null;
749         }
750         if (execServerBoss != null) {
751             ExecutorUtil.terminate(execServerBoss);
752             execServerBoss = null;
753         }
754         if (execServerWorker != null) {
755             ExecutorUtil.terminate(execServerWorker);
756             execServerWorker = null;
757         }
758         if (execOtherWorker != null) {
759             execOtherWorker.shutdownNow();
760             execOtherWorker = null;
761         }
762         if (timerTrafficCounter != null) {
763             timerTrafficCounter.stop();
764         }
765         if (timerCloseOperations != null) {
766             timerCloseOperations.stop();
767         }
768     }
769     /**
770      * To be called after all other stuff are closed for Client
771      */
772     public void clientStop() {
773         if (localTransaction != null) {
774             localTransaction.closeAll();
775             localTransaction = null;
776         }
777         if (serverPipelineExecutor != null) {
778             ExecutorUtil.terminate(serverPipelineExecutor);
779             serverPipelineExecutor = null;
780         }
781         if (localPipelineExecutor != null) {
782             ExecutorUtil.terminate(localPipelineExecutor);
783             localPipelineExecutor = null;
784         }
785         if (localClientPipelineExecutor != null) {
786             ExecutorUtil.terminate(localClientPipelineExecutor);
787             localClientPipelineExecutor = null;
788         }
789         if (httpPipelineExecutor != null) {
790             ExecutorUtil.terminate(httpPipelineExecutor);
791             httpPipelineExecutor = null;
792         }
793         if (useLocalExec) {
794             LocalExecClient.releaseResources();
795         }
796         if (timerTrafficCounter != null) {
797             timerTrafficCounter.stop();
798         }
799         if (timerCloseOperations != null) {
800             timerCloseOperations.stop();
801         }
802         r66BusinessFactory.releaseResources();
803     }
804     /**
805      * Try to reload the Commander
806      * @return True if reloaded, else in error
807      */
808     public boolean reloadCommanderDelay() {
809         if (internalRunner != null) {
810             try {
811                 internalRunner.reloadInternalRunner();
812                 return true;
813             } catch (GoldenGateDatabaseNoConnectionException e) {
814             } catch (GoldenGateDatabaseSqlException e) {
815             }
816         }
817         return false;
818     }
819     /**
820      * Reset the global monitor for bandwidth limitation and change future
821      * channel monitors
822      *
823      * @param writeGlobalLimit
824      * @param readGlobalLimit
825      * @param writeSessionLimit
826      * @param readSessionLimit
827      * @param delayLimit
828      */
829     public void changeNetworkLimit(long writeGlobalLimit, long readGlobalLimit,
830             long writeSessionLimit, long readSessionLimit, long delayLimit) {
831         long newWriteLimit = writeGlobalLimit > 1024? writeGlobalLimit
832                 : serverGlobalWriteLimit;
833         if (writeGlobalLimit <= 0) {
834             newWriteLimit = 0;
835         }
836         long newReadLimit = readGlobalLimit > 1024? readGlobalLimit
837                 : serverGlobalReadLimit;
838         if (readGlobalLimit <= 0) {
839             newReadLimit = 0;
840         }
841         serverGlobalReadLimit = newReadLimit;
842         serverGlobalWriteLimit = newWriteLimit;
843         this.delayLimit = delayLimit;
844         if (globalTrafficShapingHandler != null) {
845             globalTrafficShapingHandler.configure(serverGlobalWriteLimit, serverGlobalReadLimit, delayLimit);
846             logger.warn("Bandwidth limits change: {}", globalTrafficShapingHandler);
847         }
848         newWriteLimit = writeSessionLimit > 1024? writeSessionLimit
849                 : serverChannelWriteLimit;
850         if (writeSessionLimit <= 0) {
851             newWriteLimit = 0;
852         }
853         newReadLimit = readSessionLimit > 1024? readSessionLimit
854                 : serverChannelReadLimit;
855         if (readSessionLimit <= 0) {
856             newReadLimit = 0;
857         }
858         serverChannelReadLimit = newReadLimit;
859         serverChannelWriteLimit = newWriteLimit;
860         anyBandwidthLimitation = (serverGlobalReadLimit > 0 || serverGlobalWriteLimit > 0 || 
861                 serverChannelReadLimit > 0 || serverChannelWriteLimit > 0);
862     }
863 
864     /**
865      * Compute number of threads for both client and server from the real number
866      * of available processors (double + 1) if the value is less than 32
867      * threads else (available +1).
868      */
869     public void computeNbThreads() {
870         int nb = Runtime.getRuntime().availableProcessors() * 2 + 1;
871         if (nb > 32) {
872             nb = Runtime.getRuntime().availableProcessors() + 1;
873         }
874         if (SERVER_THREAD < nb) {
875             logger.info("Change default number of threads to " + nb);
876             SERVER_THREAD = nb;
877             CLIENT_THREAD = SERVER_THREAD*10;
878         }
879     }
880 
881     /**
882      * @return a new ChannelTrafficShapingHandler
883      * @throws OpenR66ProtocolNoDataException
884      */
885     public ChannelTrafficShapingHandler newChannelTrafficShapingHandler() throws OpenR66ProtocolNoDataException {
886         if (serverChannelReadLimit == 0 && serverChannelWriteLimit == 0) {
887             throw new OpenR66ProtocolNoDataException("No limit for channel");
888         }
889         return new ChannelTrafficHandler(objectSizeEstimator,
890                 timerTrafficCounter, serverChannelWriteLimit,
891                 serverChannelReadLimit, delayLimit);
892     }
893     /**
894      * 
895      * @return an executorService to be used for any thread
896      */
897     public ExecutorService getExecutorService() {
898         return execOtherWorker;
899     }
900     
901     /**
902      * @return the timer
903      */
904     public Timer getTimerTraffic() {
905         return timerTrafficCounter;
906     }
907 
908     public Timer getTimerClose() {
909         return timerCloseOperations;
910     }
911     
912     /**
913      * @return the globalTrafficShapingHandler
914      */
915     public GlobalTrafficShapingHandler getGlobalTrafficShapingHandler() {
916         return globalTrafficShapingHandler;
917     }
918 
919     /**
920      * @return the serverChannelGroup
921      */
922     public ChannelGroup getServerChannelGroup() {
923         return serverChannelGroup;
924     }
925 
926     /**
927      * @return the serverChannelFactory
928      */
929     public ChannelFactory getServerChannelFactory() {
930         return serverChannelFactory;
931     }
932     /**
933      * @return the httpChannelGroup
934      */
935     public ChannelGroup getHttpChannelGroup() {
936         return httpChannelGroup;
937     }
938 
939     /**
940      * @return the httpChannelFactory
941      */
942     public ChannelFactory getHttpChannelFactory() {
943         return httpChannelFactory;
944     }
945     /**
946      * @return the httpsChannelFactory
947      */
948     public ChannelFactory getHttpsChannelFactory() {
949         return httpsChannelFactory;
950     }
951     /**
952      * @return the serverPipelineExecutor
953      */
954     public OrderedMemoryAwareThreadPoolExecutor getServerPipelineExecutor() {
955         return serverPipelineExecutor;
956     }
957 
958     /**
959      * @return the localPipelineExecutor
960      */
961     public OrderedMemoryAwareThreadPoolExecutor getLocalPipelineExecutor() {
962         return localPipelineExecutor;
963     }
964 
965     /**
966      * @return the localPipelineExecutor
967      */
968     public OrderedMemoryAwareThreadPoolExecutor getLocalClientPipelineExecutor() {
969         return localClientPipelineExecutor;
970     }
971 
972     /**
973      * @return the httpPipelineExecutor
974      */
975     public OrderedMemoryAwareThreadPoolExecutor getHttpPipelineExecutor() {
976         return httpPipelineExecutor;
977     }
978 
979     /**
980      * @return the localTransaction
981      */
982     public LocalTransaction getLocalTransaction() {
983         return localTransaction;
984     }
985 
986     /**
987      *
988      * @return the FilesystemBasedFileParameterImpl
989      */
990     public static FilesystemBasedFileParameterImpl getFileParameter() {
991         return fileParameter;
992     }
993 
994     /**
995      * @return the SERVERADMINKEY
996      */
997     public byte[] getSERVERADMINKEY() {
998         return SERVERADMINKEY;
999     }
1000 
1001     /**
1002      * Is the given key a valid one
1003      *
1004      * @param newkey
1005      * @return True if the key is valid (or any key is valid)
1006      */
1007     public boolean isKeyValid(byte[] newkey) {
1008         if (newkey == null) {
1009             return false;
1010         }
1011         return FilesystemBasedDigest.equalPasswd(SERVERADMINKEY, newkey);
1012     }
1013 
1014     /**
1015      * @param serverkey
1016      *            the SERVERADMINKEY to set
1017      */
1018     public void setSERVERKEY(byte[] serverkey) {
1019         SERVERADMINKEY = serverkey;
1020     }
1021     /**
1022      *
1023      * @param isSSL
1024      * @return the HostId according to SSL
1025      * @throws OpenR66ProtocolNoSslException
1026      */
1027     public String getHostId(boolean isSSL) throws OpenR66ProtocolNoSslException {
1028         if (isSSL) {
1029             if (HOST_SSLID == null) {
1030                 throw new OpenR66ProtocolNoSslException("No SSL support");
1031             }
1032             return HOST_SSLID;
1033         } else {
1034             return HOST_ID;
1035         }
1036     }
1037     /**
1038      *
1039      * @param dbSession
1040      * @param remoteHost
1041      * @return the HostId according to remoteHost (and its SSL status)
1042      * @throws GoldenGateDatabaseException
1043      */
1044     public String getHostId(DbSession dbSession, String remoteHost) throws GoldenGateDatabaseException {
1045         DbHostAuth hostAuth = new DbHostAuth(dbSession,remoteHost);
1046         try {
1047             return Configuration.configuration.getHostId(hostAuth.isSsl());
1048         } catch (OpenR66ProtocolNoSslException e) {
1049             throw new GoldenGateDatabaseException(e);
1050         }
1051     }
1052 }