KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > core > ControllerFactory


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Emmanuel Cecchet.
22  * Contributor(s): Mathieu Peltier, Nicolas Modrzyk, Duncan Smith.
23  */

24
25 package org.objectweb.cjdbc.controller.core;
26
27 import java.io.File JavaDoc;
28 import java.io.FileReader JavaDoc;
29 import java.net.InetAddress JavaDoc;
30 import java.net.URL JavaDoc;
31 import java.net.URLDecoder JavaDoc;
32 import java.net.UnknownHostException JavaDoc;
33 import java.util.Hashtable JavaDoc;
34
35 import org.apache.commons.cli.CommandLine;
36 import org.apache.commons.cli.CommandLineParser;
37 import org.apache.commons.cli.GnuParser;
38 import org.apache.commons.cli.HelpFormatter;
39 import org.apache.commons.cli.Option;
40 import org.apache.commons.cli.OptionGroup;
41 import org.apache.commons.cli.Options;
42 import org.apache.commons.cli.ParseException;
43 import org.objectweb.cjdbc.common.i18n.Translate;
44 import org.objectweb.cjdbc.common.jmx.JmxConstants;
45 import org.objectweb.cjdbc.common.jmx.JmxException;
46 import org.objectweb.cjdbc.common.log.Trace;
47 import org.objectweb.cjdbc.common.net.SSLConfiguration;
48 import org.objectweb.cjdbc.controller.authentication.PasswordAuthenticator;
49 import org.objectweb.cjdbc.controller.core.security.ControllerSecurityManager;
50 import org.objectweb.cjdbc.controller.jmx.HttpAdaptor;
51 import org.objectweb.cjdbc.controller.jmx.MBeanServerManager;
52 import org.objectweb.cjdbc.controller.jmx.RmiConnector;
53 import org.objectweb.cjdbc.controller.monitoring.datacollector.DataCollector;
54 import org.objectweb.cjdbc.controller.xml.ControllerParser;
55
56 /**
57  * The <code>ControllerFactory</code> class prepares a <code>Controller</code>
58  * object by configurating ports, security, loaded databases.
59  *
60  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
61  * @author <a HREF="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
62  * @author <a HREF="mailto:duncan@mightybot.com">Duncan Smith </a>
63  * @version 1.0
64  */

