src/org/objectweb/cjdbc/controller/virtualdatabase/VirtualDatabase.java

説明を見る。
00001 00025 package org.objectweb.cjdbc.controller.virtualdatabase; 00026 00027 import java.io.Serializable; 00028 import java.sql.SQLException; 00029 import java.util.ArrayList; 00030 import java.util.Hashtable; 00031 import java.util.Map; 00032 00033 import javax.management.NotCompliantMBeanException; 00034 import javax.management.ObjectName; 00035 00036 import org.objectweb.cjdbc.common.exceptions.BackupException; 00037 import org.objectweb.cjdbc.common.exceptions.ExceptionTypes; 00038 import org.objectweb.cjdbc.common.exceptions.OctopusException; 00039 import org.objectweb.cjdbc.common.exceptions.VirtualDatabaseException; 00040 import org.objectweb.cjdbc.common.i18n.Translate; 00041 import org.objectweb.cjdbc.common.jmx.JmxConstants; 00042 import org.objectweb.cjdbc.common.jmx.JmxException; 00043 import org.objectweb.cjdbc.common.jmx.mbeans.VirtualDatabaseMBean; 00044 import org.objectweb.cjdbc.common.jmx.notifications.CjdbcNotificationList; 00045 import org.objectweb.cjdbc.common.log.Trace; 00046 import org.objectweb.cjdbc.common.shared.BackendState; 00047 import org.objectweb.cjdbc.common.shared.BackupListener; 00048 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest; 00049 import org.objectweb.cjdbc.common.sql.SelectRequest; 00050 import org.objectweb.cjdbc.common.sql.StoredProcedure; 00051 import org.objectweb.cjdbc.common.sql.filters.AbstractBlobFilter; 00052 import org.objectweb.cjdbc.common.sql.schema.DatabaseSchema; 00053 import org.objectweb.cjdbc.common.sql.schema.DatabaseTable; 00054 import org.objectweb.cjdbc.common.users.AdminUser; 00055 import org.objectweb.cjdbc.common.users.VirtualDatabaseUser; 00056 import org.objectweb.cjdbc.common.util.Constants; 00057 import org.objectweb.cjdbc.common.util.ReadPrioritaryFIFOWriteLock; 00058 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags; 00059 import org.objectweb.cjdbc.common.xml.XmlComponent; 00060 import org.objectweb.cjdbc.controller.authentication.AuthenticationManager; 00061 import org.objectweb.cjdbc.controller.backend.DatabaseBackend; 00062 import org.objectweb.cjdbc.controller.core.Controller; 00063 import org.objectweb.cjdbc.controller.core.shutdown.VirtualDatabaseShutdownThread; 00064 import org.objectweb.cjdbc.controller.jmx.AbstractStandardMBean; 00065 import org.objectweb.cjdbc.controller.jmx.MBeanServerManager; 00066 import org.objectweb.cjdbc.controller.jmx.RmiConnector; 00067 import org.objectweb.cjdbc.controller.monitoring.SQLMonitoring; 00068 import org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLog; 00069 import org.objectweb.cjdbc.controller.recoverylog.BackendRecoveryInfo; 00070 import org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog; 00071 import org.objectweb.cjdbc.controller.requestmanager.RequestManager; 00072 00085 public class VirtualDatabase extends AbstractStandardMBean 00086 implements 00087 Serializable, 00088 VirtualDatabaseMBean, 00089 XmlComponent 00090 { 00091 // 00092 // How the code is organized ? 00093 // 00094 // 1. Member variables 00095 // 2. Constructor(s) 00096 // 3. Request handling 00097 // 4. Transaction handling 00098 // 5. Database backend management 00099 // 6. Distribution management (multicast) 00100 // 7. Getter/Setter (possibly in alphabetical order) 00101 // 8. Shutdown 00102 // 00103 00105 protected String name; 00106 00111 protected AuthenticationManager authenticationManager; 00112 00114 protected ArrayList backends; 00115 00117 protected ReadPrioritaryFIFOWriteLock rwLock; 00118 00120 protected RequestManager requestManager; 00121 00123 public Trace logger = null; 00124 protected Trace requestLogger = null; 00125 00126 // List of current active Worker Threads 00127 private ArrayList activeThreads = new ArrayList(); 00128 // List of current idle Worker Threads 00129 private int idleThreads = 0; 00130 // List of current pending connections (Socket objects) 00131 private ArrayList pendingConnections = new ArrayList(); 00132 00134 protected int maxNbOfConnections; 00135 00137 protected boolean poolConnectionThreads; 00138 00140 protected long maxThreadIdleTime; 00141 00146 protected int minNbOfThreads; 00147 00149 protected int maxNbOfThreads; 00150 00152 protected int currentNbOfThreads; 00153 00155 protected VirtualDatabaseMetaData metadata; 00156 00157 private SQLMonitoring sqlMonitor = null; 00158 00160 public static final int CHECK_BACKEND_ENABLE = 1; 00162 public static final int CHECK_BACKEND_DISABLE = 0; 00164 public static final int NO_CHECK_BACKEND = -1; 00165 00167 private int sqlShortFormLength; 00168 00170 private AbstractBlobFilter blobFilter; 00171 00173 Controller controller; 00174 00176 private String databaseProductNames = "C-JDBC"; 00177 00179 private boolean shuttingDown = false; 00180 00181 /* Constructors */ 00182 00201 public VirtualDatabase(Controller controller, String name, 00202 int maxConnections, boolean pool, int minThreads, int maxThreads, 00203 long maxThreadIdleTime, int sqlShortFormLength, 00204 AbstractBlobFilter blobFilter) throws NotCompliantMBeanException, 00205 JmxException 00206 { 00207 super(VirtualDatabaseMBean.class); 00208 this.controller = controller; 00209 this.name = name; 00210 this.maxNbOfConnections = maxConnections; 00211 this.poolConnectionThreads = pool; 00212 this.minNbOfThreads = minThreads; 00213 this.maxNbOfThreads = maxThreads; 00214 this.maxThreadIdleTime = maxThreadIdleTime; 00215 this.sqlShortFormLength = sqlShortFormLength; 00216 this.blobFilter = blobFilter; 00217 backends = new ArrayList(); 00218 00219 ObjectName objectName = JmxConstants.getVirtualDbObjectName(name); 00220 MBeanServerManager.registerMBean(this, objectName); 00221 00222 rwLock = new ReadPrioritaryFIFOWriteLock(); 00223 logger = Trace.getLogger("org.objectweb.cjdbc.controller.virtualdatabase." 00224 + name); 00225 requestLogger = Trace 00226 .getLogger("org.objectweb.cjdbc.controller.virtualdatabase.request." 00227 + name); 00228 } 00229 00233 public String getAssociatedString() 00234 { 00235 return "virtualdatabase"; 00236 } 00237 00243 public boolean isDistributed() 00244 { 00245 return false; 00246 } 00247 00248 /* Request Handling */ 00249 00259 public boolean checkUserAuthentication(String virtualLogin, 00260 String virtualPassword) 00261 { 00262 if (authenticationManager == null) 00263 { 00264 logger.error("No authentification manager defined to check login '" 00265 + virtualLogin + "'"); 00266 return false; 00267 } 00268 else 00269 return authenticationManager.isValidVirtualUser(new VirtualDatabaseUser( 00270 virtualLogin, virtualPassword)); 00271 } 00272 00282 public boolean checkAdminAuthentication(String adminLogin, 00283 String adminPassword) 00284 { 00285 if (authenticationManager == null) 00286 { 00287 logger.error("No authentification manager defined to check admin login '" 00288 + adminLogin + "'"); 00289 return false; 00290 } 00291 else 00292 return authenticationManager.isValidAdminUser(new AdminUser(adminLogin, 00293 adminPassword)); 00294 } 00295 00303 public ControllerResultSet execReadRequest(SelectRequest request) 00304 throws SQLException 00305 { 00306 if (request == null) 00307 { 00308 String msg = "Request failed (null read request received)"; 00309 logger.warn(msg); 00310 throw new SQLException(msg); 00311 } 00312 00313 try 00314 { 00315 if (requestLogger.isInfoEnabled()) 00316 requestLogger.info("S " + request.getTransactionId() + " " 00317 + request.getSQL()); 00318 00319 long start = 0; 00320 if (sqlMonitor != null) 00321 start = System.currentTimeMillis(); 00322 00323 ControllerResultSet rs = requestManager.execReadRequest(request); 00324 00325 if (sqlMonitor != null) 00326 sqlMonitor.logRequestTime(request, System.currentTimeMillis() - start); 00327 00328 return rs; 00329 } 00330 catch (SQLException e) 00331 { 00332 String msg = "Request '" + request.getId() + "' failed (" 00333 + e.getMessage() + ")"; 00334 logger.warn(msg); 00335 if (sqlMonitor != null) 00336 sqlMonitor.logError(request); 00337 throw e; 00338 } 00339 } 00340 00348 public int execWriteRequest(AbstractWriteRequest request) throws SQLException 00349 { 00350 if (request == null) 00351 { 00352 String msg = "Request failed (null write request received)"; 00353 logger.warn(msg); 00354 throw new SQLException(msg); 00355 } 00356 00357 try 00358 { 00359 if (requestLogger.isInfoEnabled()) 00360 requestLogger.info("W " + request.getTransactionId() + " " 00361 + request.getSQL()); 00362 00363 long start = 0; 00364 if (sqlMonitor != null) 00365 start = System.currentTimeMillis(); 00366 00367 int result = requestManager.execWriteRequest(request); 00368 00369 if (sqlMonitor != null) 00370 sqlMonitor.logRequestTime(request, System.currentTimeMillis() - start); 00371 00372 return result; 00373 } 00374 catch (SQLException e) 00375 { 00376 String msg = "Request '" + request.getId() + "' failed (" 00377 + e.getMessage() + ")"; 00378 logger.warn(msg); 00379 if (sqlMonitor != null) 00380 sqlMonitor.logError(request); 00381 throw e; 00382 } 00383 } 00384 00392 public ControllerResultSet execWriteRequestWithKeys( 00393 AbstractWriteRequest request) throws SQLException 00394 { 00395 if (request == null) 00396 { 00397 String msg = "Request failed (null write request received)"; 00398 logger.warn(msg); 00399 throw new SQLException(msg); 00400 } 00401 00402 try 00403 { 00404 if (requestLogger.isInfoEnabled()) 00405 requestLogger.info("W " + request.getTransactionId() + " " 00406 + request.getSQL()); 00407 00408 long start = 0; 00409 if (sqlMonitor != null) 00410 start = System.currentTimeMillis(); 00411 00412 ControllerResultSet result = requestManager 00413 .execWriteRequestWithKeys(request); 00414 00415 if (sqlMonitor != null) 00416 sqlMonitor.logRequestTime(request, System.currentTimeMillis() - start); 00417 00418 return result; 00419 } 00420 catch (SQLException e) 00421 { 00422 String msg = "Request '" + request.getId() + "' failed (" 00423 + e.getMessage() + ")"; 00424 logger.warn(msg); 00425 if (sqlMonitor != null) 00426 sqlMonitor.logError(request); 00427 throw e; 00428 } 00429 } 00430 00438 public ControllerResultSet execReadStoredProcedure(StoredProcedure proc) 00439 throws SQLException 00440 { 00441 if (proc == null) 00442 { 00443 String msg = "Request failed (null stored procedure received)"; 00444 logger.warn(msg); 00445 throw new SQLException(msg); 00446 } 00447 00448 try 00449 { 00450 if (requestLogger.isInfoEnabled()) 00451 requestLogger 00452 .info("S " + proc.getTransactionId() + " " + proc.getSQL()); 00453 00454 long start = 0; 00455 if (sqlMonitor != null) 00456 start = System.currentTimeMillis(); 00457 00458 ControllerResultSet rs = requestManager.execReadStoredProcedure(proc); 00459 00460 if (sqlMonitor != null) 00461 sqlMonitor.logRequestTime(proc, System.currentTimeMillis() - start); 00462 00463 return rs; 00464 } 00465 catch (SQLException e) 00466 { 00467 String msg = Translate.get("loadbalancer.storedprocedure.failed", 00468 new String[]{String.valueOf(proc.getId()), e.getMessage()}); 00469 logger.warn(msg); 00470 if (sqlMonitor != null) 00471 sqlMonitor.logError(proc); 00472 throw e; 00473 } 00474 } 00475 00483 protected int execWriteStoredProcedure(StoredProcedure proc) 00484 throws SQLException 00485 { 00486 if (proc == null) 00487 { 00488 String msg = "Request failed (null stored procedure received)"; 00489 logger.warn(msg); 00490 throw new SQLException(msg); 00491 } 00492 00493 try 00494 { 00495 if (requestLogger.isInfoEnabled()) 00496 requestLogger 00497 .info("W " + proc.getTransactionId() + " " + proc.getSQL()); 00498 00499 long start = 0; 00500 if (sqlMonitor != null) 00501 start = System.currentTimeMillis(); 00502 00503 int result = requestManager.execWriteStoredProcedure(proc); 00504 00505 if (sqlMonitor != null) 00506 sqlMonitor.logRequestTime(proc, System.currentTimeMillis() - start); 00507 00508 return result; 00509 } 00510 catch (SQLException e) 00511 { 00512 String msg = Translate.get("loadbalancer.storedprocedure.failed", 00513 new String[]{String.valueOf(proc.getId()), e.getMessage()}); 00514 logger.warn(msg); 00515 if (sqlMonitor != null) 00516 sqlMonitor.logError(proc); 00517 throw e; 00518 } 00519 } 00520 00521 /* Transaction management */ 00522 00533 public long begin(String login) throws SQLException 00534 { 00535 try 00536 { 00537 long tid = requestManager.begin(login); 00538 if (requestLogger.isInfoEnabled()) 00539 requestLogger.info("B " + tid); 00540 return tid; 00541 } 00542 catch (SQLException e) 00543 { 00544 String msg = "Begin failed (" + e.getMessage() + ")"; 00545 logger.warn(msg); 00546 throw e; 00547 } 00548 } 00549 00556 public void commit(long transactionId) throws SQLException 00557 { 00558 try 00559 { 00560 if (requestLogger.isInfoEnabled()) 00561 requestLogger.info("C " + transactionId); 00562 requestManager.commit(transactionId); 00563 } 00564 catch (SQLException e) 00565 { 00566 String msg = "Commit of transaction '" + transactionId + "' failed (" 00567 + e.getMessage() + ")"; 00568 logger.warn(msg); 00569 throw e; 00570 } 00571 } 00572 00579 public void rollback(long transactionId) throws SQLException 00580 { 00581 try 00582 { 00583 if (requestLogger.isInfoEnabled()) 00584 requestLogger.info("R " + transactionId); 00585 requestManager.rollback(transactionId); 00586 } 00587 catch (SQLException e) 00588 { 00589 String msg = "Rollback of transaction '" + transactionId + "' failed (" 00590 + e.getMessage() + ")"; 00591 logger.warn(msg); 00592 throw e; 00593 } 00594 } 00595 00596 /* Backup management */ 00597 00601 public void backupBackendWithCheckpoint(String backendName, 00602 String checkpointName, ArrayList tables) throws VirtualDatabaseException 00603 { 00604 try 00605 { 00606 DatabaseBackend db = getAndCheckBackend(backendName, NO_CHECK_BACKEND); 00607 requestManager.backupBackendWithCheckpoint(db, checkpointName, tables, db 00608 .isReadEnabled(), true, null); 00609 } 00610 catch (SQLException sql) 00611 { 00612 throw new VirtualDatabaseException(sql.getMessage()); 00613 } 00614 } 00615 00620 public synchronized void callBackupManager(boolean backup, 00621 String backendName, String checkpoint, ArrayList tables, 00622 boolean enableAfter, BackupListener listener) 00623 throws VirtualDatabaseException 00624 { 00625 try 00626 { 00627 DatabaseBackend db = getAndCheckBackend(backendName, NO_CHECK_BACKEND); 00628 requestManager.callBackupManager(backup, db, checkpoint, tables, db 00629 .isReadEnabled(), listener); 00630 } 00631 catch (Exception sql) 00632 { 00633 throw new VirtualDatabaseException(sql.getMessage()); 00634 } 00635 } 00636 00637 /* Database backends management */ 00638 00645 public void addBackend(DatabaseBackend db) throws VirtualDatabaseException 00646 { 00647 this.addBackend(db, true); 00648 } 00649 00657 public void addBackend(DatabaseBackend db, boolean checkForCompliance) 00658 throws VirtualDatabaseException 00659 { 00660 if (db == null) 00661 { 00662 String msg = "Illegal null database backend in addBackend(DatabaseBackend) method"; 00663 logger.error(msg); 00664 throw new VirtualDatabaseException(msg); 00665 } 00666 00667 if (db.isReadEnabled()) 00668 { 00669 String msg = "It is not allowed to add an enabled database."; 00670 logger.error(msg); 00671 throw new VirtualDatabaseException(msg); 00672 } 00673 00674 try 00675 { 00676 rwLock.acquireWrite(); 00677 } 00678 catch (InterruptedException e) 00679 { 00680 String msg = Translate.get( 00681 "loadbalancer.backendlist.acquire.writelock.failed", e); 00682 logger.error(msg); 00683 throw new VirtualDatabaseException(msg); 00684 } 00685 00686 if (backends.indexOf(db) == -1) 00687 { 00688 // Check the authentication manager has all virtual logins defined 00689 ArrayList logins = authenticationManager.getVirtualLogins(); 00690 VirtualDatabaseUser vdu; 00691 String login; 00692 for (int i = 0; i < logins.size(); i++) 00693 { 00694 vdu = (VirtualDatabaseUser) logins.get(i); 00695 login = vdu.getLogin(); 00696 if (db.getConnectionManager(login) == null) 00697 throw new VirtualDatabaseException(Translate.get( 00698 "backend.missing.connection.manager", login)); 00699 } 00700 00701 // Initialize the driver and check the compliance 00702 try 00703 { 00704 if (logger.isDebugEnabled()) 00705 logger.debug("Checking driver compliance"); 00706 if (checkForCompliance) 00707 db.checkDriverCompliance(); // Also loads 00708 // the 00709 // driver 00710 } 00711 catch (Exception e) 00712 { 00713 rwLock.releaseWrite(); 00714 String msg = "Error while adding database backend " + db.getName() 00715 + " (" + e + ")"; 00716 logger.warn(msg); 00717 throw new VirtualDatabaseException(msg); 00718 } 00719 db.setSqlShortFormLength(getSQLShortFormLength()); 00720 backends.add(db); 00721 00722 // Add the backend to the list 00723 if (logger.isDebugEnabled()) 00724 logger.debug("Backend " + db.getName() + " added successfully"); 00725 00726 rwLock.releaseWrite(); // Relase the lock 00727 00728 // Jmx 00729 if (MBeanServerManager.isJmxEnabled()) 00730 { 00731 // Send notification 00732 Hashtable data = new Hashtable(); 00733 data.put(CjdbcNotificationList.DATA_DATABASE, this.name); 00734 data.put(CjdbcNotificationList.DATA_DRIVER, db.getDriverClassName()); 00735 String checkpoint = db.getLastKnownCheckpoint(); 00736 checkpoint = (checkpoint == null) ? "" : checkpoint; 00737 data.put(CjdbcNotificationList.DATA_CHECKPOINT, checkpoint); 00738 data.put(CjdbcNotificationList.DATA_NAME, db.getName()); 00739 data.put(CjdbcNotificationList.DATA_URL, db.getURL()); 00740 RmiConnector.broadcastNotification(this, 00741 CjdbcNotificationList.VIRTUALDATABASE_BACKEND_ADDED, 00742 CjdbcNotificationList.NOTIFICATION_LEVEL_INFO, Translate.get( 00743 "notification.backend.added", db.getName()), data); 00744 00745 // Add backend mbean to jmx server 00746 ObjectName objectName = JmxConstants.getDatabaseBackendObjectName(name, 00747 db.getName()); 00748 try 00749 { 00750 MBeanServerManager.registerMBean(db, objectName); 00751 } 00752 catch (JmxException e1) 00753 { 00754 logger.error(Translate.get( 00755 "virtualdatabase.fail.register.backend.mbean", db.getName()), e1); 00756 } 00757 } 00758 00759 } 00760 else 00761 { 00762 rwLock.releaseWrite(); 00763 String msg = "Duplicate backend " + db.getURL(); 00764 logger.warn(msg); 00765 throw new VirtualDatabaseException(msg); 00766 } 00767 00768 } 00769 00776 public void removeCheckpoint(String checkpointName) 00777 throws VirtualDatabaseException 00778 { 00779 try 00780 { 00781 requestManager.removeCheckpoint(checkpointName); 00782 } 00783 catch (Exception e) 00784 { 00785 throw new VirtualDatabaseException(e.getMessage()); 00786 } 00787 } 00788 00792 public void removeBackend(String backend) throws VirtualDatabaseException 00793 { 00794 removeBackend(getAndCheckBackend(backend, NO_CHECK_BACKEND)); 00795 } 00796 00803 public void removeBackend(DatabaseBackend db) throws VirtualDatabaseException 00804 { 00805 if (db == null) 00806 { 00807 String msg = "Illegal null database backend in removeBackend(DatabaseBackend) method"; 00808 logger.error(msg); 00809 throw new VirtualDatabaseException(msg); 00810 } 00811 00812 try 00813 { 00814 rwLock.acquireWrite(); 00815 } 00816 catch (InterruptedException e) 00817 { 00818 String msg = Translate.get( 00819 "loadbalancer.backendlist.acquire.writelock.failed", e); 00820 logger.error(msg); 00821 throw new VirtualDatabaseException(msg); 00822 } 00823 00824 // Sanity checks 00825 int idx = backends.indexOf(db); 00826 if (idx == -1) 00827 { 00828 rwLock.releaseWrite(); // Release the lock 00829 String msg = "Trying to remove a non-existing backend " + db.getName(); 00830 logger.warn(msg); 00831 throw new VirtualDatabaseException(msg); 00832 } 00833 00834 if (((DatabaseBackend) backends.get(idx)).isReadEnabled()) 00835 { 00836 rwLock.releaseWrite(); // Release the lock 00837 String msg = "Trying to remove an enabled backend " + db.getName(); 00838 logger.error(msg); 00839 throw new VirtualDatabaseException(msg); 00840 } 00841 00842 // Remove it 00843 backends.remove(idx); 00844 rwLock.releaseWrite(); // Relase the lock 00845 00846 // Send notification 00847 if (MBeanServerManager.isJmxEnabled()) 00848 { 00849 // Send notification 00850 Hashtable data = new Hashtable(); 00851 data.put(CjdbcNotificationList.DATA_DATABASE, this.name); 00852 data.put(CjdbcNotificationList.DATA_DRIVER, db.getDriverClassName()); 00853 String checkpoint = db.getLastKnownCheckpoint(); 00854 checkpoint = (checkpoint == null) ? "" : checkpoint; 00855 data.put(CjdbcNotificationList.DATA_CHECKPOINT, checkpoint); 00856 data.put(CjdbcNotificationList.DATA_NAME, db.getName()); 00857 data.put(CjdbcNotificationList.DATA_URL, db.getURL()); 00858 RmiConnector.broadcastNotification(this, 00859 CjdbcNotificationList.VIRTUALDATABASE_BACKEND_REMOVED, 00860 CjdbcNotificationList.NOTIFICATION_LEVEL_INFO, Translate.get( 00861 "notification.backend.removed", db.getName()), data); 00862 00863 // Remove backend mbean to jmx server 00864 ObjectName objectName = JmxConstants.getDatabaseBackendObjectName(name, 00865 db.getName()); 00866 try 00867 { 00868 MBeanServerManager.unregister(objectName); 00869 } 00870 catch (JmxException e1) 00871 { 00872 logger.error(Translate.get( 00873 "virtualdatabase.fail.unregister.backend.mbean", db.getName()), e1); 00874 } 00875 } 00876 00877 if (logger.isDebugEnabled()) 00878 logger.debug("Backend " + db.getName() + " removed successfully"); 00879 } 00880 00884 public ArrayList viewCheckpointNames() 00885 { 00886 try 00887 { 00888 AbstractRecoveryLog recoveryLog = requestManager.getRecoveryLog(); 00889 if (recoveryLog == null) 00890 return new ArrayList(); 00891 else 00892 return recoveryLog.getCheckpointNames(); 00893 } 00894 catch (SQLException e) 00895 { 00896 return new ArrayList(); 00897 } 00898 } 00899 00903 public void enableBackend(String backendName) throws VirtualDatabaseException 00904 { 00905 // Call the Request Manager 00906 try 00907 { 00908 DatabaseBackend backend = getAndCheckBackend(backendName, 00909 CHECK_BACKEND_ENABLE); 00910 00911 requestManager.enableBackend(backend); 00912 00913 // Update the list of database product names 00914 if (databaseProductNames.indexOf(backend.getDatabaseProductName()) == -1) 00915 databaseProductNames += "," + backend.getDatabaseProductName(); 00916 00917 // Send notification 00918 if (MBeanServerManager.isJmxEnabled()) 00919 { 00920 Hashtable data = new Hashtable(); 00921 data.put("driver", backend.getDriverClassName()); 00922 String checkpoint = backend.getLastKnownCheckpoint(); 00923 checkpoint = (checkpoint == null) ? "" : checkpoint; 00924 data.put("checkpoint", checkpoint); 00925 data.put("name", backend.getName()); 00926 data.put("url", backend.getURL()); 00927 RmiConnector.broadcastNotification(this, 00928 CjdbcNotificationList.VIRTUALDATABASE_BACKEND_ENABLED, 00929 CjdbcNotificationList.NOTIFICATION_LEVEL_INFO, Translate.get( 00930 "notification.backend.enabled", backend.getName()), data); 00931 } 00932 } 00933 catch (Exception e) 00934 { 00935 e.printStackTrace(); 00936 throw new VirtualDatabaseException(e.getMessage()); 00937 } 00938 } 00939 00943 public void enableBackendFromCheckpoint(String backendName, 00944 String checkpointName) throws VirtualDatabaseException 00945 { 00946 // Call the Request Manager 00947 try 00948 { 00949 DatabaseBackend backend = getAndCheckBackend(backendName, 00950 CHECK_BACKEND_ENABLE); 00951 requestManager.enableBackendFromCheckpoint(backend, checkpointName); 00952 00953 // Update the list of database product names 00954 if (databaseProductNames.indexOf(backend.getDatabaseProductName()) == -1) 00955 databaseProductNames += "," + backend.getDatabaseProductName(); 00956 } 00957 catch (Exception e) 00958 { 00959 throw new VirtualDatabaseException( 00960 "Failed to enable backend from checkpoint: " + e); 00961 } 00962 } 00963 00967 public void enableBackendFromLastCheckpoint(String backendName) 00968 throws VirtualDatabaseException 00969 { 00970 DatabaseBackend backend = getAndCheckBackend(backendName, NO_CHECK_BACKEND); 00971 String checkpoint = backend.getLastKnownCheckpoint(); 00972 if (checkpoint == null) 00973 throw new VirtualDatabaseException("No last checkpoint for backend:" 00974 + backendName); 00975 else 00976 { 00977 if (logger.isDebugEnabled()) 00978 logger.debug("Enabling backend:" + backendName 00979 + " with its last checkpoint:" + backend.getLastKnownCheckpoint()); 00980 } 00981 enableBackendFromCheckpoint(backendName, backend.getLastKnownCheckpoint()); 00982 } 00983 00997 public DatabaseBackend getAndCheckBackend(String backendName, int testEnable) 00998 throws VirtualDatabaseException 00999 { 01000 try 01001 { 01002 acquireReadLockBackendLists(); 01003 } 01004 catch (InterruptedException e) 01005 { 01006 String msg = "Unable to acquire read lock on backend list in getAndCheckBackend (" 01007 + e + ")"; 01008 logger.error(msg); 01009 throw new VirtualDatabaseException(msg); 01010 } 01011 01012 // Find the backend 01013 int size = backends.size(); 01014 DatabaseBackend b = null; 01015 for (int i = 0; i < size; i++) 01016 { 01017 b = (DatabaseBackend) backends.get(i); 01018 if (b.getName().equals(backendName)) 01019 break; 01020 else 01021 b = null; 01022 } 01023 // Check not null 01024 if (b == null) 01025 { 01026 releaseReadLockBackendLists(); 01027 String msg = "Trying to access a non-existing backend " + backendName; 01028 logger.warn(msg); 01029 throw new VirtualDatabaseException(msg); 01030 } 01031 01032 // Check enable/disable 01033 switch (testEnable) 01034 { 01035 case NO_CHECK_BACKEND : 01036 break; 01037 case CHECK_BACKEND_DISABLE : 01038 if (!b.isReadEnabled()) 01039 { 01040 releaseReadLockBackendLists(); 01041 String msg = "Backend " + backendName + " is already disabled"; 01042 logger.warn(msg); 01043 throw new VirtualDatabaseException(msg); 01044 } 01045 break; 01046 case CHECK_BACKEND_ENABLE : 01047 if (b.isReadEnabled()) 01048 { 01049 releaseReadLockBackendLists(); 01050 String msg = "Backend " + backendName + " is already enabled"; 01051 logger.warn(msg); 01052 throw new VirtualDatabaseException(msg); 01053 } 01054 break; 01055 default : 01056 releaseReadLockBackendLists(); 01057 String msg = "Unexpected parameter in getAndCheckBackend(...)"; 01058 logger.error(msg); 01059 throw new VirtualDatabaseException(msg); 01060 } 01061 01062 releaseReadLockBackendLists(); 01063 01064 if (testEnable == CHECK_BACKEND_ENABLE) 01065 { 01066 // Initialize backend for enable 01067 try 01068 { 01069 if (logger.isDebugEnabled()) 01070 logger.debug("Initializing connections for backend " + b.getName()); 01071 b.initializeConnections(); 01072 01073 b.checkDriverCompliance(); 01074 01075 if (logger.isDebugEnabled()) 01076 logger.debug("Checking schema for backend " + b.getName()); 01077 b.checkDatabaseSchema(); 01078 01079 DatabaseSchema backendSchema = b.getDatabaseSchema(); 01080 01081 if (backendSchema != null) 01082 requestManager.mergeDatabaseSchema(backendSchema); 01083 else 01084 logger.warn("Backend " + b.getName() + " has no defined schema."); 01085 } 01086 catch (SQLException e) 01087 { 01088 String msg = "Error while initalizing database backend " + b.getName() 01089 + " (" + e + ")"; 01090 logger.warn(msg,e); 01091 throw new VirtualDatabaseException(msg); 01092 } 01093 } 01094 01095 return b; 01096 } 01097 01101 public void disableBackend(String backendName) 01102 throws VirtualDatabaseException 01103 { 01104 try 01105 { 01106 DatabaseBackend db = getAndCheckBackend(backendName, 01107 CHECK_BACKEND_DISABLE); 01108 requestManager.disableBackend(db); 01109 requestManager.setDatabaseSchema( 01110 getDatabaseSchemaFromActiveBackendsAndRefreshDatabaseProductNames(), 01111 false); 01112 01113 // Send notification 01114 if (MBeanServerManager.isJmxEnabled()) 01115 { 01116 Hashtable data = new Hashtable(); 01117 data.put("driver", db.getDriverClassName()); 01118 String checkpoint = db.getLastKnownCheckpoint(); 01119 checkpoint = (checkpoint == null) ? "" : checkpoint; 01120 data.put("checkpoint", checkpoint); 01121 data.put("name", db.getName()); 01122 data.put("url", db.getURL()); 01123 RmiConnector.broadcastNotification(this, 01124 CjdbcNotificationList.VIRTUALDATABASE_BACKEND_DISABLED, 01125 CjdbcNotificationList.NOTIFICATION_LEVEL_INFO, Translate.get( 01126 "notification.backend.disabled", db.getName()), data); 01127 } 01128 } 01129 catch (Exception e) 01130 { 01131 logger.error("An error occured while disabling backend " + backendName 01132 + " (" + e + ")"); 01133 throw new VirtualDatabaseException(e.getMessage()); 01134 } 01135 } 01136 01145 public void disableAllBackend() throws VirtualDatabaseException 01146 { 01147 try 01148 { 01149 int size = this.backends.size(); 01150 DatabaseBackend dbe; 01151 for (int i = 0; i < size; i++) 01152 { 01153 dbe = (DatabaseBackend) backends.get(i); 01154 if (dbe.isReadEnabled()) 01155 requestManager.disableBackend(getAndCheckBackend(dbe.getName(), 01156 CHECK_BACKEND_DISABLE)); 01157 } 01158 } 01159 catch (Exception e) 01160 { 01161 throw new VirtualDatabaseException(e.getMessage()); 01162 } 01163 } 01164 01170 public void enableAllBackend() throws VirtualDatabaseException 01171 { 01172 try 01173 { 01174 int size = this.backends.size(); 01175 DatabaseBackend dbe; 01176 for (int i = 0; i < size; i++) 01177 { 01178 dbe = (DatabaseBackend) backends.get(i); 01179 if (!dbe.isReadEnabled()) 01180 enableBackend(((DatabaseBackend) backends.get(i)).getName()); 01181 } 01182 } 01183 catch (Exception e) 01184 { 01185 logger.error(e); 01186 throw new VirtualDatabaseException(e.getMessage()); 01187 } 01188 } 01189 01196 public void enableAllBackend(String checkpoint) 01197 throws VirtualDatabaseException 01198 { 01199 if (checkpoint == null || checkpoint.equals("")) 01200 enableAllBackend(); 01201 else 01202 { 01203 try 01204 { 01205 int size = this.backends.size(); 01206 DatabaseBackend dbe; 01207 for (int i = 0; i < size; i++) 01208 { 01209 dbe = (DatabaseBackend) backends.get(i); 01210 if (!dbe.isReadEnabled()) 01211 { 01212 if (checkpoint == null || checkpoint.equals("")) 01213 enableBackend(((DatabaseBackend) backends.get(i)).getName()); 01214 else 01215 enableBackendFromCheckpoint(((DatabaseBackend) backends.get(i)) 01216 .getName(), checkpoint); 01217 } 01218 } 01219 } 01220 catch (Exception e) 01221 { 01222 throw new VirtualDatabaseException(e.getMessage()); 01223 } 01224 } 01225 } 01226 01230 public void enableAllBackendsFromRecovery(String checkpoint) 01231 throws VirtualDatabaseException 01232 { 01233 AbstractRecoveryLog log = requestManager.getRecoveryLog(); 01234 // If no recovery log is defined ignore call to this method 01235 if (log == null) 01236 { 01237 enableAllBackend(); 01238 } 01239 else 01240 { 01241 try 01242 { 01243 int size = this.backends.size(); 01244 DatabaseBackend dbe; 01245 String backendName; 01246 BackendRecoveryInfo info; 01247 for (int i = 0; i < size; i++) 01248 { 01249 dbe = (DatabaseBackend) backends.get(i); 01250 backendName = dbe.getName(); 01251 info = log.getBackendInfo(name, backendName); 01252 if (info.getBackendState() == BackendState.DISABLED) 01253 continue; 01254 if (!dbe.isReadEnabled()) 01255 { 01256 if (checkpoint == null || checkpoint.equals("")) 01257 enableBackend(dbe.getName()); 01258 else 01259 enableBackendFromCheckpoint(dbe.getName(), checkpoint); 01260 } 01261 } 01262 } 01263 catch (Exception e) 01264 { 01265 throw new VirtualDatabaseException(e.getMessage()); 01266 } 01267 } 01268 01269 } 01270 01274 public void disableBackendForCheckpoint(String backendName, 01275 String checkpointName) throws VirtualDatabaseException 01276 { 01277 try 01278 { 01279 requestManager.disableBackendForCheckpoint(getAndCheckBackend( 01280 backendName, CHECK_BACKEND_DISABLE), checkpointName); 01281 requestManager.setDatabaseSchema( 01282 getDatabaseSchemaFromActiveBackendsAndRefreshDatabaseProductNames(), 01283 false); 01284 } 01285 catch (Exception e) 01286 { 01287 logger.error("An error occured while disabling backend " + backendName 01288 + " (" + e + ")"); 01289 throw new VirtualDatabaseException(e.getMessage()); 01290 } 01291 } 01292 01300 public final void acquireReadLockBackendLists() throws InterruptedException 01301 { 01302 rwLock.acquireRead(); 01303 } 01304 01310 public final void releaseReadLockBackendLists() 01311 { 01312 rwLock.releaseRead(); 01313 } 01314 01315 /* Getter/Setter and tools (equals, ...) */ 01316 01322 public AuthenticationManager getAuthenticationManager() 01323 { 01324 return authenticationManager; 01325 } 01326 01333 public void setAuthenticationManager( 01334 AuthenticationManager authenticationManager) 01335 { 01336 this.authenticationManager = authenticationManager; 01337 } 01338 01344 public ArrayList getBackends() 01345 { 01346 return backends; 01347 } 01348 01352 public ArrayList getAllBackendNames() throws VirtualDatabaseException 01353 { 01354 try 01355 { 01356 acquireReadLockBackendLists(); 01357 } 01358 catch (InterruptedException e) 01359 { 01360 String msg = "Unable to acquire read lock on backend list in getAllBackendNames (" 01361 + e + ")"; 01362 logger.error(msg); 01363 throw new VirtualDatabaseException(msg); 01364 } 01365 01366 int size = backends.size(); 01367 ArrayList result = new ArrayList(); 01368 for (int i = 0; i < size; i++) 01369 { 01370 result.add(((DatabaseBackend) backends.get(i)).getName()); 01371 } 01372 01373 releaseReadLockBackendLists(); 01374 return result; 01375 } 01376 01385 public String getDatabaseName() 01386 { 01387 return name; 01388 } 01389 01393 public String getDatabaseProductName() 01394 { 01395 return databaseProductNames; 01396 } 01397 01404 public int getSQLShortFormLength() 01405 { 01406 return sqlShortFormLength; 01407 } 01408 01413 public VirtualDatabaseMetaData getMetaData() 01414 { 01415 if (metadata == null) 01416 { 01417 metadata = new VirtualDatabaseMetaData(this); 01418 } 01419 return metadata; 01420 } 01421 01429 public DatabaseSchema getDatabaseSchemaFromActiveBackendsAndRefreshDatabaseProductNames() 01430 throws SQLException 01431 { 01432 try 01433 { 01434 acquireReadLockBackendLists(); 01435 } 01436 catch (InterruptedException e) 01437 { 01438 String msg = "Unable to acquire read lock on backend list in getDatabaseSchemaFromActiveBackends (" 01439 + e + ")"; 01440 logger.error(msg); 01441 throw new SQLException(msg); 01442 } 01443 // Build the new schema from all active backend's schemas 01444 int size = backends.size(); 01445 DatabaseSchema schema = null; 01446 DatabaseBackend b = null; 01447 String dbProductNames = "C-JDBC"; 01448 for (int i = 0; i < size; i++) 01449 { 01450 b = (DatabaseBackend) backends.get(i); 01451 if (b.isReadEnabled()) 01452 { 01453 if (schema == null) 01454 schema = b.getDatabaseSchema(); 01455 else 01456 schema.mergeSchema(b.getDatabaseSchema()); 01457 } 01458 01459 // Update the list of database product names 01460 if (dbProductNames.indexOf(b.getDatabaseProductName()) == -1) 01461 dbProductNames += "," + b.getDatabaseProductName(); 01462 } 01463 01464 releaseReadLockBackendLists(); 01465 databaseProductNames = dbProductNames; 01466 logger.debug("getDatabaseSchemaFromActiveBackends - end"); 01467 if (requestManager.getRecoveryLog() != null) 01468 { 01469 try 01470 { 01471 JDBCRecoveryLog log = (JDBCRecoveryLog) requestManager.getRecoveryLog(); 01472 // Remove recovery log tables from schema 01473 if (schema.hasTable(log.getBackendTableName())) 01474 schema.removeTable(new DatabaseTable(log.getBackendTableName())); 01475 if (schema.hasTable(log.getCheckpointTableName())) 01476 schema.removeTable(new DatabaseTable(log.getCheckpointTableName())); 01477 if (schema.hasTable(log.getLogTableName())) 01478 schema.removeTable(new DatabaseTable(log.getLogTableName())); 01479 } 01480 catch (RuntimeException ignore) 01481 { 01482 // Should be a ClassCastException 01483 } 01484 } 01485 return schema; 01486 } 01487 01496 public void setDatabaseSchema(DatabaseSchema schema, boolean isStatic) 01497 { 01498 if (requestManager != null) 01499 requestManager.setDatabaseSchema(schema, isStatic); 01500 else 01501 logger 01502 .warn("Unable to set database schema, no request manager has been defined."); 01503 } 01504 01510 public RequestManager getRequestManager() 01511 { 01512 return requestManager; 01513 } 01514 01520 public void setRequestManager(RequestManager requestManager) 01521 { 01522 this.requestManager = requestManager; 01523 } 01524 01530 public String getVirtualDatabaseName() 01531 { 01532 return name; 01533 } 01534 01541 public SQLMonitoring getSQLMonitor() 01542 { 01543 return sqlMonitor; 01544 } 01545 01551 public void setSQLMonitor(SQLMonitoring sqlMonitor) 01552 { 01553 this.sqlMonitor = sqlMonitor; 01554 } 01555 01562 public boolean equals(Object other) 01563 { 01564 if ((other == null) || (!(other instanceof VirtualDatabase))) 01565 return false; 01566 else 01567 { 01568 VirtualDatabase db = (VirtualDatabase) other; 01569 return name.equals(db.getDatabaseName()); 01570 } 01571 } 01572 01578 public String getXml() 01579 { 01580 StringBuffer info = new StringBuffer(); 01581 info.append("<C-JDBC>"); 01582 info.append("<" + DatabasesXmlTags.ELT_VirtualDatabase + " " 01583 + DatabasesXmlTags.ATT_name + "=\"" + this.getName() + "\" " 01584 + DatabasesXmlTags.ATT_maxNbOfConnections + "=\"" 01585 + this.getMaxNbOfConnections() + "\" " 01586 + DatabasesXmlTags.ATT_poolThreads + "=\"" 01587 + this.isPoolConnectionThreads() + "\" " 01588 + DatabasesXmlTags.ATT_minNbOfThreads + "=\"" 01589 + this.getMinNbOfThreads() + "\" " 01590 + DatabasesXmlTags.ATT_maxNbOfThreads + "=\"" 01591 + this.getMaxNbOfThreads() + "\" " 01592 + DatabasesXmlTags.ATT_maxThreadIdleTime + "=\"" 01593 + this.getMaxThreadIdleTime() / 1000 + "\" " 01594 + DatabasesXmlTags.ATT_sqlDumpLength + "=\"" + this.sqlShortFormLength 01595 + "\" " + DatabasesXmlTags.ATT_blobEncodingMethod + "=\"" 01596 + this.blobFilter.getXml() + "\">"); 01597 01598 info.append(getDistributionXml()); 01599 01600 if (this.getSQLMonitor() != null) 01601 info.append(sqlMonitor.getXml()); 01602 01603 info.append(requestManager.getBackupManager().getXml()); 01604 01605 if (this.getAuthenticationManager() != null) 01606 info.append(authenticationManager.getXml()); 01607 01608 try 01609 { 01610 acquireReadLockBackendLists(); 01611 int size = backends.size(); 01612 for (int i = 0; i < size; i++) 01613 info.append(((DatabaseBackend) backends.get(i)).getXml()); 01614 releaseReadLockBackendLists(); 01615 } 01616 catch (InterruptedException e) 01617 { 01618 logger.error(Translate.get("virtualdatabase.fail.read.lock", e)); 01619 } 01620 if (requestManager != null) 01621 info.append(requestManager.getXml()); 01622 info.append("</" + DatabasesXmlTags.ELT_VirtualDatabase + ">"); 01623 info.append("</C-JDBC>"); 01624 return info.toString(); 01625 } 01626 01632 protected String getDistributionXml() 01633 { 01634 return ""; 01635 } 01636 01640 public String getBackendInformation(String backendName) 01641 throws VirtualDatabaseException 01642 { 01643 try 01644 { 01645 acquireReadLockBackendLists(); 01646 } 01647 catch (InterruptedException e) 01648 { 01649 String msg = "Unable to acquire read lock on backend list in getBackendInformation (" 01650 + e + ")"; 01651 logger.error(msg); 01652 throw new VirtualDatabaseException(msg); 01653 } 01654 01655 // Find the backend 01656 int size = backends.size(); 01657 DatabaseBackend b = null; 01658 for (int i = 0; i < size; i++) 01659 { 01660 b = (DatabaseBackend) backends.get(i); 01661 if (b.getName().equals(backendName)) 01662 break; 01663 else 01664 b = null; 01665 } 01666 01667 if (b == null) 01668 { 01669 releaseReadLockBackendLists(); 01670 String msg = "Backend " + backendName + " does not exists."; 01671 logger.warn(msg); 01672 throw new VirtualDatabaseException(msg); 01673 } 01674 01675 releaseReadLockBackendLists(); 01676 return b.getXml(); 01677 } 01678 01680 // JMX 01682 01688 public String getName() 01689 { 01690 return name; 01691 } 01692 01698 public int getCurrentNbOfThreads() 01699 { 01700 return currentNbOfThreads; 01701 } 01702 01706 public void addCurrentNbOfThread() 01707 { 01708 currentNbOfThreads++; 01709 } 01710 01715 public void removeCurrentNbOfThread() 01716 { 01717 currentNbOfThreads--; 01718 } 01719 01725 public int getMinNbOfThreads() 01726 { 01727 return minNbOfThreads; 01728 } 01729 01735 public boolean isPoolConnectionThreads() 01736 { 01737 return poolConnectionThreads; 01738 } 01739 01745 public void setMinNbOfThreads(int minNbOfThreads) 01746 { 01747 this.minNbOfThreads = minNbOfThreads; 01748 } 01749 01755 public void setPoolConnectionThreads(boolean poolConnectionThreads) 01756 { 01757 this.poolConnectionThreads = poolConnectionThreads; 01758 } 01759 01765 public long getMaxThreadIdleTime() 01766 { 01767 return maxThreadIdleTime; 01768 } 01769 01775 public void setMaxThreadIdleTime(long maxThreadIdleTime) 01776 { 01777 this.maxThreadIdleTime = maxThreadIdleTime; 01778 } 01779 01785 public int getMaxNbOfConnections() 01786 { 01787 return maxNbOfConnections; 01788 } 01789 01795 public int getMaxNbOfThreads() 01796 { 01797 return maxNbOfThreads; 01798 } 01799 01805 public ArrayList getPendingConnections() 01806 { 01807 return pendingConnections; 01808 } 01809 01815 public void setMaxNbOfConnections(int maxNbOfConnections) 01816 { 01817 this.maxNbOfConnections = maxNbOfConnections; 01818 } 01819 01825 public void setMaxNbOfThreads(int maxNbOfThreads) 01826 { 01827 this.maxNbOfThreads = maxNbOfThreads; 01828 } 01829 01835 public ArrayList getActiveThreads() 01836 { 01837 return activeThreads; 01838 } 01839 01843 public String[] viewBackendInformation(String backendName) 01844 throws VirtualDatabaseException 01845 { 01846 DatabaseBackend backend = getAndCheckBackend(backendName, NO_CHECK_BACKEND); 01847 return backend.getBackendData(); 01848 } 01849 01854 public void addIdleThread() 01855 { 01856 idleThreads++; 01857 } 01858 01863 public void removeIdleThread() 01864 { 01865 idleThreads--; 01866 } 01867 01874 public int getIdleThreads() 01875 { 01876 return idleThreads; 01877 } 01878 01882 public ArrayList viewAllBackendNames() throws VirtualDatabaseException 01883 { 01884 return this.getAllBackendNames(); 01885 } 01886 01893 public ArrayList viewAllClientNames() 01894 { 01895 ArrayList list = this.getActiveThreads(); 01896 int size = list.size(); 01897 ArrayList clients = new ArrayList(size); 01898 for (int i = 0; i < list.size(); i++) 01899 clients.add(((VirtualDatabaseWorkerThread) list.get(i)).getUser()); 01900 return clients; 01901 } 01902 01906 public void disableAllBackendForCheckpoint(String checkpoint) 01907 throws VirtualDatabaseException 01908 { 01909 if (checkpoint == null) 01910 { 01911 disableAllBackend(); 01912 return; 01913 } 01914 01915 try 01916 { 01917 this.acquireReadLockBackendLists(); 01918 requestManager.disableBackendsForCheckpoint(backends, checkpoint); 01919 this.releaseReadLockBackendLists(); 01920 } 01921 catch (Exception e) 01922 { 01923 throw new VirtualDatabaseException(e.getMessage()); 01924 } 01925 } 01926 01927 /* Shutdown */ 01928 01935 public void shutdown(int level) 01936 { 01937 if (shuttingDown) 01938 return; 01939 shuttingDown = true; 01940 VirtualDatabaseShutdownThread vdst = new VirtualDatabaseShutdownThread( 01941 this, level); 01942 new Thread(vdst.getShutdownGroup(), vdst, "VirtualDatabase Shutdown Thread") 01943 .start(); 01944 } 01945 01951 public void shutdown() throws VirtualDatabaseException 01952 { 01953 shutdown(Constants.CONTROLLER_SHUTDOWN_FAST); 01954 } 01955 01961 public void setBlobFilter(AbstractBlobFilter filter) 01962 { 01963 this.blobFilter = filter; 01964 } 01965 01971 public AbstractBlobFilter getBlobFilter() 01972 { 01973 return blobFilter; 01974 } 01975 01979 public void setBackendLastKnownCheckpoint(String backendName, 01980 String checkpoint) throws VirtualDatabaseException 01981 { 01982 AbstractRecoveryLog log = requestManager.getRecoveryLog(); 01983 DatabaseBackend backend = getAndCheckBackend(backendName, NO_CHECK_BACKEND); 01984 if (log == null) 01985 throw new VirtualDatabaseException(ExceptionTypes.NO_RECOVERY_LOG); 01986 else 01987 { 01988 if (!backend.isDisabled()) 01989 throw new VirtualDatabaseException( 01990 "Cannot setLastKnownCheckpoint on a non-disabled backend"); 01991 else 01992 { 01993 try 01994 { 01995 log.storeBackendInfo(name, backendName, checkpoint, backend 01996 .getStateValue()); 01997 backend.setLastKnownCheckpoint(checkpoint); 01998 } 01999 catch (SQLException e) 02000 { 02001 throw new VirtualDatabaseException( 02002 "Failed to store recovery info for backend:" + backendName); 02003 } 02004 } 02005 } 02006 02007 } 02008 02012 public String getBackendState(String backendName) 02013 throws VirtualDatabaseException 02014 { 02015 DatabaseBackend backend = getAndCheckBackend(backendName, NO_CHECK_BACKEND); 02016 return backend.getState(); 02017 } 02018 02022 public String viewOwningController() 02023 { 02024 return controller.getJmxName(); 02025 } 02026 02031 public void restoreBackendFromBackupCheckpoint(String databaseBackendName, 02032 String checkpointName) throws VirtualDatabaseException, BackupException, 02033 OctopusException 02034 { 02035 DatabaseBackend backend = getAndCheckBackend(databaseBackendName, 02036 NO_CHECK_BACKEND); 02037 // Backend cannot be null, otherwise the above throws an 02038 // VirtualDatabaseException 02039 requestManager.restoreBackendFromBackupCheckpoint(backend, checkpointName, 02040 true, null); 02041 } 02042 02046 public void storeBackendsInfo() 02047 { 02048 requestManager.storeBackendsInfo(this.name, getBackends()); 02049 } 02050 02054 public boolean hasRecoveryLog() 02055 { 02056 AbstractRecoveryLog log = requestManager.getRecoveryLog(); 02057 if (log == null) 02058 return false; 02059 else 02060 return true; 02061 } 02062 02067 public void replicateBackend(String backendName, String newBackendName, 02068 Map parameters) throws VirtualDatabaseException 02069 { 02070 // Access the backend we want to replicate 02071 DatabaseBackend backend = getAndCheckBackend(backendName, NO_CHECK_BACKEND); 02072 DatabaseBackend newBackend = null; 02073 02074 // Create a clone of the backend with additionnal parameters 02075 try 02076 { 02077 newBackend = backend.copy(newBackendName, parameters); 02078 } 02079 catch (Exception e) 02080 { 02081 String msg = Translate.get("virtualdatabase.fail.backend.copy"); 02082 logger.warn(msg, e); 02083 throw new VirtualDatabaseException(msg); 02084 } 02085 02086 // Add the backend to the virtual database. 02087 addBackend(newBackend); 02088 } 02089 02093 public String[][] retrieveBackendsData() throws VirtualDatabaseException 02094 { 02095 try 02096 { 02097 acquireReadLockBackendLists(); 02098 } 02099 catch (InterruptedException e) 02100 { 02101 String msg = Translate.get("virtualdatabase.fail.read.lock", e); 02102 throw new VirtualDatabaseException(msg); 02103 } 02104 ArrayList backends = this.getBackends(); 02105 int backendListSize = backends.size(); 02106 String[][] data = new String[backendListSize][]; 02107 for (int i = 0; i < backendListSize; i++) 02108 { 02109 data[i] = ((DatabaseBackend) backends.get(i)).getBackendData(); 02110 } 02111 releaseReadLockBackendLists(); 02112 return data; 02113 } 02114 02118 public String[] viewControllerList() 02119 { 02120 return new String[]{viewOwningController()}; 02121 } 02122 02126 public Hashtable viewGroupBackends() throws VirtualDatabaseException 02127 { 02128 Hashtable map = new Hashtable(); 02129 map.put(controller.getJmxName(), viewAllBackendNames()); 02130 return map; 02131 } 02132 02137 public void transferBackend(String backend, String controllerDestination) 02138 throws VirtualDatabaseException 02139 { 02140 throw new VirtualDatabaseException("Cannot transfer backend to controller:" 02141 + controllerDestination + " because database is not distributed"); 02142 } 02143 }

CJDBCversion1.0.4に対してTue Oct 12 15:16:04 2004に生成されました。 doxygen 1.3.8