KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > controller > core > ControllerConfiguration


1 /**
2  * Sequoia: Database clustering technology.
3  * Copyright (C) 2002-2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Copyright (C) 2006 Continuent, Inc.
6  * Contact: sequoia@continuent.org
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  * Initial developer(s): Emmanuel Cecchet.
21  * Contributor(s): Mathieu Peltier, Nicolas Modrzyk, Duncan Smith.
22  */

23
24 package org.continuent.sequoia.controller.core;
25
26 import java.io.File JavaDoc;
27 import java.io.FileReader JavaDoc;
28 import java.net.InetAddress JavaDoc;
29 import java.net.URL JavaDoc;
30 import java.net.URLDecoder JavaDoc;
31 import java.net.UnknownHostException JavaDoc;
32 import java.util.Hashtable JavaDoc;
33
34 import javax.management.ObjectName JavaDoc;
35
36 import org.apache.commons.cli.CommandLine;
37 import org.apache.commons.cli.CommandLineParser;
38 import org.apache.commons.cli.GnuParser;
39 import org.apache.commons.cli.HelpFormatter;
40 import org.apache.commons.cli.Option;
41 import org.apache.commons.cli.OptionGroup;
42 import org.apache.commons.cli.Options;
43 import org.apache.commons.cli.ParseException;
44 import org.continuent.sequoia.common.authentication.PasswordAuthenticator;
45 import org.continuent.sequoia.common.i18n.Translate;
46 import org.continuent.sequoia.common.jmx.JmxConstants;
47 import org.continuent.sequoia.common.log.Trace;
48 import org.continuent.sequoia.common.net.SSLConfiguration;
49 import org.continuent.sequoia.common.xml.ControllerXmlTags;
50 import org.continuent.sequoia.controller.jmx.MBeanServerManager;
51 import org.continuent.sequoia.controller.jmx.RmiConnector;
52 import org.continuent.sequoia.controller.monitoring.datacollector.DataCollector;
53 import org.continuent.sequoia.controller.xml.ControllerParser;
54
55 /**
56  * The <code>ControllerConfiguration</code> class prepares a
57  * <code>Controller</code> object by configurating ports, security, loaded
58  * 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 ControllerConfiguration 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
73   /** The xml file possibly used to configure controller */
74   public static final String JavaDoc XML_FILE = "xmlFile";
75
76   /** Add driver enable */
77   public static final String JavaDoc ADD_DRIVER_ENABLE = "addDriverEnable";
78
79   /** Logger instance. */
80   static Trace logger = Trace
81                                                    .getLogger(Controller.class
82                                                        .getName());
83   static Trace endUserLogger = Trace
84                                                    .getLogger("org.continuent.sequoia.enduser");
85
86   private Controller controller = null;
87
88   /**
89    * Configure the controller with parameters
90    *
91    * @param args parameters from the command line
92    */

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

224   public void setUpByXml(String JavaDoc filename) throws Exception JavaDoc
225   {
226     logger.info(Translate.get("controller.configure.loading.file", filename));
227     FileReader JavaDoc fileReader = null;
228     try
229     {
230       fileReader = new FileReader JavaDoc(filename);
231       ControllerParser cparser = new ControllerParser(this);
232       cparser.readXML(fileReader, true);
233       fileReader.close();
234     }
235     catch (Exception JavaDoc e)
236     {
237       logger.warn(Translate.get("controller.configure.xml.file.error", e), e);
238       throw e;
239     }
240     finally
241     {
242       if (fileReader != null)
243         fileReader.close();
244     }
245   }
246
247   /**
248    * Test if there is a file to take configuration from, if so call <method>
249    * setUpByXml() </method>
250    *
251    * @return an instanciated and configured object of class
252    * <code>Controller</code>
253    * @throws Exception if configuration fails
254    */

255   private Controller setup() throws Exception JavaDoc
256   {
257     String JavaDoc xml = (String JavaDoc) this.get(XML_FILE);
258
259     String JavaDoc controllerName = (String JavaDoc) this
260         .get(ControllerXmlTags.ATT_CONTROLLER_NAME);
261     /**
262      * @see org.continuent.sequoia.controller.xml.ControllerParser#configureController(Attributes)
263      * for how CONTROLLER_IP is set
264      */

265     String JavaDoc ipAddress = (String JavaDoc) this.get(ControllerXmlTags.ATT_CONTROLLER_IP);
266     int portNumber = Integer.parseInt((String JavaDoc) this
267         .get(ControllerXmlTags.ATT_CONTROLLER_PORT));
268     int backlog = Integer.parseInt((String JavaDoc) this
269         .get(ControllerXmlTags.ATT_BACKLOG_SIZE));
270     // Warning! Next value can be null, don't reverse the test
271
boolean allowDriver = "true"
272         .equalsIgnoreCase((String JavaDoc) get(ControllerXmlTags.ATT_ALLOW_ADDITIONAL_DRIVER));
273
274     controller = new Controller(controllerName, ipAddress, portNumber, backlog,
275         allowDriver);
276     controller.setConfiguration(this);
277     org.continuent.sequoia.controller.management.Controller managedController = new org.continuent.sequoia.controller.management.Controller(
278         controller);
279     ObjectName JavaDoc name = JmxConstants.getControllerObjectName();
280     MBeanServerManager.registerMBean(managedController, name);
281     controller.setNotificationBroadcasterSupport(managedController
282         .getBroadcaster());
283
284     if (xml != null)
285     {
286       try
287       {
288         setUpByXml(xml);
289       }
290       catch (Exception JavaDoc e)
291       {
292         logger.error(Translate.get(
293             "controller.configure.load.file.failed.minimum.configuration",
294             new String JavaDoc[]{xml, e.getMessage()}), e);
295       }
296     }
297     else
298       setUpJmx(null);
299
300     return this.controller;
301   }
302
303   /**
304    * Retrieve the controller associated with this
305    * <code>ControllerConfiguration</code> instance.
306    *
307    * @return <code>Controller</code> object. Can be null if this method is
308    * called before setup
309    * @throws Exception if an error occurs
310    */

