00001
00025 package org.objectweb.cjdbc.controller.core;
00026
00027
import java.io.BufferedOutputStream;
00028
import java.io.BufferedReader;
00029
import java.io.BufferedWriter;
00030
import java.io.DataOutputStream;
00031
import java.io.File;
00032
import java.io.FileInputStream;
00033
import java.io.FileNotFoundException;
00034
import java.io.FileOutputStream;
00035
import java.io.FileReader;
00036
import java.io.FileWriter;
00037
import java.io.FilenameFilter;
00038
import java.io.IOException;
00039
import java.io.InputStream;
00040
import java.io.StringReader;
00041
import java.io.StringWriter;
00042
import java.net.URL;
00043
import java.text.SimpleDateFormat;
00044
import java.util.ArrayList;
00045
import java.util.Date;
00046
import java.util.Enumeration;
00047
import java.util.Hashtable;
00048
import java.util.Iterator;
00049
import java.util.Locale;
00050
import java.util.ResourceBundle;
00051
import java.util.zip.ZipEntry;
00052
import java.util.zip.ZipFile;
00053
00054
import javax.management.NotCompliantMBeanException;
00055
import javax.management.ObjectName;
00056
import javax.xml.transform.Transformer;
00057
import javax.xml.transform.TransformerFactory;
00058
import javax.xml.transform.stream.StreamResult;
00059
import javax.xml.transform.stream.StreamSource;
00060
00061
import org.objectweb.cjdbc.common.exceptions.ControllerException;
00062
import org.objectweb.cjdbc.common.exceptions.ExceptionTypes;
00063
import org.objectweb.cjdbc.common.exceptions.VirtualDatabaseException;
00064
import org.objectweb.cjdbc.common.i18n.Translate;
00065
import org.objectweb.cjdbc.common.jmx.JmxConstants;
00066
import org.objectweb.cjdbc.common.jmx.JmxException;
00067
import org.objectweb.cjdbc.common.jmx.mbeans.ControllerMBean;
00068
import org.objectweb.cjdbc.common.jmx.notifications.CjdbcNotificationList;
00069
import org.objectweb.cjdbc.common.log.LogManager;
00070
import org.objectweb.cjdbc.common.log.Trace;
00071
import org.objectweb.cjdbc.common.util.Constants;
00072
import org.objectweb.cjdbc.common.util.ZipMe;
00073
import org.objectweb.cjdbc.common.xml.ControllerXmlTags;
00074
import org.objectweb.cjdbc.common.xml.XmlComponent;
00075
import org.objectweb.cjdbc.controller.core.security.ControllerSecurityManager;
00076
import org.objectweb.cjdbc.controller.core.shutdown.ControllerShutdownThread;
00077
import org.objectweb.cjdbc.controller.jmx.AbstractStandardMBean;
00078
import org.objectweb.cjdbc.controller.jmx.MBeanServerManager;
00079
import org.objectweb.cjdbc.controller.jmx.RmiConnector;
00080
import org.objectweb.cjdbc.controller.virtualdatabase.VirtualDatabase;
00081
import org.objectweb.cjdbc.controller.xml.DatabasesParser;
00082
00093 public class Controller extends AbstractStandardMBean
00094 implements
00095 ControllerMBean,
00096 XmlComponent
00097 {
00098
00100 private int portNumber;
00101 private int backlogSize;
00102
00108 private String
ipAddress;
00109
00111 private ControllerServerThread connectionThread;
00112
00114 static Trace
logger = Trace
00115 .getLogger(
"org.objectweb.cjdbc.controller.core.Controller");
00116
00118 private Hashtable
virtualDatabases;
00119
00121 private Hashtable
configuration;
00122
00124 private ControllerSecurityManager
security;
00125
00127 private ReportManager report;
00128
00130 private TransformerFactory
tFactory;
00131 private Transformer
infoTransformer;
00132 private boolean isShuttingDown;
00133
00134
00135
00146 public Controller(String ipAddress,
int port,
int backlog)
00147
throws NotCompliantMBeanException,
JmxException
00148 {
00149 super(ControllerMBean.class);
00150
virtualDatabases =
new Hashtable();
00151
this.ipAddress =
ipAddress;
00152
this.portNumber = port;
00153
this.backlogSize = backlog;
00154 ObjectName name =
JmxConstants.getControllerObjectName();
00155
MBeanServerManager.registerMBean(
this, name);
00156 }
00157
00161 public String
getAssociatedString()
00162 {
00163
return "controller";
00164 }
00165
00166
00167
00173 public void addVirtualDatabases(String xml, String virtualName,
00174
int autoLoad, String checkPoint)
throws ControllerException
00175 {
00176
if (
logger.isDebugEnabled())
00177
logger
00178 .debug(
Translate.get(
"controller.add.virtualdatabase", virtualName));
00179
if (virtualName != null &&
this.hasVirtualDatabase(virtualName))
00180 {
00181
throw new ControllerException(
Translate
00182 .get(
"controller.add.virtualdatabase.already.used"));
00183 }
00184
try
00185 {
00186
DatabasesParser parser =
new DatabasesParser(
this, virtualName,
00187 autoLoad, checkPoint);
00188 parser.
readXML(xml,
true);
00189 }
00190
catch (Exception e)
00191 {
00192 String msg =
Translate.get(
"controller.add.virtualdatabase.failed", e);
00193
logger.warn(msg, e);
00194
throw new ControllerException(msg);
00195 }
00196 }
00197
00203 public void addVirtualDatabases(String xml)
throws ControllerException
00204 {
00205
if (
logger.isDebugEnabled())
00206 {
00207
logger.debug(
Translate.get(
"controller.loading.virtualdatabase"));
00208 }
00209
this.addVirtualDatabases(xml, null,
00210
ControllerConstants.AUTO_ENABLE_BACKEND,
00211
ControllerConstants.DATABASE_DEFAULT_CHECKPOINT);
00212 }
00213
00220 public void addVirtualDatabase(
VirtualDatabase vdb)
00221
throws ControllerException
00222 {
00223
this.addVirtualDatabase(vdb,
ControllerConstants.AUTO_ENABLE_BACKEND,
00224
ControllerConstants.DATABASE_DEFAULT_CHECKPOINT);
00225 }
00226
00237 public synchronized void addVirtualDatabase(
VirtualDatabase vdb,
00238
int autoLoad, String checkPoint)
throws ControllerException
00239 {
00240
00241
if (
hasVirtualDatabase(vdb.getDatabaseName()))
00242 {
00243 String msg =
Translate.get(
"controller.database.already.exists", vdb
00244 .getDatabaseName());
00245
logger.warn(msg);
00246
throw new ControllerException(msg);
00247 }
00248
else
00249 {
00250
virtualDatabases.put(vdb.getDatabaseName(), vdb);
00251
00252
00253
if (
MBeanServerManager.isJmxEnabled())
00254 {
00255 Hashtable databases =
new Hashtable();
00256
try
00257 {
00258 databases.put(
"backends", vdb.getAllBackendNames());
00259 }
00260
catch (
VirtualDatabaseException e)
00261 {
00262
00263 }
00264
RmiConnector
00265 .broadcastNotification(
this,
00266
CjdbcNotificationList.CONTROLLER_VIRTUALDATABASE_ADDED,
00267
CjdbcNotificationList.NOTIFICATION_LEVEL_INFO,
Translate.get(
00268
"notification.virtualdatabase.added", vdb.getName()),
00269 databases);
00270 }
00271 }
00272
00273
00274
try
00275 {
00276
switch (autoLoad)
00277 {
00278
case ControllerConstants.AUTO_ENABLE_TRUE :
00279 vdb.enableAllBackend(checkPoint);
00280
break;
00281
case ControllerConstants.AUTO_ENABLE_FALSE :
00282
break;
00283
case ControllerConstants.AUTO_ENABLE_RESTORE :
00284 vdb.enableAllBackendsFromRecovery(checkPoint);
00285
break;
00286
default :
00287
break;
00288 }
00289 }
00290
catch (
VirtualDatabaseException e)
00291 {
00292
throw new ControllerException(e);
00293 }
00294
00295
logger.info(
Translate.get(
"controller.add.virtualdatabase", vdb
00296 .getDatabaseName()));
00297
if (
logger.isDebugEnabled())
00298
logger.debug(
Translate.get(
"controller.database.enabled", autoLoad));
00299 }
00300
00304 public String
viewInfo() throws Exception
00305 {
00306
return prettyXml(
getXmlController());
00307 }
00308
00312 public String
viewConfiguration() throws Exception
00313 {
00314
return applyXsl(
getXmlController(),
"c-jdbc-controller.xsl");
00315 }
00316
00320 public String
viewDatabases() throws Exception
00321 {
00322
return applyXsl(
getXmlVirtualDatabases(),
"c-jdbc.xsl");
00323 }
00324
00328 public String
viewDatabasesXml() throws Exception
00329 {
00330
00331
00332
return prettyXml(
getXmlVirtualDatabases());
00333 }
00334
00341 private String
prettyXml(String xml)
00342 {
00343
try
00344 {
00345
return applyXsl(xml,
"c-jdbc-pretty.xsl");
00346 }
00347
catch (RuntimeException e)
00348 {
00349
logger.error(e.getMessage(), e);
00350
return e.getMessage();
00351 }
00352
catch (Exception e)
00353 {
00354
return e.getMessage();
00355 }
00356 }
00357
00365 private String
applyXsl(String xml, String xsl)
00366 {
00367
try
00368 {
00369 StringWriter result =
new StringWriter();
00370
if (
tFactory == null)
00371
tFactory = TransformerFactory.newInstance();
00372 File infoXsl =
internationalizeXsl(
new File(
this.getClass().getResource(
00373
"/" + xsl).getFile()));
00374
if (
logger.isDebugEnabled())
00375
logger.debug(
Translate.get(
"controller.xml.use.xsl", infoXsl));
00376
00377
infoTransformer =
tFactory.newTransformer(
new StreamSource(infoXsl));
00378
infoTransformer.transform(
new StreamSource(
new StringReader(xml)),
00379
new StreamResult(result));
00380
return result.toString();
00381 }
00382
catch (Exception e)
00383 {
00384 String msg =
Translate.get(
"controller.xml.transformation.failed", e);
00385
00386
if (
logger.isDebugEnabled())
00387
logger.debug(msg, e);
00388
logger.error(msg);
00389
return msg;
00390 }
00391 }
00392
00393 private File
internationalizeXsl(File xsl)
throws Exception
00394 {
00395
int point = xsl.getAbsolutePath().lastIndexOf(
'.');
00396 String xslPath = xsl.getAbsolutePath();
00397 xslPath = xslPath.substring(0, point) +
"_" + Locale.getDefault()
00398 + xslPath.substring(point);
00399 File i18nXsl =
new File(xslPath);
00400
if (i18nXsl.exists() ==
false)
00401 {
00402 ResourceBundle rb = ResourceBundle.getBundle(
"c-jdbc-xsl");
00403 BufferedReader br =
new BufferedReader(
new FileReader(xsl));
00404 String xml =
"";
00405 String oi18n =
"<i18n>";
00406 String ci18n =
"</i18n>";
00407
int oi18nl = oi18n.length();
00408
int ci18nl = oi18nl + 1;
00409 StringBuffer buffer =
new StringBuffer();
00410 String i18n =
"";
00411
while ((xml = br.readLine()) != null)
00412 {
00413
int indexOpen = 0, indexClose = 0;
00414
while ((indexOpen = xml.indexOf(oi18n)) != -1)
00415 {
00416 indexClose = xml.indexOf(ci18n);
00417 i18n = xml.substring(indexOpen + oi18nl, indexClose).trim();
00418
try
00419 {
00420 i18n = rb.getString(i18n);
00421 }
00422
catch (Exception ignore)
00423
00424 {
00425 }
00426 xml = xml.substring(0, indexOpen) + i18n
00427 + xml.substring(indexClose + ci18nl);
00428 }
00429 buffer.append(xml + System.getProperty(
"line.separator"));
00430 }
00431 BufferedWriter bw =
new BufferedWriter(
new FileWriter(i18nXsl));
00432 bw.write(buffer.toString());
00433 bw.flush();
00434 bw.close();
00435 }
00436
return i18nXsl;
00437 }
00438
00442 public String
removeVirtualDatabase(String virtualname)
00443
throws ControllerException
00444 {
00445
if (
hasVirtualDatabase(virtualname))
00446 {
00447
VirtualDatabase vdb = (
VirtualDatabase)
virtualDatabases.get(virtualname);
00448
try
00449 {
00450 vdb.
disableAllBackend();
00451 }
00452
catch (
VirtualDatabaseException e)
00453 {
00454
throw new ControllerException(e);
00455 }
00456
this.virtualDatabases.remove(virtualname);
00457
00458
00459
if (
MBeanServerManager.isJmxEnabled())
00460 {
00461 Hashtable databases =
new Hashtable();
00462
try
00463 {
00464 databases.put(
"backends", vdb.
getAllBackendNames());
00465 }
00466
catch (
VirtualDatabaseException e)
00467 {
00468
00469 }
00470
RmiConnector.broadcastNotification(
this,
00471
CjdbcNotificationList.CONTROLLER_VIRTUALDATABASE_REMOVED,
00472
CjdbcNotificationList.NOTIFICATION_LEVEL_INFO,
Translate.get(
00473
"notification.virtualdatabase.removed", vdb.
getName()),
00474 databases);
00475 }
00476 }
00477
return Translate.get(
"controller.removeVirtualDatabase.success",
00478 virtualname);
00479 }
00480
00484 public void addDriver(byte[] bytes)
throws Exception
00485 {
00486
00487 File driversDirectory = null;
00488 URL url =
Controller.class
00489 .getResource(
ControllerConstants.C_JDBC_DRIVER_JAR_FILE);
00490
boolean error =
false;
00491
if (url != null)
00492 {
00493 driversDirectory = (
new File(url.getFile())).getParentFile();
00494 error = (driversDirectory == null) || !driversDirectory.exists();
00495 }
00496
00497
if (error)
00498 {
00499 String msg =
Translate.get(
"controller.driver.dir.not.found");
00500
logger.error(msg);
00501
throw new ControllerException(msg);
00502 }
00503
00504
00505 File temp = null;
00506
try
00507 {
00508 temp = File.createTempFile(
"driver",
"zip", driversDirectory);
00509 FileOutputStream output =
new FileOutputStream(temp);
00510 output.write(bytes);
00511 output.close();
00512 }
00513
catch (IOException e)
00514 {
00515 String msg =
Translate.get(
"controller.add.jar.read.failed", e);
00516
logger.error(msg);
00517
throw new ControllerException(msg);
00518 }
00519
00520
00521
try
00522 {
00523 Enumeration entries;
00524 ZipFile zipFile =
new ZipFile(temp);
00525
00526
00527
int lenght;
00528 InputStream in;
00529 BufferedOutputStream out;
00530 byte[] buffer =
new byte[1024];
00531
00532 entries = zipFile.entries();
00533
while (entries.hasMoreElements())
00534 {
00535 ZipEntry entry = (ZipEntry) entries.nextElement();
00536
00537
if (entry.isDirectory())
00538 {
00539
00540
if (
logger.isDebugEnabled())
00541
logger.debug(
Translate.get(
"controller.add.jar.extract.dir", entry
00542 .getName()));
00543
00544 (
new File(driversDirectory, entry.getName())).mkdir();
00545
continue;
00546 }
00547
00548
00549
if (
logger.isDebugEnabled())
00550
logger.debug(
Translate.get(
"controller.add.jar.extract.file", entry
00551 .getName()));
00552
00553 in = zipFile.getInputStream(entry);
00554 out =
new BufferedOutputStream(
new FileOutputStream(driversDirectory
00555 + System.getProperty(
"file.separator") + entry.getName()));
00556
while ((lenght = in.read(buffer)) >= 0)
00557 out.write(buffer, 0, lenght);
00558
00559 in.close();
00560 out.close();
00561 }
00562
00563 zipFile.close();
00564 temp.delete();
00565
logger.info(
Translate.get(
"controller.add.jar.to.directory",
00566 driversDirectory.toString()));
00567 }
00568
catch (IOException e)
00569 {
00570 String msg =
Translate.get(
"controller.driver.extract.failed", e);
00571
logger.error(msg);
00572
throw new ControllerException(msg);
00573 }
00574 }
00575
00583 public VirtualDatabase getVirtualDatabase(String virtualDatabaseName)
00584 {
00585
return (
VirtualDatabase)
virtualDatabases.get(virtualDatabaseName);
00586 }
00587
00588
00589
00593 public void refreshLogConfiguration() throws
ControllerException
00594 {
00595
try
00596 {
00597
LogManager.configure(
this.getClass().getResource(
00598
ControllerConstants.LOG4J_RESOURCE).getFile());
00599
if (
logger.isDebugEnabled())
00600
logger.info(
Translate.get(
"controller.refresh.log.success"));
00601 }
00602
catch (Exception e)
00603 {
00604
throw new ControllerException(
Translate
00605 .get(
"controller.logconfigfile.not.found"));
00606 }
00607 }
00608
00612 public String
getVersionNumber()
00613 {
00614
return Constants.VERSION;
00615 }
00616
00620 public String
getXml()
00621 {
00622
try
00623 {
00624
return prettyXml(
getXmlController());
00625 }
00626
catch (Exception e)
00627 {
00628
logger.error(
Translate.get(
"controller.xml.transformation.failed", e));
00629
return e.getMessage();
00630 }
00631 }
00632
00639 public String
getXmlController()
00640 {
00641 StringBuffer info =
new StringBuffer();
00642 info.append(
"<C-JDBC-CONTROLLER>");
00643 info.append(
"<" +
ControllerXmlTags.ELT_CONTROLLER +
" "
00644 +
ControllerXmlTags.ATT_CONTROLLER_IP +
"=\"" +
this.getIPAddress()
00645 +
"\" " +
ControllerXmlTags.ATT_CONTROLLER_PORT +
"=\""
00646 +
this.getPortNumber() +
"\" " +
">");
00647
00648 info.append(
"<" +
ControllerXmlTags.ELT_INTERNATIONALIZATION +
" "
00649 +
ControllerXmlTags.ATT_LANGUAGE +
"=\""
00650 + Locale.getDefault().getLanguage() +
"\"/>");
00651
00652
if (
report.
isReportEnabled())
00653 {
00654 info.append(
"<" +
ControllerXmlTags.ELT_REPORT +
" "
00655 +
ControllerXmlTags.ATT_REPORT_ENABLE_FILE_LOGGING +
"=\""
00656 +
report.
isEnableFileLogging() +
"\" "
00657 +
ControllerXmlTags.ATT_REPORT_HIDE_SENSITIVE_DATA +
"=\""
00658 +
report.
isHideSensitiveData() +
"\" "
00659 +
ControllerXmlTags.ATT_REPORT_GENERATE_ON_FATAL +
"=\""
00660 +
report.
isGenerateOnFatal() +
"\" "
00661 +
ControllerXmlTags.ATT_REPORT_GENERATE_ON_SHUTDOWN +
"=\""
00662 +
report.
isGenerateOnShutdown() +
"\" "
00663 +
ControllerXmlTags.ATT_REPORT_REPORT_LOCATION +
"=\""
00664 +
report.
getReportLocation() +
"\" />");
00665 }
00666
00667
if (
getJmxEnable())
00668 {
00669 info.append(
"<" +
ControllerXmlTags.ELT_JMX +
">");
00670
if (
configuration.containsKey(
JmxConstants.ADAPTOR_TYPE_HTTP))
00671 {
00672 info.append(
"<" +
ControllerXmlTags.ELT_HTTP_JMX_ADAPTOR +
" "
00673 +
ControllerXmlTags.ATT_JMX_ADAPTOR_PORT +
"=\""
00674 +
configuration.get(
JmxConstants.ADAPTOR_TYPE_HTTP) +
"\" />");
00675 }
00676
if (
configuration.containsKey(
JmxConstants.ADAPTOR_TYPE_RMI))
00677 {
00678 info.append(
"<" +
ControllerXmlTags.ELT_RMI_JMX_ADAPTOR +
" "
00679 +
ControllerXmlTags.ATT_JMX_ADAPTOR_PORT +
"=\""
00680 +
configuration.get(
JmxConstants.ADAPTOR_TYPE_RMI) +
"\" />");
00681 }
00682
00683 info.append(
"</" +
ControllerXmlTags.ELT_JMX +
">");
00684 }
00685
00686
if (
this.isSecurityEnabled())
00687 info.append(
this.
getSecurity().
getXml());
00688 info.append(
"</" +
ControllerXmlTags.ELT_CONTROLLER +
">");
00689 info.append(
"</C-JDBC-CONTROLLER>");
00690
return info.toString();
00691 }
00692
00698 public String
getXmlVirtualDatabases()
00699 {
00700
try
00701 {
00702 StringBuffer info =
new StringBuffer();
00703 info.append(
"<C-JDBC>");
00704 ArrayList
virtualDatabases =
this.getVirtualDatabases();
00705
for (
int i = 0, size = virtualDatabases.size(); i < size; i++)
00706 info.append(((
VirtualDatabase) virtualDatabases.get(i)).getXml());
00707 info.append(
"</C-JDBC>");
00708
return info.toString();
00709 }
00710
catch (Exception e)
00711 {
00712
logger.error(e.getMessage(), e);
00713
return e.getMessage();
00714 }
00715 }
00716
00722 public ControllerServerThread getConnectionThread()
00723 {
00724
return connectionThread;
00725 }
00726
00732 public void shutdown() throws
ControllerException
00733 {
00734
this.shutdown(
Constants.DEFAULT_SHUTDOWN_MODE);
00735 }
00736
00740 public void shutdown(
int level)
throws ControllerException
00741 {
00742
this.shutdown(level,
true);
00743 }
00744
00749 public void shutdownDatabase(String databaseName,
int level)
00750
throws ControllerException
00751 {
00752
VirtualDatabase database =
this.getVirtualDatabase(databaseName);
00753
if (database != null)
00754 {
00755
virtualDatabases.remove(databaseName);
00756
if (
getJmxEnable() ==
true)
00757 {
00758
try
00759 {
00760
MBeanServerManager.unregister(
JmxConstants
00761 .getVirtualDbObjectName(databaseName));
00762 }
00763
catch (Exception jmxException)
00764 {
00765
logger.error(
Translate.get(
"jmx.shutdown.virtual.database.failed"));
00766 }
00767 }
00768
00769
00770
00771
if (
MBeanServerManager.isJmxEnabled())
00772 {
00773 Hashtable databases =
new Hashtable();
00774
try
00775 {
00776 databases.put(
"backends", database.
getAllBackendNames());
00777 }
00778
catch (
VirtualDatabaseException e)
00779 {
00780
00781 }
00782
RmiConnector.broadcastNotification(
this,
00783
CjdbcNotificationList.CONTROLLER_VIRTUALDATABASE_REMOVED,
00784
CjdbcNotificationList.NOTIFICATION_LEVEL_INFO,
Translate.get(
00785
"notification.virtualdatabase.removed", database.
getName()),
00786 databases);
00787 }
00788
00789 database.
shutdown(level);
00790
00791
logger.info(
Translate.get(
"controller.shutdown.remove", databaseName));
00792 }
00793 }
00794
00798 public void shutdown(
int level,
boolean systemExit)
00799
throws ControllerException
00800 {
00801
if (
isShuttingDown)
00802 {
00803
logger.info(
Translate.get(
"controller.already.shutting.down", this
00804 .getName()));
00805
return;
00806 }
00807
isShuttingDown =
true;
00808
00809
if (
isSecurityEnabled() && !
security.getAllowConsoleShutdown())
00810
throw new ControllerException(
Translate
00811 .get(
"controller.shutdown.refused"));
00812
00813
ControllerShutdownThread shutdown =
new ControllerShutdownThread(
this,
00814 level);
00815 shutdown.
setSystemExit(systemExit);
00816 Thread thread =
new Thread(shutdown.
getShutdownGroup(), shutdown,
00817
"Controller Shutdown Thread");
00818 thread.start();
00819
00820
if (
report != null &&
report.
isGenerateOnShutdown())
00821 {
00822
new ReportManager(
this).generate();
00823
logger.info(
Translate.get(
"fatal.report.generated",
report
00824 .
getReportLocation()
00825 + File.separator +
ControllerConstants.REPORT_FILE));
00826 }
00827 }
00828
00836 public String
saveConfiguration() throws
VirtualDatabaseException
00837 {
00838 String msg =
Translate.get(
"controller.save.configuration");
00839
try
00840 {
00841 String configurationFile =
ControllerConstants
00842 .getSaveFile(
new SimpleDateFormat(
"EEE, MMM d, yy")
00843 .format(
new Date()));
00844 DataOutputStream dos =
new DataOutputStream(
new BufferedOutputStream(
00845
new FileOutputStream(configurationFile)));
00846 StringBuffer xml =
new StringBuffer();
00847 xml.append(
prettyXml(
getXmlVirtualDatabases().toString()));
00848 dos.write(xml.toString().getBytes());
00849 dos.close();
00850 }
00851
catch (Exception e)
00852 {
00853 msg =
Translate.get(
"controller.save.configuration.failed", e);
00854
logger.error(msg);
00855 }
00856
return msg;
00857 }
00858
00866 public boolean hasVirtualDatabase(String name)
00867 {
00868
return virtualDatabases.containsKey(name);
00869 }
00870
00871
00872
00900 public static void main(String args[])
throws Exception
00901 {
00902
logger.info(
getVersion());
00903
00904 System.setProperty(
"javax.management.builder.initial",
00905 org.objectweb.cjdbc.controller.jmx.MBeanServerBuilder.class.getName());
00906
00907
ControllerFactory conf =
new ControllerFactory(args);
00908
Controller controller = conf.
getController();
00909
if (controller != null)
00910 controller.
launch();
00911
else
00912
throw new Exception(
Translate.get(
"controller.configure.failed"));
00913 }
00914
00920 public void endOfController(Exception fatal)
00921 {
00922
logger.fatal(
Translate.get(
"fatal.error"));
00923
if (
report.
isGenerateOnFatal())
00924 {
00925
new ReportManager(
this, fatal).generate();
00926
logger.info(
Translate.get(
"fatal.report.generated",
report
00927 .
getReportLocation()
00928 + File.separator +
ControllerConstants.REPORT_FILE));
00929 }
00930 Runtime.getRuntime().exit(1);
00931 }
00932
00937 public void launch()
00938 {
00939
connectionThread =
new ControllerServerThread(
this);
00940
connectionThread.start();
00941
00942 SimpleDateFormat formatter =
new SimpleDateFormat(
00943
"yyyy.MM.dd ww 'at' hh:mm:ss a zzz");
00944 Date day =
new Date();
00945 String date = formatter.format(day);
00946
logger.info(
Translate.get(
"controller.date", date));
00947
logger.info(
Translate.get(
"controller.ready",
getName()));
00948 }
00949
00950
00951
00957 public String
getName()
00958 {
00959
return ipAddress +
":" +
portNumber;
00960 }
00961
00962
00963
00978 public String
loadXmlConfiguration(String filename, String virtualName,
00979
int autoLoad, String checkPoint)
throws Exception
00980 {
00981
try
00982 {
00983 filename = filename.trim();
00984 FileReader fileReader;
00985
try
00986 {
00987 fileReader =
new FileReader(filename);
00988 }
00989
catch (FileNotFoundException fnf)
00990 {
00991
return Translate.get(
"controller.file.not.found", filename);
00992 }
00993
00994
00995 BufferedReader in =
new BufferedReader(fileReader);
00996 StringBuffer xml =
new StringBuffer();
00997 String line;
00998
do
00999 {
01000 line = in.readLine();
01001
if (line != null)
01002 xml.append(line);
01003 }
01004
while (line != null);
01005
01006
01007
addVirtualDatabases(xml.toString(), virtualName, autoLoad, checkPoint);
01008
return Translate.get(
"controller.file.send", filename);
01009 }
01010
catch (Exception e)
01011 {
01012
logger.error(
Translate.get(
"controller.loadXml.failed", e), e);
01013
throw new ControllerException(
Translate.get(
"controller.loadXml.failed",
01014 e));
01015 }
01016 }
01017
01025 public String
loadXML(String filename)
throws Exception
01026 {
01027
return this.loadXmlConfiguration(filename, null,
01028
ControllerConstants.AUTO_ENABLE_BACKEND,
01029
ControllerConstants.DATABASE_DEFAULT_CHECKPOINT);
01030 }
01031
01039 public String
addDriver(String filename)
throws Exception
01040 {
01041
01042
if (
isSecurityEnabled() &&
security.getAllowAdditionalDriver() ==
false)
01043 {
01044
return Translate.get(
"controller.addDriver.abort", filename);
01045 }
01046
try
01047 {
01048 filename = filename.trim();
01049 File file;
01050 FileInputStream fileInput = null;
01051
try
01052 {
01053 file =
new File(filename);
01054 fileInput =
new FileInputStream(file);
01055 }
01056
catch (FileNotFoundException fnf)
01057 {
01058
return Translate.get(
"controller.file.not.found", filename);
01059 }
01060
01061
01062
try
01063 {
01064
long size = file.length();
01065
if (size > Integer.MAX_VALUE)
01066 {
01067
01068 fileInput.close();
01069
return Translate.get(
"controller.addDriver.too.large");
01070
01071 }
01072 byte[] bytes =
new byte[(
int) size];
01073
01074
int nb = fileInput.read(bytes);
01075 fileInput.close();
01076
if (nb != size)
01077 {
01078
return Translate.get(
"controller.file.unreadable", filename);
01079 }
01080
01081
01082
addDriver(bytes);
01083
return Translate.get(
"controller.addDriver.successful", filename);
01084 }
01085
catch (IOException e)
01086 {
01087
return Translate.get(
"controller.addDriver.transfer.failed", filename);
01088 }
01089 }
01090
catch (Exception e)
01091 {
01092
return Translate.get(
"controller.addDriver.send.failed", e);
01093 }
01094 }
01095
01101 public ArrayList
getVirtualDatabases()
01102 {
01103 ArrayList result =
new ArrayList();
01104
for (Iterator iter =
virtualDatabases.values().iterator(); iter.hasNext();)
01105 result.add(iter.next());
01106
return result;
01107 }
01108
01114 public String
getIPAddress()
01115 {
01116
return ipAddress;
01117 }
01118
01124 public void setIPAddress(String ipAddress)
01125 {
01126
this.ipAddress = ipAddress;
01127 }
01128
01134 public int getPortNumber()
01135 {
01136
return portNumber;
01137 }
01138
01144 public void setPortNumber(
int port)
01145 {
01146
portNumber = port;
01147 }
01148
01154 public int getBacklogSize()
01155 {
01156
return backlogSize;
01157 }
01158
01164 public void setBacklogSize(
int size)
01165 {
01166
backlogSize = size;
01167 }
01168
01174 public boolean getJmxEnable()
01175 {
01176
return MBeanServerManager.isJmxEnabled();
01177 }
01178
01184 public String
getJmxName()
01185 {
01186
if (
getJmxEnable())
01187 {
01188
RmiConnector connector = ((
RmiConnector)
RmiConnector.getRmiConnectors()
01189 .get(0));
01190
return connector.
getHostName() +
":" + connector.
getPort();
01191 }
01192
else
01193
return getName();
01194 }
01195
01201 public void setJmxEnable(
boolean enable)
01202 {
01203
configuration.put(
ControllerFactory.JMX_ENABLE,
"" + enable);
01204 }
01205
01211 public static String
getVersion()
01212 {
01213
return Translate.get(
"controller.info",
Constants.VERSION);
01214 }
01215
01221 public Hashtable
getConfiguration()
01222 {
01223
return configuration;
01224 }
01225
01231 public boolean isSecurityEnabled()
01232 {
01233
return security != null;
01234 }
01235
01239 public ControllerSecurityManager
getSecurity()
01240 {
01241
return security;
01242 }
01243
01247 public void setSecurity(ControllerSecurityManager security)
01248 {
01249
this.security = security;
01250 }
01251
01255 public ArrayList
listVirtualDatabases()
01256 {
01257
return new ArrayList(
virtualDatabases.keySet());
01258 }
01259
01263 public String
generateReport() throws Exception
01264 {
01265
report.
startReport();
01266
return report.
generate();
01267 }
01268
01272 public ArrayList
listBackends(String virtualDbName)
throws Exception
01273 {
01274
VirtualDatabase vdb = (
VirtualDatabase)
virtualDatabases.get(virtualDbName);
01275
if (vdb == null)
01276
throw new Exception(
ExceptionTypes.DATABASE_NOT_FOUND);
01277
else
01278 {
01279
return vdb.
viewAllBackendNames();
01280 }
01281 }
01282
01286 public ArrayList
listDatabaseClients(String virtualDbName)
throws Exception
01287 {
01288
VirtualDatabase vdb = (
VirtualDatabase)
virtualDatabases.get(virtualDbName);
01289
if (vdb == null)
01290
throw new Exception(
ExceptionTypes.DATABASE_NOT_FOUND);
01291
else
01292 {
01293
return vdb.
viewAllClientNames();
01294 }
01295 }
01296
01300 public boolean isCacheEnableForDatabase(String virtualDbName)
01301
throws Exception
01302 {
01303
VirtualDatabase vdb = (
VirtualDatabase)
virtualDatabases.get(virtualDbName);
01304
if (vdb == null)
01305
throw new Exception(
ExceptionTypes.DATABASE_NOT_FOUND);
01306
else
01307 {
01308
return (vdb.
getRequestManager().getResultCache() == null) ?
false :
true;
01309 }
01310 }
01311
01317 public void setConfiguration(Hashtable configuration)
01318 {
01319
this.configuration = configuration;
01320 }
01321
01325 public String
viewDatabaseXml(String databaseName)
throws Exception
01326 {
01327
VirtualDatabase database =
getVirtualDatabase(databaseName);
01328
if (database != null)
01329
return prettyXml(database.
getXml());
01330
else
01331
return "";
01332 }
01333
01337 public String
generateLogReport() throws Exception
01338 {
01339
ReportManager report =
new ReportManager(
this,
true);
01340
return report.
generateJustLogs();
01341 }
01342
01346 public File[]
listAvailableDumpFiles()
01347 {
01348
if (
getVirtualDatabases().size() <= 0)
01349
return new File[0];
01350
01351 File f =
new File(((
VirtualDatabase)
getVirtualDatabases().get(0))
01352 .getRequestManager().getBackupManager().getBackupDir());
01353
if (f.exists())
01354 {
01355
return f.listFiles(
new FilenameFilter()
01356 {
01360
public boolean accept(File dir, String name)
01361 {
01362
if (name.endsWith(
ZipMe.ZIP_EXT))
01363
return true;
01364
else
01365
return false;
01366 }
01367 });
01368 }
01369
else
01370
return new File[0];
01371 }
01372
01376 public boolean removeDumpFile(File dumpFile)
01377 {
01378 logger.info(
Translate.get(
"controller.remove.dump", dumpFile.getName()));
01379
return dumpFile.delete();
01380 }
01381
01385 public String viewLogConfigurationFile() throws IOException
01386 {
01387 File logFile =
new File(getClass().getResource(
01388
ControllerConstants.LOG4J_RESOURCE).getFile());
01389 BufferedReader reader =
new BufferedReader(
new FileReader(logFile));
01390 StringBuffer buffer =
new StringBuffer();
01391 String line;
01392
while ((line = reader.readLine()) != null)
01393 buffer.append(line + System.getProperty(
"line.separator"));
01394 reader.close();
01395
return buffer.toString();
01396 }
01397
01401 public void updateLogConfigurationFile(String newConfiguration)
01402
throws IOException,
ControllerException
01403 {
01404 File logFile =
new File(getClass().getResource(
01405
ControllerConstants.LOG4J_RESOURCE).getFile());
01406 BufferedWriter writer =
new BufferedWriter(
new FileWriter(logFile));
01407 writer.write(newConfiguration);
01408 writer.flush();
01409 writer.close();
01410 refreshLogConfiguration();
01411 }
01412
01416 public boolean isDistributedVirtualDatabase(String databaseName)
01417 {
01418
VirtualDatabase db = getVirtualDatabase(databaseName);
01419
if (db == null || !db.
isDistributed())
01420
return false;
01421
else
01422
return true;
01423 }
01424
01430 public ReportManager getReport()
01431 {
01432
return report;
01433 }
01434
01440 public void setReport(
ReportManager report)
01441 {
01442
this.report = report;
01443 }
01444 }