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 goldengate.ftp.core.config;
22  
23  import goldengate.common.file.FileParameterInterface;
24  import goldengate.ftp.core.control.BusinessHandler;
25  import goldengate.ftp.core.data.handler.DataBusinessHandler;
26  import goldengate.ftp.core.exception.FtpUnknownFieldException;
27  import goldengate.ftp.core.session.FtpSession;
28  
29  import java.io.File;
30  import java.net.InetAddress;
31  import java.net.InetSocketAddress;
32  import java.util.HashMap;
33  import java.util.concurrent.locks.Lock;
34  import java.util.concurrent.locks.ReentrantLock;
35  
36  import org.jboss.netty.channel.Channel;
37  
38  /**
39   * Abstract class for configuration
40   *
41   * @author Frederic Bregier
42   *
43   */
44  public abstract class FtpConfiguration {
45      /**
46       * True if use of JDK6 or upper, False if JDK5.
47       */
48      public static final boolean USEJDK6 = true;
49      // FTP Configuration: Externals
50      /**
51       * Default session limit 64Mbit, so up to 8 full simultaneous clients
52       */
53      public static long DEFAULT_SESSION_LIMIT = 0x800000L;
54  
55      /**
56       * Default global limit 512Mbit
57       */
58      public static long DEFAULT_GLOBAL_LIMIT = 0x4000000L;
59  
60  
61      /**
62       * PASSWORD for SHUTDOWN
63       */
64      private static final String FTP_PASSWORD = "FTP_PASSWORD";
65  
66      // END OF STATIC VALUES
67      /**
68       * Internal configuration
69       */
70      private final FtpInternalConfiguration internalConfiguration;
71  
72      /**
73       * SERVER PORT
74       */
75      private int SERVER_PORT = 21;
76      /**
77       * Default Address if any
78       */
79      private String SERVER_ADDRESS = null;
80  
81      /**
82       * Base Directory
83       */
84      private String BASE_DIRECTORY = null;
85  
86      /**
87       * Associated FileParameterInterface
88       */
89      private final FileParameterInterface fileParameter;
90  
91      /**
92       * True if the service is going to shutdown
93       */
94      public volatile boolean isShutdown = false;
95  
96      /**
97       * Default number of threads in pool for Server. The default value is for
98       * client for Executor in the Pipeline for Business logic. Server will
99       * change this value on startup if not set.
100      */
101     public int SERVER_THREAD = 8;
102 
103     /**
104      * Default number of threads in pool for Client part.
105      */
106     public int CLIENT_THREAD = 80;
107 
108     /**
109      * Which class owns this configuration
110      */
111     public Class<?> fromClass = null;
112 
113     /**
114      * Which class will be used for DataBusinessHandler
115      */
116     public Class<? extends DataBusinessHandler> dataBusinessHandler = null;
117 
118     /**
119      * Which class will be used for BusinessHandler
120      */
121     public Class<? extends BusinessHandler> businessHandler = null;
122 
123     /**
124      * Internal Lock
125      */
126     private ReentrantLock lock = new ReentrantLock();
127 
128     /**
129      * Nb of milliseconds after connection is in timeout
130      */
131     public long TIMEOUTCON = 30000;
132 
133     /**
134      * Size by default of block size for receive/sending files. Should be a
135      * multiple of 8192 (maximum = 64K due to block limitation to 2 bytes)
136      */
137     public int BLOCKSIZE = 0x10000; // 64K
138 
139     /**
140      * Limit in Write byte/s to apply globally to the FTP Server
141      */
142     protected long serverGlobalWriteLimit = DEFAULT_GLOBAL_LIMIT;
143 
144     /**
145      * Limit in Read byte/s to apply globally to the FTP Server
146      */
147     protected long serverGlobalReadLimit = DEFAULT_GLOBAL_LIMIT;
148 
149     /**
150      * Limit in Write byte/s to apply by session to the FTP Server
151      */
152     protected long serverChannelWriteLimit = DEFAULT_SESSION_LIMIT;
153 
154     /**
155      * Limit in Read byte/s to apply by session to the FTP Server
156      */
157     protected long serverChannelReadLimit = DEFAULT_SESSION_LIMIT;
158 
159     /**
160      * Delay in ms between two checks
161      */
162     protected long delayLimit = 1000;
163 
164     /**
165      * Should the file be deleted when the transfer is aborted on STOR like
166      * commands
167      */
168     public boolean deleteOnAbort = false;
169 
170     /**
171      * Max global memory limit: default is 4GB
172      */
173     public long maxGlobalMemory = 0x100000000L;
174 
175     /**
176      * General Configuration Object
177      */
178     private final HashMap<String, Object> properties = new HashMap<String, Object>();
179 
180     /**
181      * Simple constructor
182      *
183      * @param classtype
184      *            Owner
185      * @param businessHandler
186      *            class that will be used for BusinessHandler
187      * @param dataBusinessHandler
188      *            class that will be used for DataBusinessHandler
189      * @param fileParameter
190      *            the FileParameterInterface to used
191      */
192     public FtpConfiguration(Class<?> classtype,
193             Class<? extends BusinessHandler> businessHandler,
194             Class<? extends DataBusinessHandler> dataBusinessHandler,
195             FileParameterInterface fileParameter) {
196         fromClass = classtype;
197         this.dataBusinessHandler = dataBusinessHandler;
198         this.businessHandler = businessHandler;
199         internalConfiguration = new FtpInternalConfiguration(this);
200         this.fileParameter = fileParameter;
201     }
202 
203     /**
204      *
205      * @param key
206      * @return The String property associated to the key
207      * @throws FtpUnknownFieldException
208      */
209     public String getStringProperty(String key) throws FtpUnknownFieldException {
210         String s = (String) properties.get(key);
211         if (s == null) {
212             throw new FtpUnknownFieldException("Property has no value: " + key);
213         }
214         return s;
215     }
216 
217     /**
218      *
219      * @param key
220      * @return The Integer property associated to the key
221      * @throws FtpUnknownFieldException
222      */
223     public int getIntProperty(String key) throws FtpUnknownFieldException {
224         Integer i = (Integer) properties.get(key);
225         if (i == null) {
226             throw new FtpUnknownFieldException("Property has no value: " + key);
227         }
228         return i;
229     }
230 
231     /**
232      *
233      * @param key
234      * @return The File associated to the key
235      * @throws FtpUnknownFieldException
236      */
237     public File getFileProperty(String key) throws FtpUnknownFieldException {
238         File f = (File) properties.get(key);
239         if (f == null) {
240             throw new FtpUnknownFieldException("Property has no value: " + key);
241         }
242         return f;
243     }
244 
245     /**
246      *
247      * @param key
248      * @return The Object property associated to the key
249      * @throws FtpUnknownFieldException
250      */
251     public Object getProperty(String key) throws FtpUnknownFieldException {
252         Object o = properties.get(key);
253         if (o == null) {
254             throw new FtpUnknownFieldException("Property has no value: " + key);
255         }
256         return o;
257     }
258 
259     /**
260      *
261      * @return the TCP Port to listen in the Ftp Server
262      */
263     public int getServerPort() {
264         return SERVER_PORT;
265     }
266     /**
267     *
268     * @return the Address of the Ftp Server if any (may be null)
269     */
270    public String getServerAddress() {
271        return SERVER_ADDRESS;
272    }
273 
274     /**
275      *
276      * @return the limit in Write byte/s to apply globally to the Ftp Server
277      */
278     public long getServerGlobalWriteLimit() {
279         return serverGlobalWriteLimit;
280     }
281 
282     /**
283      *
284      * @return the limit in Write byte/s to apply for each session to the Ftp
285      *         Server
286      */
287     public long getServerChannelWriteLimit() {
288         return serverChannelWriteLimit;
289     }
290 
291     /**
292      *
293      * @return the limit in Read byte/s to apply globally to the Ftp Server
294      */
295     public long getServerGlobalReadLimit() {
296         return serverGlobalReadLimit;
297     }
298 
299     /**
300      *
301      * @return the limit in Read byte/s to apply for each session to the Ftp
302      *         Server
303      */
304     public long getServerChannelReadLimit() {
305         return serverChannelReadLimit;
306     }
307 
308     /**
309      * @return the delayLimit to apply between two check
310      */
311     public long getDelayLimit() {
312         return delayLimit;
313     }
314 
315     /**
316      * Check the password for Shutdown
317      *
318      * @param password
319      * @return True if the password is OK
320      */
321     public boolean checkPassword(String password) {
322         String serverpassword;
323         try {
324             serverpassword = getStringProperty(FTP_PASSWORD);
325         } catch (FtpUnknownFieldException e) {
326             return false;
327         }
328         return serverpassword.equals(password);
329     }
330 
331     /**
332      * Return the next available port for passive connections.
333      *
334      * @return the next available Port for Passive connections
335      */
336     public abstract int getNextRangePort();
337 
338     /**
339      *
340      * @return the Base Directory of this Ftp Server
341      */
342     public String getBaseDirectory() {
343         return BASE_DIRECTORY;
344     }
345 
346     /**
347      *
348      * @param key
349      * @param s
350      */
351     public void setStringProperty(String key, String s) {
352         properties.put(key, s);
353     }
354 
355     /**
356      *
357      * @param key
358      * @param i
359      */
360     public void setIntProperty(String key, int i) {
361         properties.put(key, Integer.valueOf(i));
362     }
363 
364     /**
365      *
366      * @param key
367      * @param f
368      */
369     public void setFileProperty(String key, File f) {
370         properties.put(key, f);
371     }
372 
373     /**
374      *
375      * @param key
376      * @param o
377      */
378     public void setProperty(String key, Object o) {
379         properties.put(key, o);
380     }
381 
382     /**
383      * @param port
384      *            the new port
385      */
386     public void setServerPort(int port) {
387         SERVER_PORT = port;
388     }
389 
390     /**
391      * @param address
392      *            the address to use while answering for address
393      */
394     public void setServerAddress(String address) {
395         SERVER_ADDRESS = address;
396     }
397     /**
398      * @param dir
399      *            the new base directory
400      */
401     public void setBaseDirectory(String dir) {
402         BASE_DIRECTORY = dir;
403     }
404 
405     /**
406      * @param password
407      *            the new password for shutdown
408      */
409     public void setPassword(String password) {
410         setStringProperty(FTP_PASSWORD, password);
411     }
412 
413     /**
414      * @return the dataBusinessHandler
415      */
416     public Class<? extends DataBusinessHandler> getDataBusinessHandler() {
417         return dataBusinessHandler;
418     }
419 
420     /**
421      * Init internal configuration
422      *
423      */
424     public void serverStartup() {
425         internalConfiguration.serverStartup();
426     }
427 
428     /**
429      * Reset the global monitor for bandwidth limitation and change future
430      * channel monitors with values divided by 10 (channel = global / 10)
431      *
432      * @param writeLimit
433      * @param readLimit
434      */
435     public void changeNetworkLimit(long writeLimit, long readLimit) {
436         long newWriteLimit = writeLimit > 1024? writeLimit
437                 : serverGlobalWriteLimit;
438         if (writeLimit <= 0) {
439             newWriteLimit = 0;
440         }
441         long newReadLimit = readLimit > 1024? readLimit : serverGlobalReadLimit;
442         if (readLimit <= 0) {
443             newReadLimit = 0;
444         }
445         internalConfiguration.getGlobalTrafficShapingHandler().configure(
446                 newWriteLimit, newReadLimit);
447         serverChannelReadLimit = newReadLimit / 10;
448         serverChannelWriteLimit = newWriteLimit / 10;
449     }
450 
451     /**
452      * Compute number of threads for both client and server from the real number
453      * of available processors (double + 1) if the value is less than 64
454      * threads.
455      *
456      */
457     public void computeNbThreads() {
458         int nb = Runtime.getRuntime().availableProcessors() * 2 + 1;
459         if (nb > 32) {
460             nb = Runtime.getRuntime().availableProcessors() + 1;
461         }
462         if (SERVER_THREAD < nb) {
463             SERVER_THREAD = nb;
464             CLIENT_THREAD = SERVER_THREAD*10;
465         }
466     }
467 
468     /**
469      *
470      * @return the lock on configuration
471      */
472     public Lock getLock() {
473         return lock;
474     }
475     /**
476      * In bind/unbind operation, lock
477      */
478     public void bindLock() {
479         lock.lock();
480     }
481     /**
482      * In bind/unbind operation, unlock
483      */
484     public void bindUnlock() {
485         lock.unlock();
486     }
487     /**
488      *
489      * @return the FtpInternalConfiguration
490      */
491     public FtpInternalConfiguration getFtpInternalConfiguration() {
492         return internalConfiguration;
493     }
494 
495     /**
496      * Add a session from a couple of addresses
497      *
498      * @param ipOnly
499      * @param fullIp
500      * @param session
501      */
502     public void setNewFtpSession(InetAddress ipOnly, InetSocketAddress fullIp,
503             FtpSession session) {
504         internalConfiguration.setNewFtpSession(ipOnly, fullIp, session);
505     }
506 
507     /**
508      * Return and remove the FtpSession
509      *
510      * @param channel
511      * @param active
512      * @return the FtpSession if it exists associated to this channel
513      */
514     public FtpSession getFtpSession(Channel channel, boolean active) {
515         return internalConfiguration.getFtpSession(channel, active);
516     }
517 
518     /**
519      * Remove the FtpSession
520      *
521      * @param ipOnly
522      * @param fullIp
523      */
524     public void delFtpSession(InetAddress ipOnly, InetSocketAddress fullIp) {
525         internalConfiguration.delFtpSession(ipOnly, fullIp);
526     }
527 
528     /**
529      * Test if the couple of addresses is already in the context
530      *
531      * @param ipOnly
532      * @param fullIp
533      * @return True if the couple is present
534      */
535     public boolean hasFtpSession(InetAddress ipOnly, InetSocketAddress fullIp) {
536         return internalConfiguration.hasFtpSession(ipOnly, fullIp);
537     }
538 
539     /**
540      * @return the fileParameter
541      */
542     public FileParameterInterface getFileParameter() {
543         return fileParameter;
544     }
545 
546     public String getUniqueExtension() {
547         // Can be overridden if necessary
548         return ".stou";
549     }
550     /**
551      * To use if any external resources are to be released when shutting down
552      */
553     public void releaseResources() {
554         internalConfiguration.releaseResources();
555     }
556     /**
557      * Shutdown process is on going
558      */
559     public abstract void inShutdownProcess();
560 }