311   public Controller getController() throws Exception JavaDoc
312   {
313     if (controller == null)
314       setup();
315     return this.controller;
316   }
317
318   /**
319    * Start up the jmx services if enabled.
320    *
321    * @param ssl SSL configuration or null
322    */

323   public void setUpJmx(SSLConfiguration ssl)
324   {
325     logger.info(Translate.get("jmx.configure.enabled"));
326     // Create and start the JMX agent
327
try
328     {
329       new DataCollector(controller);
330       String JavaDoc hostIP = (String JavaDoc) get(ControllerXmlTags.ATT_JMX_ADAPTOR_IP);
331       if (hostIP == null)
332         hostIP = controller.getIPAddress();
333       int port = Integer.parseInt((String JavaDoc) this
334           .get(ControllerXmlTags.ATT_JMX_ADAPTOR_PORT));
335
336       logger.info(Translate.get("controller.configure.start.jmx", hostIP + ":"
337           + port));
338
339       PasswordAuthenticator authenticator = null;
340       if (this.containsKey(ControllerXmlTags.ATT_JMX_CONNECTOR_USERNAME))
341       {
342         String JavaDoc username = (String JavaDoc) get(ControllerXmlTags.ATT_JMX_CONNECTOR_USERNAME);
343         String JavaDoc password = (String JavaDoc) get(ControllerXmlTags.ATT_JMX_CONNECTOR_PASSWORD);
344         authenticator = new PasswordAuthenticator(username, password);
345       }
346       RmiConnector rmi = new RmiConnector(controller.getControllerName(),
347           hostIP, port, authenticator, ssl);
348       rmi.start();
349       controller.setRmiConnector(rmi);
350
351       logger.debug(Translate.get("controller.configure.jmx.started"));
352     }
353     catch (Exception JavaDoc e)
354     {
355       logger.error(Translate.get("controller.configure.jmx.fail.start", e), e);
356     }
357   }
358
359   /**
360    * Will load the <code>VirtualDatabase</code> configuration into the
361    * controller.
362    *
363    * @param filePath the path to xml definition of the virtual database
364    * @param virtualName the name of the virtualDatabase to load
365    * @param autoLoad specified if backend should be enabled.
366    */

367   public void setUpVirtualDatabase(String JavaDoc filePath, String JavaDoc virtualName,
368       int autoLoad)
369   {
370     try
371     {
372       controller.loadXmlConfiguration(filePath, virtualName, autoLoad);
373       if (logger.isDebugEnabled())
374         logger.debug(Translate.get("controller.configure.file.autoload",
375             new String JavaDoc[]{filePath, "" + autoLoad}));
376
377     }
378     catch (Exception JavaDoc e)
379     {
380       logger.error(Translate.get("controller.configure.load.file.failed",
381           new String JavaDoc[]{filePath, e.getMessage()}), e);
382     }
383   }
384
385   /**
386    * Displays usage message.
387    *
388    * @param options available command line options
389    */

390   private static void printUsage(Options options)
391   {
392     String JavaDoc header = Translate.get("controller.commandline.header", ControllerConstants.PRODUCT_NAME);
393     header += System.getProperty("line.separator");
394     header += Translate.get("controller.commandline.options");
395     String JavaDoc footer = Translate.get("controller.commandline.footer");
396
397     (new HelpFormatter()).printHelp(80, "controller(.sh|.bat) [options]",
398         header, options, footer);
399   }
400
401   /**
402    * Creates <code>Options</code> object that contains all available options
403    * that can be used launching Sequoia controller.
404    *
405    * @return an <code>Options</code> instance
406    */

407   private static Options createOptions()
408   {
409     Options options = new Options();
410     OptionGroup group = new OptionGroup();
411
412     // help and verbose options
413
group.addOption(new Option("h", "help", false, Translate
414         .get("controller.commandline.option.help")));
415     group.addOption(new Option("v", "version", false, Translate
416         .get("controller.commandline.option.version")));
417     options.addOptionGroup(group);
418
419     // JMX port option
420
options.addOption(new Option("j", "jmx", true, Translate.get(
421         "controller.commandline.option.jmx", ""
422             + JmxConstants.DEFAULT_JMX_RMI_PORT)));
423
424     // IP option
425
String JavaDoc defaultIp = "127.0.0.1";
426     try
427     {
428       defaultIp = InetAddress.getLocalHost().getHostAddress();
429     }
430     catch (UnknownHostException JavaDoc e)
431     {
432
433     }
434     options.addOption(new Option("i", "ip", true, Translate.get(
435         "controller.commandline.option.ip", "" + defaultIp)));
436
437     // Port options
438
options.addOption(new Option("p", "port", true, Translate.get(
439         "controller.commandline.option.port", ""
440             + ControllerConstants.DEFAULT_PORT)));
441
442     // configuration file option
443
options.addOption(new Option("f", "file", true, Translate
444         .get("controller.commandline.option.file")));
445
446     return options;
447   }
448
449 }
Popular Tags