65 public class ControllerFactory extends Hashtable JavaDoc
66 {
67   private static final long serialVersionUID = -3766086549425915891L;
68
69   /**
70    * The different fields that can be set on the command line.
71    */

72   /** The Rmi port value */
73   public static final String JavaDoc RMI_PORT = "rmiPort";
74
75   /** The jmx port value */
76   public static final String JavaDoc JMX_PORT = "jmxPort";
77
78   /** The jmx enable value */
79   public static final String JavaDoc JMX_ENABLE = "jmxEnable";
80
81   /** The xml file possibly used to configure controller */
82   public static final String JavaDoc XML_FILE = "xmlFile";
83
84   /** The NIC IP address to bind the controller to */
85   public static final String JavaDoc CONTROLLER_IP = "controllerIP";
86
87   /** The controller port number */
88   public static final String JavaDoc CONTROLLER_PORT = "controllerPort";
89
90   /** The controller backlog size */
91   public static final String JavaDoc CONTROLLER_BACKLOG = "controllerBackLogSize";
92
93   /** Add driver enable */
94   public static final String JavaDoc ADD_DRIVER_ENABLE = "addDriverEnable";
95
96   /** Logger instance. */
97   static Trace logger = Trace
98                                                     .getLogger(Controller.class
99                                                         .getName());
100
101   private Controller controller = null;
102
103   /**
104    * Configure the controller with parameters
105    *
106    * @param args parameters from the command line
107    */

108   public ControllerFactory(String JavaDoc[] args)
109   {
110     System.setProperty("org.xml.sax.driver",
111         "org.apache.crimson.parser.XMLReaderImpl");
112
113     URL JavaDoc defaultControllerXmlFile = ControllerFactory.class.getResource("/"
114         + ControllerConstants.DEFAULT_CONFIG_FILE);
115     if (defaultControllerXmlFile == null)
116       logger
117           .warn("Unable to find default controller.xml configuration file in CLASSPATH.");
118     else
119     {
120       String JavaDoc file = URLDecoder.decode(defaultControllerXmlFile.getFile());
121       this.put(XML_FILE, file);
122     }
123     this.put(CONTROLLER_IP, ControllerConstants.DEFAULT_IP);
124     this.put(CONTROLLER_PORT, "" + ControllerConstants.DEFAULT_PORT);
125     this.put(CONTROLLER_BACKLOG, "" + ControllerConstants.DEFAULT_BACKLOG_SIZE);
126
127     // Create options object
128
Options options = createOptions();
129
130     // Parse command line
131
CommandLineParser parser = new GnuParser();
132     CommandLine commandLine = null;
133     try
134     {
135       commandLine = parser.parse(options, args);
136     }
137     catch (ParseException e)
138     {
139       logger.fatal(Translate.get("controller.configure.commandline.error", e),
140           e);
141       printUsage(options);
142       Runtime.getRuntime().exit(1);
143     }
144
145     // Non-recognized options
146
int n = commandLine.getArgs().length;
147     for (int i = 0; i < n; i++)
148     {
149       logger.fatal(Translate.get("controller.configure.unknown.option",
150           commandLine.getArgs()[i]));
151       printUsage(options);
152       Runtime.getRuntime().exit(1);
153     }
154     // Handle --help option
155
if (commandLine.hasOption('h'))
156     {
157       if (commandLine.getOptions().length > 1)
158         logger.fatal(Translate.get("controller.configure.commandline.error"));
159
160       printUsage(options);
161       Runtime.getRuntime().exit(1);
162     }
163
164     // Handle --version option
165
if (commandLine.hasOption('v'))
166     {
167       if (commandLine.getOptions().length > 1)
168       {
169         logger.fatal(Translate.get("controller.configure.commandline.error"));
170         printUsage(options);
171       }
172       else
173         logger.info(Controller.getVersion());
174       Runtime.getRuntime().exit(1);
175     }
176
177     // Handle -rmi option
178
if (commandLine.hasOption('r'))
179     {
180       String JavaDoc s = commandLine.getOptionValue('r');
181       if (s != null)
182       {
183         this.put(JMX_ENABLE, "true");
184         this.put(RMI_PORT, s);
185         this.put(JmxConstants.ADAPTOR_TYPE_RMI, s);
186       }
187     }
188
189     // Handle -jmx option
190
if (commandLine.hasOption('j'))
191     {
192       String JavaDoc s = commandLine.getOptionValue('j');
193       if (s != null)
194       {
195         this.put(JMX_ENABLE, "true");
196         this.put(JMX_PORT, s);
197         this.put(JmxConstants.ADAPTOR_TYPE_HTTP, s);
198       }
199     }
200
201     // Handle --ip option
202
if (commandLine.hasOption('i'))
203     {
204       String JavaDoc ipAddress = commandLine.getOptionValue('i');
205       if (ipAddress != null)
206         this.put(CONTROLLER_IP, ipAddress);
207     }
208
209     // Handle --port option
210
if (commandLine.hasOption('p'))
211     {
212       String JavaDoc port = commandLine.getOptionValue('p');
213       if (port != null)
214         this.put(CONTROLLER_PORT, port);
215     }
216
217     // Handle -f option
218
if (commandLine.hasOption('f'))
219     {
220       // If a config file is specified we ignore the default file.
221
this.remove(XML_FILE);
222       String JavaDoc filePath = commandLine.getOptionValue('f');
223       File JavaDoc f = new File JavaDoc(filePath);
224       logger.debug(f.getAbsolutePath());
225       if (f.exists() == false || f.isFile() == false)
226         logger
227             .warn(Translate.get("controller.configure.optional.file.invalid"));
228       else
229         this.put(XML_FILE, filePath);
230     }
231   }
232
233   /**
234    * This method is going to call a <code>ControllerParser</code> object to
235    * configure controller while parsing file. This method will call <method>
236    * setUpRmi() </method> and <method>setUpJmx() </method> as well as <method>
237    * setUpVirtualDatabases </method> while parsing.
238    *
239    * @param filename path to the xml file to parse from
240    * @throws Exception if configuration fails
241    */

242   public void setUpByXml(String JavaDoc filename) throws Exception JavaDoc
243   {
244     logger.info(Translate.get("controller.configure.loading.file", filename));
245     FileReader JavaDoc fileReader = null;
246     try
247     {
248       fileReader = new FileReader JavaDoc(filename);
249       ControllerParser cparser = new ControllerParser(this);
250       cparser.readXML(fileReader, true);
251       fileReader.close();
252     }
253     catch (Exception JavaDoc e)
254     {
255
256       logger.warn(Translate.get("controller.configure.xml.file.error", e), e);
257       throw e;
258     }
259     finally
260     {
261       if (fileReader != null)
262         fileReader.close();
263     }
264   }
265
266   /**
267    * Test if there is a file to take configuration from, if so call <method>
268    * setUpByXml() </method>
269    *
270    * @return an instanciated and configured object of class
271    * <code>Controller</code>
272    * @throws Exception if configuration fails
273    */

274   private Controller setup() throws Exception JavaDoc
275   {
276     String JavaDoc xml = (String JavaDoc) this.get(XML_FILE);
277
278     int portNumber = Integer.parseInt((String JavaDoc) this.get(CONTROLLER_PORT));
279     int backlog = Integer.parseInt((String JavaDoc) this.get(CONTROLLER_BACKLOG));
280     String JavaDoc ipAddress = (String JavaDoc) this.get(CONTROLLER_IP);
281
282     controller = new Controller(ipAddress, portNumber, backlog);
283     controller.setConfiguration(this);
284
285     if (xml != null)
286     {
287       try
288       {
289         setUpByXml(xml);
290       }
291       catch (Exception JavaDoc e)
292       {
293         logger.error(Translate.get(
294             "controller.configure.load.file.failed.minimum.configuration",
295             new String JavaDoc[]{xml, e.getMessage()}), e);
296       }
297     }
298     else
299       setUpJmx();
300
301     return this.controller;
302   }
303
304   /**
305    * Retrieve the controller associated with this <code>ControllerFactory</code>
306    * instance.
307    *
308    * @return <code>Controller</code> object. Can be null if this method is
309    * called before setup
310    * @throws Exception if an error occurs
311    */

312   public Controller getController() throws Exception JavaDoc
313   {
314     if (controller == null)
315       setup();
316     return this.controller;
317   }
318
319   /**
320    * Start up the jmx services if enabled.
321    *
322    * @throws JmxException an exception
323    */

324   public void setUpJmx() throws JmxException
325   {
326     boolean jmxEnable = new Boolean JavaDoc((String JavaDoc) get(JMX_ENABLE)).booleanValue();
327     if (jmxEnable == false)
328     {
329       MBeanServerManager.setJmxEnabled(false);
330       logger.info(Translate.get("jmx.configure.disabled"));
331     }
332     else
333     {
334       MBeanServerManager.setJmxEnabled(true);
335       logger.info(Translate.get("jmx.configure.enabled"));
336       // Create and start the JMX agent
337
try
338       {
339         new DataCollector(controller);
340         String JavaDoc hostIP = controller.getIPAddress();
341
342         logger.info(Translate.get("controller.configure.start.jmx", hostIP));
343
344         if (this.containsKey(JmxConstants.ADAPTOR_TYPE_HTTP))
345         {
346           int port = Integer.parseInt((String JavaDoc) this
347               .get(JmxConstants.ADAPTOR_TYPE_HTTP));
348           HttpAdaptor http = new HttpAdaptor(hostIP, port, null);
349           http.start();
350         }
351         if (this.containsKey(JmxConstants.ADAPTOR_TYPE_RMI))
352         {
353           SSLConfiguration ssl = null;
354           PasswordAuthenticator authenticator = null;
355           int port = Integer.parseInt((String JavaDoc) this
356               .get(JmxConstants.ADAPTOR_TYPE_RMI));
357           if (this.containsKey(JmxConstants.CONNECTOR_AUTH_USERNAME))
358           {
359             String JavaDoc username = (String JavaDoc) this
360                 .get(JmxConstants.CONNECTOR_AUTH_USERNAME);
361             String JavaDoc password = (String JavaDoc) this
362                 .get(JmxConstants.CONNECTOR_AUTH_PASSWORD);
363             authenticator = new PasswordAuthenticator(username, password);
364           }
365           if (this.containsKey(JmxConstants.CONNECTOR_RMI_SSL))
366           {
367             ssl = (SSLConfiguration) this.get(JmxConstants.CONNECTOR_RMI_SSL);
368           }
369           RmiConnector rmi = new RmiConnector(controller.getControllerName(),
370               hostIP, port, authenticator, ssl);
371           rmi.start();
372         }
373         logger.debug(Translate.get("controller.configure.jmx.started"));
374       }
375       catch (Exception JavaDoc e)
376       {
377         logger
378             .error(Translate.get("controller.configure.jmx.fail.start", e), e);
379       }
380     }
381     controller.setJmxEnable(jmxEnable);
382   }
383
384   /**
385    * Set up security settings if needed here.
386    *
387    * @param security to enforce
388    */

389   public void setUpSecurity(ControllerSecurityManager security)
390   {
391     controller.setSecurity(security);
392   }
393
394   /**
395    * Will load the <code>VirtualDatabase</code> configuration into the
396    * controller.
397    *
398    * @param filePath the path to xml definition of the virtual database
399    * @param virtualName the name of the virtualDatabase to load
400    * @param autoLoad specified if backend should be enabled.
401    * @param checkPoint the check point to load the database from.
402    */

403   public void setUpVirtualDatabase(String JavaDoc filePath, String JavaDoc virtualName,
404       int autoLoad, String JavaDoc checkPoint)
405   {
406     try
407     {
408       controller.loadXmlConfiguration(filePath, virtualName, autoLoad,
409           checkPoint);
410       if (logger.isDebugEnabled())
411         logger.debug(Translate.get("controller.configure.file.autoload",
412             new String JavaDoc[]{filePath, "" + autoLoad}));
413
414     }
415     catch (Exception JavaDoc e)
416     {
417       logger.error(Translate.get("controller.configure.load.file.failed",
418           new String JavaDoc[]{filePath, e.getMessage()}), e);
419     }
420   }
421
422   /**
423    * Displays usage message.
424    *
425    * @param options available command line options
426    */

427   private static void printUsage(Options options)
428   {
429     String JavaDoc header = Translate.get("controller.commandline.header");
430     header += System.getProperty("line.separator");
431     header += Translate.get("controller.commandline.options");
432     String JavaDoc footer = Translate.get("controller.commandline.footer");
433
434     (new HelpFormatter()).printHelp(80, "controller(.sh|.bat) [options]",
435         header, options, footer);
436   }
437
438   /**
439    * Creates <code>Options</code> object that contains all available options
440    * that can be used launching C-JDBC controller.
441    *
442    * @return an <code>Options</code> instance
443    */

444   private static Options createOptions()
445   {
446     Options options = new Options();
447     OptionGroup group = new OptionGroup();
448
449     // help and verbose options
450
group.addOption(new Option("h", "help", false, Translate
451         .get("controller.commandline.option.help")));
452     group.addOption(new Option("v", "version", false, Translate
453         .get("controller.commandline.option.version")));
454     options.addOptionGroup(group);
455
456     // RMI port option
457
options.addOption(new Option("r", "rmi", true, Translate.get(
458         "controller.commandline.option.rmi", ""
459             + JmxConstants.DEFAULT_JMX_RMI_PORT)));
460     // JMX port option
461
options.addOption(new Option("j", "jmx", true, Translate.get(
462         "controller.commandline.option.jmx", ""
463             + JmxConstants.DEFAULT_JMX_HTTP_PORT)));
464
465     // IP option
466
String JavaDoc defaultIp = "127.0.0.1";
467     try
468     {
469       defaultIp = InetAddress.getLocalHost().getHostAddress();
470     }
471     catch (UnknownHostException JavaDoc e)
472     {
473
474     }
475     options.addOption(new Option("i", "ip", true, Translate.get(
476         "controller.commandline.option.ip", "" + defaultIp)));
477
478     // Port options
479
options.addOption(new Option("p", "port", true, Translate.get(
480         "controller.commandline.option.port", ""
481             + ControllerConstants.DEFAULT_PORT)));
482
483     // configuration file option
484
options.addOption(new Option("f", "file", true, Translate
485         .get("controller.commandline.option.file")));
486
487     return options;
488   }
489
490 }
Popular Tags