/** {@inheritDoc} */ @Override() public void restoreBackup(RestoreConfig restoreConfig) throws DirectoryException { BackupManager backupManager = new BackupManager(getBackendID()); File parentDir = getFileForPath(cfg.getDBDirectory()); File backendDir = new File(parentDir, cfg.getBackendId()); backupManager.restoreBackup(backendDir, restoreConfig); }
/** {@inheritDoc} */ public void diskFullThresholdReached(DiskSpaceMonitor monitor) { Message msg = ERR_JEB_DISK_FULL_THRESHOLD_REACHED.get( monitor.getDirectory().getPath(), cfg.getBackendId(), monitor.getFreeSpace(), Math.max(monitor.getLowThreshold(), monitor.getFullThreshold())); DirectoryServer.sendAlertNotification(this, ALERT_TYPE_DISK_FULL, msg); }
/** {@inheritDoc} */ public void diskSpaceRestored(DiskSpaceMonitor monitor) { Message msg = NOTE_JEB_DISK_SPACE_RESTORED.get( monitor.getFreeSpace(), monitor.getDirectory().getPath(), cfg.getBackendId(), Math.max(monitor.getLowThreshold(), monitor.getFullThreshold())); logError(msg); }
/** {@inheritDoc} */ @Override() public void finalizeBackend() { // Deregister as a change listener. cfg.removeLocalDBChangeListener(this); // Deregister our base DNs. for (DN dn : rootContainer.getBaseDNs()) { try { DirectoryServer.deregisterBaseDN(dn); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } } } DirectoryServer.deregisterMonitorProvider(rootContainerMonitor); DirectoryServer.deregisterMonitorProvider(diskMonitor); // We presume the server will prevent more operations coming into this // backend, but there may be existing operations already in the // backend. We need to wait for them to finish. waitUntilQuiescent(); // Close the database. try { rootContainer.close(); rootContainer = null; } catch (DatabaseException e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_JEB_DATABASE_EXCEPTION.get(e.getMessage()); logError(message); } // Checksum this db environment and register its offline state id/checksum. DirectoryServer.registerOfflineBackendStateID(this.getBackendID(), checksumDbEnv()); // Deregister the alert generator. DirectoryServer.deregisterAlertGenerator(this); // Make sure the thread counts are zero for next initialization. threadTotalCount.set(0); threadWriteCount.set(0); // Log an informational message. Message message = NOTE_BACKEND_OFFLINE.get(cfg.getBackendId()); logError(message); }
/** * This method will attempt to checksum the current JE db environment by computing the Adler-32 * checksum on the latest JE log file available. * * @return The checksum of JE db environment or zero if checksum failed. */ private long checksumDbEnv() { File parentDirectory = getFileForPath(cfg.getDBDirectory()); File backendDirectory = new File(parentDirectory, cfg.getBackendId()); List<File> jdbFiles = new ArrayList<File>(); if (backendDirectory.isDirectory()) { jdbFiles = Arrays.asList( backendDirectory.listFiles( new FilenameFilter() { public boolean accept(File dir, String name) { return name.endsWith(".jdb"); } })); } if (!jdbFiles.isEmpty()) { Collections.sort(jdbFiles, Collections.reverseOrder()); FileInputStream fis = null; try { fis = new FileInputStream(jdbFiles.get(0).toString()); CheckedInputStream cis = new CheckedInputStream(fis, new Adler32()); byte[] tempBuf = new byte[8192]; while (cis.read(tempBuf) >= 0) {} return cis.getChecksum().getValue(); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } } finally { if (fis != null) { try { fis.close(); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } } } } } return 0; }
/** {@inheritDoc} */ @Override() public LDIFImportResult importLDIF(LDIFImportConfig importConfig) throws DirectoryException { RuntimeInformation.logInfo(); // If the backend already has the root container open, we must use the same // underlying root container boolean openRootContainer = rootContainer == null; // If the rootContainer is open, the backend is initialized by something // else. // We can't do import while the backend is online. if (!openRootContainer) { Message message = ERR_JEB_IMPORT_BACKEND_ONLINE.get(); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message); } try { EnvironmentConfig envConfig = new EnvironmentConfig(); envConfig.setAllowCreate(true); envConfig.setTransactional(false); envConfig.setDurability(Durability.COMMIT_NO_SYNC); envConfig.setLockTimeout(0, TimeUnit.SECONDS); envConfig.setTxnTimeout(0, TimeUnit.SECONDS); envConfig.setConfigParam( EnvironmentConfig.CLEANER_MIN_FILE_UTILIZATION, String.valueOf(cfg.getDBCleanerMinUtilization())); envConfig.setConfigParam( EnvironmentConfig.LOG_FILE_MAX, String.valueOf(cfg.getDBLogFileMax())); if (!importConfig.appendToExistingData()) { if (importConfig.clearBackend() || cfg.getBaseDN().size() <= 1) { // We have the writer lock on the environment, now delete the // environment and re-open it. Only do this when we are // importing to all the base DNs in the backend or if the backend only // have one base DN. File parentDirectory = getFileForPath(cfg.getDBDirectory()); File backendDirectory = new File(parentDirectory, cfg.getBackendId()); // If the backend does not exist the import will create it. if (backendDirectory.exists()) { EnvManager.removeFiles(backendDirectory.getPath()); } } } Importer importer = new Importer(importConfig, cfg, envConfig); rootContainer = initializeRootContainer(envConfig); return importer.processImport(rootContainer); } catch (ExecutionException execEx) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, execEx); } if (execEx.getCause() instanceof DirectoryException) { throw ((DirectoryException) execEx.getCause()); } else { Message message = ERR_EXECUTION_ERROR.get(execEx.getMessage()); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message); } } catch (InterruptedException intEx) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, intEx); } Message message = ERR_INTERRUPTED_ERROR.get(intEx.getMessage()); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message); } catch (JebException je) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, je); } throw new DirectoryException( DirectoryServer.getServerErrorResultCode(), je.getMessageObject()); } catch (InitializationException ie) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, ie); } throw new DirectoryException( DirectoryServer.getServerErrorResultCode(), ie.getMessageObject()); } catch (ConfigException ce) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, ce); } throw new DirectoryException( DirectoryServer.getServerErrorResultCode(), ce.getMessageObject()); } finally { // leave the backend in the same state. try { if (rootContainer != null) { long startTime = System.currentTimeMillis(); rootContainer.close(); long finishTime = System.currentTimeMillis(); long closeTime = (finishTime - startTime) / 1000; Message msg = NOTE_JEB_IMPORT_LDIF_ROOTCONTAINER_CLOSE.get(closeTime); logError(msg); rootContainer = null; } // Sync the environment to disk. if (debugEnabled()) { Message message = NOTE_JEB_IMPORT_CLOSING_DATABASE.get(); TRACER.debugInfo(message.toString()); } } catch (DatabaseException de) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, de); } } } }
/** {@inheritDoc} */ @Override() public void initializeBackend() throws ConfigException, InitializationException { // Checksum this db environment and register its offline state id/checksum. DirectoryServer.registerOfflineBackendStateID(this.getBackendID(), checksumDbEnv()); if (rootContainer == null) { EnvironmentConfig envConfig = ConfigurableEnvironment.parseConfigEntry(cfg); rootContainer = initializeRootContainer(envConfig); } // Preload the database cache. rootContainer.preload(cfg.getPreloadTimeLimit()); try { // Log an informational message about the number of entries. Message message = NOTE_JEB_BACKEND_STARTED.get(cfg.getBackendId(), rootContainer.getEntryCount()); logError(message); } catch (DatabaseException databaseException) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, databaseException); } Message message = WARN_JEB_GET_ENTRY_COUNT_FAILED.get(databaseException.getMessage()); throw new InitializationException(message, databaseException); } for (DN dn : cfg.getBaseDN()) { try { DirectoryServer.registerBaseDN(dn, this, false); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_BACKEND_CANNOT_REGISTER_BASEDN.get(String.valueOf(dn), String.valueOf(e)); throw new InitializationException(message, e); } } // Register a monitor provider for the environment. rootContainerMonitor = rootContainer.getMonitorProvider(); DirectoryServer.registerMonitorProvider(rootContainerMonitor); // Register as disk space monitor handler File parentDirectory = getFileForPath(cfg.getDBDirectory()); File backendDirectory = new File(parentDirectory, cfg.getBackendId()); diskMonitor = new DiskSpaceMonitor( getBackendID() + " backend", backendDirectory, cfg.getDiskLowThreshold(), cfg.getDiskFullThreshold(), 5, TimeUnit.SECONDS, this); diskMonitor.initializeMonitorProvider(null); DirectoryServer.registerMonitorProvider(diskMonitor); // Register as an AlertGenerator. DirectoryServer.registerAlertGenerator(this); // Register this backend as a change listener. cfg.addLocalDBChangeListener(this); }
/** * Clears all the entries from the backend. This method is for test cases that use the JE backend. * * @throws ConfigException If an unrecoverable problem arises in the process of performing the * initialization. * @throws JebException If an error occurs while removing the data. */ public void clearBackend() throws ConfigException, JebException { // Determine the backend database directory. File parentDirectory = getFileForPath(cfg.getDBDirectory()); File backendDirectory = new File(parentDirectory, cfg.getBackendId()); EnvManager.removeFiles(backendDirectory.getPath()); }